Skip to content

Commit 85b6f0a

Browse files
anhnh2002claude
andcommitted
Fix resume skipping missing module docs when overview.md exists
run_module_agent (caw and pydantic-ai backends) and generate_parent_module_docs returned early whenever overview.md was present. overview.md only proves the ROOT module is done, so on a resume after a partial run every nested module and parent without its own doc file was silently skipped. Gate the overview.md check on the root module (empty module_path) and let each module be checked against its own doc file. Also mechanical ruff cleanup on the touched files (Dict/List -> dict/ list, import sorting, format) so the changed-files lint job passes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent bbcac24 commit 85b6f0a

3 files changed

Lines changed: 42 additions & 35 deletions

File tree

‎codewiki/src/be/caw_backend.py‎

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
import logging
2424
import os
2525
import shutil
26-
from typing import Any, Dict, List
26+
from typing import Any
2727

2828
from caw import Agent as CawAgent
2929
from caw import ToolGroup
@@ -170,7 +170,7 @@ def _with_allowed_tools(cmd):
170170
allowed = ",".join(f"mcp__{s}" for s in servers)
171171
logger.info("Injected --allowedTools for MCP servers: %s", servers)
172172
return list(cmd) + ["--allowedTools", allowed]
173-
except Exception as e: # never break the spawn on a patch hiccup
173+
except Exception as e: # noqa: BLE001 — never break the spawn on a patch hiccup
174174
logger.warning("claude allowedTools patch skipped: %s", e)
175175
return cmd
176176

@@ -266,11 +266,11 @@ def complete(
266266
async def run_module_agent(
267267
self,
268268
module_name: str,
269-
components: Dict[str, Node],
270-
core_component_ids: List[str],
271-
module_path: List[str],
269+
components: dict[str, Node],
270+
core_component_ids: list[str],
271+
module_path: list[str],
272272
working_dir: str,
273-
) -> Dict[str, Any]:
273+
) -> dict[str, Any]:
274274
# caw.completion shells out to a subprocess and blocks the calling
275275
# thread. Push it off the event loop so the rest of the async
276276
# pipeline keeps moving.
@@ -293,13 +293,13 @@ async def run_module_agent(
293293
def _run_module_agent_sync(
294294
self,
295295
module_name: str,
296-
components: Dict[str, Node],
297-
core_component_ids: List[str],
298-
module_path: List[str],
296+
components: dict[str, Node],
297+
core_component_ids: list[str],
298+
module_path: list[str],
299299
working_dir: str,
300300
start_depth: int = 1,
301-
module_tree: Dict[str, Any] | None = None,
302-
) -> Dict[str, Any]:
301+
module_tree: dict[str, Any] | None = None,
302+
) -> dict[str, Any]:
303303
# ``start_depth`` lets the recursion preserve max_depth across nested
304304
# _run_module_agent_sync calls — each fresh deps object would otherwise
305305
# reset current_depth to 1 and silently bypass max_depth guards.
@@ -314,10 +314,15 @@ def _run_module_agent_sync(
314314
if module_tree is None:
315315
module_tree = file_manager.load_json(module_tree_path)
316316

317-
overview_docs_path = os.path.join(working_dir, OVERVIEW_FILENAME)
318-
if os.path.exists(overview_docs_path):
319-
logger.info("✓ Overview docs already exists at %s", overview_docs_path)
320-
return module_tree
317+
# overview.md is the root module's own doc (renamed from
318+
# {repo_name}.md), so its presence only proves the root is done —
319+
# nested modules must still be checked against their own doc file,
320+
# or a resume after a partial run silently skips every missing one.
321+
if not module_path:
322+
overview_docs_path = os.path.join(working_dir, OVERVIEW_FILENAME)
323+
if os.path.exists(overview_docs_path):
324+
logger.info("✓ Overview docs already exists at %s", overview_docs_path)
325+
return module_tree
321326
docs_path = os.path.join(working_dir, f"{module_name}.md")
322327
if os.path.exists(docs_path):
323328
logger.info("✓ Module docs already exists at %s", docs_path)
@@ -333,16 +338,16 @@ def _run_module_agent_sync(
333338
# agent call per sub-spec even when a single leaf write would suffice.
334339
# See generate_sub_module_documentation_tool for the pydantic-ai
335340
# equivalent.
336-
_, components_with_code = format_potential_core_components(
337-
core_component_ids, components
338-
)
341+
_, components_with_code = format_potential_core_components(core_component_ids, components)
339342
num_tokens = count_tokens(components_with_code)
340343
can_delegate = (
341344
is_complex_module(components, core_component_ids)
342345
and start_depth < config.max_depth
343346
and num_tokens >= config.max_token_per_leaf_module
344347
)
345-
logger.info(f"Module {module_name} can delegate: {can_delegate} - is_complex_module: {is_complex_module(components, core_component_ids)} - start_depth: {start_depth} - num_tokens: {num_tokens} - max_depth: {config.max_depth} - max_token_per_leaf_module: {config.max_token_per_leaf_module}")
348+
logger.info(
349+
f"Module {module_name} can delegate: {can_delegate} - is_complex_module: {is_complex_module(components, core_component_ids)} - start_depth: {start_depth} - num_tokens: {num_tokens} - max_depth: {config.max_depth} - max_token_per_leaf_module: {config.max_token_per_leaf_module}"
350+
)
346351

347352
if can_delegate:
348353
system_prompt = format_system_prompt(module_name, custom_instructions)

‎codewiki/src/be/documentation_generator.py‎

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -297,13 +297,10 @@ async def generate_parent_module_docs(
297297
module_tree_path = os.path.join(working_dir, MODULE_TREE_FILENAME)
298298
module_tree = file_manager.load_json(module_tree_path)
299299

300-
# check if overview docs already exists
301-
overview_docs_path = os.path.join(working_dir, OVERVIEW_FILENAME)
302-
if os.path.exists(overview_docs_path):
303-
logger.info(f"✓ Overview docs already exists at {overview_docs_path}")
304-
return module_tree
305-
306-
# check if parent docs already exists
300+
# check if parent docs already exists (for the root module the doc
301+
# path below resolves to overview.md, so a blanket "overview exists →
302+
# skip" check is not needed here and would mask missing parent docs
303+
# on resume)
307304
parent_docs_path = os.path.join(
308305
working_dir,
309306
f"{module_name if len(module_path) >= 1 else OVERVIEW_FILENAME.replace('.md', '')}.md",

‎codewiki/src/be/pydantic_ai_backend.py‎

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
import logging
1212
import os
1313
import traceback
14-
from typing import Any, Dict, List
14+
from typing import Any
1515

1616
from pydantic_ai import Agent
1717

@@ -55,19 +55,24 @@ def complete(
5555
async def run_module_agent(
5656
self,
5757
module_name: str,
58-
components: Dict[str, Node],
59-
core_component_ids: List[str],
60-
module_path: List[str],
58+
components: dict[str, Node],
59+
core_component_ids: list[str],
60+
module_path: list[str],
6161
working_dir: str,
62-
) -> Dict[str, Any]:
62+
) -> dict[str, Any]:
6363
config = self._config
6464
module_tree_path = os.path.join(working_dir, MODULE_TREE_FILENAME)
6565
module_tree = file_manager.load_json(module_tree_path)
6666

67-
overview_docs_path = os.path.join(working_dir, OVERVIEW_FILENAME)
68-
if os.path.exists(overview_docs_path):
69-
logger.info("✓ Overview docs already exists at %s", overview_docs_path)
70-
return module_tree
67+
# overview.md is the root module's own doc (renamed from
68+
# {repo_name}.md), so its presence only proves the root is done —
69+
# nested modules must still be checked against their own doc file,
70+
# or a resume after a partial run silently skips every missing one.
71+
if not module_path:
72+
overview_docs_path = os.path.join(working_dir, OVERVIEW_FILENAME)
73+
if os.path.exists(overview_docs_path):
74+
logger.info("✓ Overview docs already exists at %s", overview_docs_path)
75+
return module_tree
7176
docs_path = os.path.join(working_dir, f"{module_name}.md")
7277
if os.path.exists(docs_path):
7378
logger.info("✓ Module docs already exists at %s", docs_path)

0 commit comments

Comments
 (0)