feat(context): Granular AST Control for C/C++ files
This commit is contained in:
+21
-3
@@ -121,21 +121,27 @@ def build_file_items(base_dir: Path, files: list[str | dict[str, Any]]) -> list[
|
|||||||
tier = entry_raw.get("tier")
|
tier = entry_raw.get("tier")
|
||||||
auto_aggregate = entry_raw.get("auto_aggregate", True)
|
auto_aggregate = entry_raw.get("auto_aggregate", True)
|
||||||
force_full = entry_raw.get("force_full", False)
|
force_full = entry_raw.get("force_full", False)
|
||||||
|
ast_signatures = entry_raw.get("ast_signatures", False)
|
||||||
|
ast_definitions = entry_raw.get("ast_definitions", False)
|
||||||
elif hasattr(entry_raw, "path"):
|
elif hasattr(entry_raw, "path"):
|
||||||
entry = entry_raw.path
|
entry = entry_raw.path
|
||||||
tier = getattr(entry_raw, "tier", None)
|
tier = getattr(entry_raw, "tier", None)
|
||||||
auto_aggregate = getattr(entry_raw, "auto_aggregate", True)
|
auto_aggregate = getattr(entry_raw, "auto_aggregate", True)
|
||||||
force_full = getattr(entry_raw, "force_full", False)
|
force_full = getattr(entry_raw, "force_full", False)
|
||||||
|
ast_signatures = getattr(entry_raw, "ast_signatures", False)
|
||||||
|
ast_definitions = getattr(entry_raw, "ast_definitions", False)
|
||||||
else:
|
else:
|
||||||
entry = entry_raw
|
entry = entry_raw
|
||||||
tier = None
|
tier = None
|
||||||
auto_aggregate = True
|
auto_aggregate = True
|
||||||
force_full = False
|
force_full = False
|
||||||
|
ast_signatures = False
|
||||||
|
ast_definitions = False
|
||||||
if not entry or not isinstance(entry, str):
|
if not entry or not isinstance(entry, str):
|
||||||
continue
|
continue
|
||||||
paths = resolve_paths(base_dir, entry)
|
paths = resolve_paths(base_dir, entry)
|
||||||
if not paths:
|
if not paths:
|
||||||
items.append({"path": None, "entry": entry, "content": f"ERROR: no files matched: {entry}", "error": True, "mtime": 0.0, "tier": tier, "auto_aggregate": auto_aggregate, "force_full": force_full})
|
items.append({"path": None, "entry": entry, "content": f"ERROR: no files matched: {entry}", "error": True, "mtime": 0.0, "tier": tier, "auto_aggregate": auto_aggregate, "force_full": force_full, "ast_signatures": ast_signatures, "ast_definitions": ast_definitions})
|
||||||
continue
|
continue
|
||||||
for path in paths:
|
for path in paths:
|
||||||
try:
|
try:
|
||||||
@@ -150,7 +156,7 @@ def build_file_items(base_dir: Path, files: list[str | dict[str, Any]]) -> list[
|
|||||||
content = f"ERROR: {e}"
|
content = f"ERROR: {e}"
|
||||||
mtime = 0.0
|
mtime = 0.0
|
||||||
error = True
|
error = True
|
||||||
items.append({"path": path, "entry": entry, "content": content, "error": error, "mtime": mtime, "tier": tier, "auto_aggregate": auto_aggregate, "force_full": force_full})
|
items.append({"path": path, "entry": entry, "content": content, "error": error, "mtime": mtime, "tier": tier, "auto_aggregate": auto_aggregate, "force_full": force_full, "ast_signatures": ast_signatures, "ast_definitions": ast_definitions})
|
||||||
return items
|
return items
|
||||||
|
|
||||||
|
|
||||||
@@ -264,6 +270,8 @@ def build_tier3_context(file_items: list[dict[str, Any]], screenshot_base_dir: P
|
|||||||
name = path.name if path else ""
|
name = path.name if path else ""
|
||||||
tier = item.get("tier")
|
tier = item.get("tier")
|
||||||
force_full = item.get("force_full")
|
force_full = item.get("force_full")
|
||||||
|
ast_signatures = item.get("ast_signatures", False)
|
||||||
|
ast_definitions = item.get("ast_definitions", False)
|
||||||
content = item.get("content", "")
|
content = item.get("content", "")
|
||||||
is_focus = entry in focus_set or (name and name in focus_set) or (path_str and path_str in focus_set)
|
is_focus = entry in focus_set or (name and name in focus_set) or (path_str and path_str in focus_set)
|
||||||
if not is_focus and path_str:
|
if not is_focus and path_str:
|
||||||
@@ -276,7 +284,17 @@ def build_tier3_context(file_items: list[dict[str, Any]], screenshot_base_dir: P
|
|||||||
suffix = path.suffix.lstrip(".") if path and path.suffix else "text"
|
suffix = path.suffix.lstrip(".") if path and path.suffix else "text"
|
||||||
sections.append(f"### `{original}`\n\n```{suffix}\n{content}\n```")
|
sections.append(f"### `{original}`\n\n```{suffix}\n{content}\n```")
|
||||||
elif path:
|
elif path:
|
||||||
if path.suffix == ".py" and not item.get("error"):
|
if path.suffix in ['.c', '.h', '.cpp', '.hpp', '.cxx', '.cc'] and not item.get("error"):
|
||||||
|
from src import mcp_client
|
||||||
|
if ast_definitions:
|
||||||
|
skeleton = mcp_client.ts_cpp_get_skeleton(str(path)) if 'cpp' in path.suffix or 'hpp' in path.suffix or 'cxx' in path.suffix or 'cc' in path.suffix else mcp_client.ts_c_get_skeleton(str(path))
|
||||||
|
sections.append(f"### `{original}` (AST Definitions)\n\n```{path.suffix.lstrip('.')}\n{skeleton}\n```")
|
||||||
|
elif ast_signatures:
|
||||||
|
outline = mcp_client.ts_cpp_get_code_outline(str(path)) if 'cpp' in path.suffix or 'hpp' in path.suffix or 'cxx' in path.suffix or 'cc' in path.suffix else mcp_client.ts_c_get_code_outline(str(path))
|
||||||
|
sections.append(f"### `{original}` (AST Signatures)\n\n```{path.suffix.lstrip('.')}\n{outline}\n```")
|
||||||
|
else:
|
||||||
|
sections.append(f"### `{original}`\n\n{summarize.summarise_file(path, content)}")
|
||||||
|
elif path.suffix == ".py" and not item.get("error"):
|
||||||
try:
|
try:
|
||||||
skeleton = parser.get_skeleton(content)
|
skeleton = parser.get_skeleton(content)
|
||||||
sections.append(f"### `{original}` (AST Skeleton)\n\n```python\n{skeleton}\n```")
|
sections.append(f"### `{original}` (AST Skeleton)\n\n```python\n{skeleton}\n```")
|
||||||
|
|||||||
+6
-1
@@ -2529,7 +2529,7 @@ class App:
|
|||||||
imgui.separator()
|
imgui.separator()
|
||||||
if imgui.begin_table("ctx_comp_table", 2, imgui.TableFlags_.resizable | imgui.TableFlags_.borders):
|
if imgui.begin_table("ctx_comp_table", 2, imgui.TableFlags_.resizable | imgui.TableFlags_.borders):
|
||||||
imgui.table_setup_column("File", imgui.TableColumnFlags_.width_stretch)
|
imgui.table_setup_column("File", imgui.TableColumnFlags_.width_stretch)
|
||||||
imgui.table_setup_column("Flags", imgui.TableColumnFlags_.width_fixed, 120)
|
imgui.table_setup_column("Flags", imgui.TableColumnFlags_.width_fixed, 200)
|
||||||
imgui.table_headers_row()
|
imgui.table_headers_row()
|
||||||
for i, f_item in enumerate(self.files):
|
for i, f_item in enumerate(self.files):
|
||||||
imgui.table_next_row()
|
imgui.table_next_row()
|
||||||
@@ -2540,6 +2540,11 @@ class App:
|
|||||||
changed_agg, f_item.auto_aggregate = imgui.checkbox(f"Agg##cc{i}", f_item.auto_aggregate)
|
changed_agg, f_item.auto_aggregate = imgui.checkbox(f"Agg##cc{i}", f_item.auto_aggregate)
|
||||||
imgui.same_line()
|
imgui.same_line()
|
||||||
changed_full, f_item.force_full = imgui.checkbox(f"Full##cc{i}", f_item.force_full)
|
changed_full, f_item.force_full = imgui.checkbox(f"Full##cc{i}", f_item.force_full)
|
||||||
|
if hasattr(f_item, "ast_signatures"):
|
||||||
|
imgui.same_line()
|
||||||
|
_, f_item.ast_signatures = imgui.checkbox(f"Sig##cc{i}", f_item.ast_signatures)
|
||||||
|
imgui.same_line()
|
||||||
|
_, f_item.ast_definitions = imgui.checkbox(f"Def##cc{i}", f_item.ast_definitions)
|
||||||
imgui.end_table()
|
imgui.end_table()
|
||||||
imgui.separator()
|
imgui.separator()
|
||||||
imgui.text("Screenshots")
|
imgui.text("Screenshots")
|
||||||
|
|||||||
@@ -495,6 +495,8 @@ class FileItem:
|
|||||||
path: str
|
path: str
|
||||||
auto_aggregate: bool = True
|
auto_aggregate: bool = True
|
||||||
force_full: bool = False
|
force_full: bool = False
|
||||||
|
ast_signatures: bool = False
|
||||||
|
ast_definitions: bool = False
|
||||||
injected_at: Optional[float] = None
|
injected_at: Optional[float] = None
|
||||||
|
|
||||||
def to_dict(self) -> Dict[str, Any]:
|
def to_dict(self) -> Dict[str, Any]:
|
||||||
@@ -505,6 +507,8 @@ class FileItem:
|
|||||||
"path": self.path,
|
"path": self.path,
|
||||||
"auto_aggregate": self.auto_aggregate,
|
"auto_aggregate": self.auto_aggregate,
|
||||||
"force_full": self.force_full,
|
"force_full": self.force_full,
|
||||||
|
"ast_signatures": self.ast_signatures,
|
||||||
|
"ast_definitions": self.ast_definitions,
|
||||||
"injected_at": self.injected_at,
|
"injected_at": self.injected_at,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -517,6 +521,8 @@ class FileItem:
|
|||||||
path=data["path"],
|
path=data["path"],
|
||||||
auto_aggregate=data.get("auto_aggregate", True),
|
auto_aggregate=data.get("auto_aggregate", True),
|
||||||
force_full=data.get("force_full", False),
|
force_full=data.get("force_full", False),
|
||||||
|
ast_signatures=data.get("ast_signatures", False),
|
||||||
|
ast_definitions=data.get("ast_definitions", False),
|
||||||
injected_at=data.get("injected_at"),
|
injected_at=data.get("injected_at"),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ def test_file_item_to_dict():
|
|||||||
"path": "test.py",
|
"path": "test.py",
|
||||||
"auto_aggregate": False,
|
"auto_aggregate": False,
|
||||||
"force_full": True,
|
"force_full": True,
|
||||||
|
"ast_signatures": False,
|
||||||
|
"ast_definitions": False,
|
||||||
"injected_at": None
|
"injected_at": None
|
||||||
}
|
}
|
||||||
assert item.to_dict() == expected
|
assert item.to_dict() == expected
|
||||||
|
|||||||
Reference in New Issue
Block a user