-
Notifications
You must be signed in to change notification settings - Fork 1
fix(CODEWIKI-002): CU-86akn96pk 2 review findings in config.py #96
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -128,11 +128,48 @@ def to_dict(self, include_secrets: bool = False) -> Dict[str, Any]: | |
| only when the caller explicitly needs to reconstruct a fully-functional | ||
| Config via from_dict() (e.g. in-process transfer within the same trust | ||
| boundary). | ||
|
|
||
| Each field is listed explicitly (rather than delegating to | ||
| dataclasses.asdict()) so that adding a new field to Config requires a | ||
| deliberate decision about whether/how it is serialized here. | ||
| """ | ||
| data = asdict(self) | ||
| if not include_secrets: | ||
| for secret_field in _RUNTIME_ONLY_SECRET_FIELDS: | ||
| data.pop(secret_field, None) | ||
| data = { | ||
| 'repo_path': self.repo_path, | ||
| 'output_dir': self.output_dir, | ||
| 'dependency_graph_dir': self.dependency_graph_dir, | ||
| 'docs_dir': self.docs_dir, | ||
| 'max_depth': self.max_depth, | ||
| 'main_model': self.main_model, | ||
| 'cluster_model': self.cluster_model, | ||
| 'fallback_model': self.fallback_model, | ||
| 'cluster_base_url': self.cluster_base_url, | ||
| 'main_base_url': self.main_base_url, | ||
| 'fallback_base_url': self.fallback_base_url, | ||
| 'cluster_api_version': self.cluster_api_version, | ||
| 'main_api_version': self.main_api_version, | ||
| 'fallback_api_version': self.fallback_api_version, | ||
| 'cluster_max_tokens': self.cluster_max_tokens, | ||
| 'main_max_tokens': self.main_max_tokens, | ||
| 'fallback_max_tokens': self.fallback_max_tokens, | ||
| 'max_token_per_module': self.max_token_per_module, | ||
| 'max_token_per_leaf_module': self.max_token_per_leaf_module, | ||
| 'cluster_temperature': self.cluster_temperature, | ||
| 'main_temperature': self.main_temperature, | ||
| 'fallback_temperature': self.fallback_temperature, | ||
| 'cluster_temperature_supported': self.cluster_temperature_supported, | ||
| 'main_temperature_supported': self.main_temperature_supported, | ||
| 'fallback_temperature_supported': self.fallback_temperature_supported, | ||
| 'cluster_max_token_field': self.cluster_max_token_field, | ||
| 'main_max_token_field': self.main_max_token_field, | ||
| 'fallback_max_token_field': self.fallback_max_token_field, | ||
| 'agent_instructions': self.agent_instructions, | ||
| 'diagrams_dir': self.diagrams_dir, | ||
| 'additional_source_paths': self.additional_source_paths, | ||
| } | ||
| if include_secrets: | ||
| data['cluster_api_key'] = self.cluster_api_key | ||
| data['main_api_key'] = self.main_api_key | ||
| data['fallback_api_key'] = self.fallback_api_key | ||
| return data | ||
|
|
||
| @classmethod | ||
|
|
@@ -143,10 +180,21 @@ def from_dict(cls, data: Dict[str, Any]) -> 'Config': | |
| If secret fields (cluster_api_key, main_api_key, fallback_api_key) were | ||
| excluded (the default for to_dict()), they must be supplied separately | ||
| in `data` or this will raise a TypeError due to missing required fields. | ||
|
|
||
| Unknown/unexpected keys in `data` (e.g. leftover fields from a previous | ||
| schema version) are rejected with a ValueError rather than silently | ||
| discarded, so that config drift between the CLI and backend Config is | ||
| surfaced instead of hidden. | ||
| """ | ||
| known_fields = {f.name for f in fields(cls)} | ||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 𦩠π Config.from_dict silently drops unknown/extra fields including ones from a previous schema version Changed π€ Prompt for AI agentsfix confidence: π΄ 55 low β review closely β react π/π to teach the reviewer |
||
| filtered = {k: v for k, v in data.items() if k in known_fields} | ||
| return cls(**filtered) | ||
| unknown = set(data.keys()) - known_fields | ||
| if unknown: | ||
| raise ValueError( | ||
| f"Unknown Config field(s) in data passed to from_dict(): {sorted(unknown)}. " | ||
| "This usually indicates config drift between schema versions; " | ||
| "remove or migrate these fields before constructing a Config." | ||
| ) | ||
| return cls(**data) | ||
|
|
||
| @property | ||
| def include_patterns(self) -> Optional[List[str]]: | ||
|
|
@@ -760,3 +808,4 @@ def from_config_manager( | |
| diagrams_dir=None, | ||
| additional_source_paths=additional_paths | ||
| ) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
𦩠π΄ Config.to_dict() delegates to asdict() instead of explicitly listing fields
Rewrote
Config.to_dict()(codewiki/src/config.py) to build the returned dict by explicitly listing every non-secret field by name (repo_path, output_dir, ... additional_source_paths), instead of callingasdict(self)and popping secret keys afterward. Secret fields (cluster_api_key, main_api_key, fallback_api_key) are now only added to the dict explicitly wheninclude_secrets=True, rather than being present by default and removed. This satisfies CODEWIKI-002's requirement that to_dict() explicitly enumerate fields, and it removes the "new field silently serialized" risk since any new dataclass field must be added to this list by hand to be included.π€ Prompt for AI agents
fix confidence: π‘ 88 medium β react π/π to teach the reviewer