66to the backend Config class when running documentation generation.
77"""
88
9- from dataclasses import dataclass , asdict , field
10- from typing import Optional , List
11- from pathlib import Path
9+ from dataclasses import dataclass , field
1210
1311from codewiki .cli .utils .validation import (
14- validate_url ,
15- validate_api_key ,
1612 validate_model_name ,
13+ validate_url ,
1714)
1815
1916
2017@dataclass
2118class AgentInstructions :
2219 """
2320 Custom instructions for the documentation agent.
24-
21+
2522 Allows users to customize:
2623 - File filtering (include/exclude patterns)
2724 - Module focus (prioritize certain modules)
2825 - Documentation type (API docs, architecture docs, etc.)
2926 - Custom instructions for the LLM
30-
27+
3128 Attributes:
3229 include_patterns: File patterns to include (e.g., ["*.cs", "*.py"])
3330 exclude_patterns: File/directory patterns to exclude (e.g., ["*Tests*", "*test*"])
3431 focus_modules: Modules to document in more detail
3532 doc_type: Type of documentation to generate
3633 custom_instructions: Additional instructions for the documentation agent
3734 """
38- include_patterns : Optional [List [str ]] = None # e.g., ["*.cs"] for C# projects
39- exclude_patterns : Optional [List [str ]] = None # e.g., ["*Tests*", "*Specs*"]
40- focus_modules : Optional [List [str ]] = None # e.g., ["src/core", "src/api"]
41- doc_type : Optional [str ] = None # e.g., "api", "architecture", "user-guide"
42- custom_instructions : Optional [str ] = None # Free-form instructions
43- artifact_exclude : Optional [List [str ]] = None # e.g., ["docker/data/*"] skipped by artifact analysis
44-
35+
36+ include_patterns : list [str ] | None = None # e.g., ["*.cs"] for C# projects
37+ exclude_patterns : list [str ] | None = None # e.g., ["*Tests*", "*Specs*"]
38+ focus_modules : list [str ] | None = None # e.g., ["src/core", "src/api"]
39+ doc_type : str | None = None # e.g., "api", "architecture", "user-guide"
40+ custom_instructions : str | None = None # Free-form instructions
41+ artifact_exclude : list [str ] | None = (
42+ None # e.g., ["docker/data/*"] skipped by artifact analysis
43+ )
44+
4545 def to_dict (self ) -> dict :
4646 """Convert to dictionary, excluding None values."""
4747 result = {}
4848 if self .include_patterns :
49- result [' include_patterns' ] = self .include_patterns
49+ result [" include_patterns" ] = self .include_patterns
5050 if self .exclude_patterns :
51- result [' exclude_patterns' ] = self .exclude_patterns
51+ result [" exclude_patterns" ] = self .exclude_patterns
5252 if self .artifact_exclude :
53- result [' artifact_exclude' ] = self .artifact_exclude
53+ result [" artifact_exclude" ] = self .artifact_exclude
5454 if self .focus_modules :
55- result [' focus_modules' ] = self .focus_modules
55+ result [" focus_modules" ] = self .focus_modules
5656 if self .doc_type :
57- result [' doc_type' ] = self .doc_type
57+ result [" doc_type" ] = self .doc_type
5858 if self .custom_instructions :
59- result [' custom_instructions' ] = self .custom_instructions
59+ result [" custom_instructions" ] = self .custom_instructions
6060 return result
61-
61+
6262 @classmethod
63- def from_dict (cls , data : dict ) -> ' AgentInstructions' :
63+ def from_dict (cls , data : dict ) -> " AgentInstructions" :
6464 """Create AgentInstructions from dictionary."""
6565 return cls (
66- include_patterns = data .get (' include_patterns' ),
67- exclude_patterns = data .get (' exclude_patterns' ),
68- focus_modules = data .get (' focus_modules' ),
69- doc_type = data .get (' doc_type' ),
70- custom_instructions = data .get (' custom_instructions' ),
71- artifact_exclude = data .get (' artifact_exclude' ),
66+ include_patterns = data .get (" include_patterns" ),
67+ exclude_patterns = data .get (" exclude_patterns" ),
68+ focus_modules = data .get (" focus_modules" ),
69+ doc_type = data .get (" doc_type" ),
70+ custom_instructions = data .get (" custom_instructions" ),
71+ artifact_exclude = data .get (" artifact_exclude" ),
7272 )
73-
73+
7474 def is_empty (self ) -> bool :
7575 """Check if all fields are empty/None."""
76- return not any ([
77- self .include_patterns ,
78- self .exclude_patterns ,
79- self .artifact_exclude ,
80- self .focus_modules ,
81- self .doc_type ,
82- self .custom_instructions ,
83- ])
84-
76+ return not any (
77+ [
78+ self .include_patterns ,
79+ self .exclude_patterns ,
80+ self .artifact_exclude ,
81+ self .focus_modules ,
82+ self .doc_type ,
83+ self .custom_instructions ,
84+ ]
85+ )
86+
8587 def get_prompt_addition (self ) -> str :
8688 """Generate prompt additions based on instructions."""
8789 additions = []
88-
90+
8991 if self .doc_type :
9092 doc_type_instructions = {
91- ' api' : "Focus on API documentation: endpoints, parameters, return types, and usage examples." ,
92- ' architecture' : "Focus on architecture documentation: system design, component relationships, and data flow." ,
93- ' user-guide' : "Focus on user guide documentation: how to use features, step-by-step tutorials." ,
94- ' developer' : "Focus on developer documentation: code structure, contribution guidelines, and implementation details." ,
93+ " api" : "Focus on API documentation: endpoints, parameters, return types, and usage examples." ,
94+ " architecture" : "Focus on architecture documentation: system design, component relationships, and data flow." ,
95+ " user-guide" : "Focus on user guide documentation: how to use features, step-by-step tutorials." ,
96+ " developer" : "Focus on developer documentation: code structure, contribution guidelines, and implementation details." ,
9597 }
9698 if self .doc_type .lower () in doc_type_instructions :
9799 additions .append (doc_type_instructions [self .doc_type .lower ()])
98100 else :
99101 additions .append (f"Focus on generating { self .doc_type } documentation." )
100-
102+
101103 if self .focus_modules :
102- additions .append (f"Pay special attention to and provide more detailed documentation for these modules: { ', ' .join (self .focus_modules )} " )
103-
104+ additions .append (
105+ f"Pay special attention to and provide more detailed documentation for these modules: { ', ' .join (self .focus_modules )} "
106+ )
107+
104108 if self .custom_instructions :
105109 additions .append (f"Additional instructions: { self .custom_instructions } " )
106-
110+
107111 return "\n " .join (additions ) if additions else ""
108112
109113
@@ -130,6 +134,7 @@ class Configuration:
130134 prompt_caching: Add prompt-cache breakpoints to agentic LLM calls (default: True)
131135 agent_instructions: Custom agent instructions for documentation generation
132136 """
137+
133138 base_url : str
134139 main_model : str
135140 cluster_model : str
@@ -146,7 +151,7 @@ class Configuration:
146151 use_gitignore : bool = True
147152 prompt_caching : bool = True
148153 agent_instructions : AgentInstructions = field (default_factory = AgentInstructions )
149-
154+
150155 def validate (self ):
151156 """
152157 Validate all configuration fields.
@@ -158,71 +163,72 @@ def validate(self):
158163 ConfigurationError: If validation fails
159164 """
160165 from codewiki .src .be .backend import is_caw_provider
166+
161167 if is_caw_provider (self .provider ):
162168 validate_model_name (self .main_model )
163169 return
164170 validate_url (self .base_url )
165171 validate_model_name (self .main_model )
166172 validate_model_name (self .cluster_model )
167173 validate_model_name (self .fallback_model )
168-
174+
169175 def to_dict (self ) -> dict :
170176 """Convert to dictionary."""
171177 result = {
172- ' base_url' : self .base_url ,
173- ' main_model' : self .main_model ,
174- ' cluster_model' : self .cluster_model ,
175- ' default_output' : self .default_output ,
176- ' provider' : self .provider ,
177- ' aws_region' : self .aws_region ,
178- ' api_version' : self .api_version ,
179- ' azure_deployment' : self .azure_deployment ,
180- ' max_tokens' : self .max_tokens ,
181- ' max_token_per_module' : self .max_token_per_module ,
182- ' max_token_per_leaf_module' : self .max_token_per_leaf_module ,
183- ' max_depth' : self .max_depth ,
184- ' use_gitignore' : self .use_gitignore ,
185- ' prompt_caching' : self .prompt_caching ,
186- ' fallback_model' : self .fallback_model ,
178+ " base_url" : self .base_url ,
179+ " main_model" : self .main_model ,
180+ " cluster_model" : self .cluster_model ,
181+ " default_output" : self .default_output ,
182+ " provider" : self .provider ,
183+ " aws_region" : self .aws_region ,
184+ " api_version" : self .api_version ,
185+ " azure_deployment" : self .azure_deployment ,
186+ " max_tokens" : self .max_tokens ,
187+ " max_token_per_module" : self .max_token_per_module ,
188+ " max_token_per_leaf_module" : self .max_token_per_leaf_module ,
189+ " max_depth" : self .max_depth ,
190+ " use_gitignore" : self .use_gitignore ,
191+ " prompt_caching" : self .prompt_caching ,
192+ " fallback_model" : self .fallback_model ,
187193 }
188194 if self .agent_instructions and not self .agent_instructions .is_empty ():
189- result [' agent_instructions' ] = self .agent_instructions .to_dict ()
195+ result [" agent_instructions" ] = self .agent_instructions .to_dict ()
190196 return result
191-
197+
192198 @classmethod
193- def from_dict (cls , data : dict ) -> ' Configuration' :
199+ def from_dict (cls , data : dict ) -> " Configuration" :
194200 """
195201 Create Configuration from dictionary.
196-
202+
197203 Args:
198204 data: Configuration dictionary
199-
205+
200206 Returns:
201207 Configuration instance
202208 """
203209 agent_instructions = AgentInstructions ()
204- if ' agent_instructions' in data :
205- agent_instructions = AgentInstructions .from_dict (data [' agent_instructions' ])
206-
210+ if " agent_instructions" in data :
211+ agent_instructions = AgentInstructions .from_dict (data [" agent_instructions" ])
212+
207213 return cls (
208- base_url = data .get (' base_url' , '' ),
209- main_model = data .get (' main_model' , '' ),
210- cluster_model = data .get (' cluster_model' , '' ),
211- fallback_model = data .get (' fallback_model' , ' glm-4p5' ),
212- default_output = data .get (' default_output' , ' docs' ),
213- provider = data .get (' provider' , ' openai-compatible' ),
214- aws_region = data .get (' aws_region' , ' us-east-1' ),
215- api_version = data .get (' api_version' , ' 2024-12-01-preview' ),
216- azure_deployment = data .get (' azure_deployment' , '' ),
217- max_tokens = data .get (' max_tokens' , 32768 ),
218- max_token_per_module = data .get (' max_token_per_module' , 36369 ),
219- max_token_per_leaf_module = data .get (' max_token_per_leaf_module' , 16000 ),
220- max_depth = data .get (' max_depth' , 2 ),
221- use_gitignore = data .get (' use_gitignore' , True ),
222- prompt_caching = data .get (' prompt_caching' , True ),
214+ base_url = data .get (" base_url" , "" ),
215+ main_model = data .get (" main_model" , "" ),
216+ cluster_model = data .get (" cluster_model" , "" ),
217+ fallback_model = data .get (" fallback_model" , " glm-4p5" ),
218+ default_output = data .get (" default_output" , " docs" ),
219+ provider = data .get (" provider" , " openai-compatible" ),
220+ aws_region = data .get (" aws_region" , " us-east-1" ),
221+ api_version = data .get (" api_version" , " 2024-12-01-preview" ),
222+ azure_deployment = data .get (" azure_deployment" , "" ),
223+ max_tokens = data .get (" max_tokens" , 32768 ),
224+ max_token_per_module = data .get (" max_token_per_module" , 36369 ),
225+ max_token_per_leaf_module = data .get (" max_token_per_leaf_module" , 16000 ),
226+ max_depth = data .get (" max_depth" , 2 ),
227+ use_gitignore = data .get (" use_gitignore" , True ),
228+ prompt_caching = data .get (" prompt_caching" , True ),
223229 agent_instructions = agent_instructions ,
224230 )
225-
231+
226232 def is_complete (self ) -> bool :
227233 """Check if all required fields are set.
228234
@@ -231,45 +237,53 @@ def is_complete(self) -> bool:
231237 are unused.
232238 """
233239 from codewiki .src .be .backend import is_caw_provider
240+
234241 if is_caw_provider (self .provider ):
235242 return bool (self .main_model )
236243 return bool (
237- self .base_url and
238- self .main_model and
239- self .cluster_model and
240- self .fallback_model
244+ self .base_url and self .main_model and self .cluster_model and self .fallback_model
241245 )
242-
243- def to_backend_config (self , repo_path : str , output_dir : str , api_key : str , runtime_instructions : AgentInstructions = None ):
246+
247+ def to_backend_config (
248+ self ,
249+ repo_path : str ,
250+ output_dir : str ,
251+ api_key : str ,
252+ runtime_instructions : AgentInstructions = None ,
253+ ):
244254 """
245255 Convert CLI Configuration to Backend Config.
246-
256+
247257 This method bridges the gap between persistent user settings (CLI Configuration)
248258 and runtime job configuration (Backend Config).
249-
259+
250260 Args:
251261 repo_path: Path to the repository to document
252262 output_dir: Output directory for generated documentation
253263 api_key: LLM API key (from keyring)
254264 runtime_instructions: Runtime agent instructions (override persistent settings)
255-
265+
256266 Returns:
257267 Backend Config instance ready for documentation generation
258268 """
259269 from codewiki .src .config import Config
260-
270+
261271 # Merge runtime instructions with persistent settings
262272 # Runtime instructions take precedence
263273 final_instructions = self .agent_instructions
264274 if runtime_instructions and not runtime_instructions .is_empty ():
265275 final_instructions = AgentInstructions (
266- include_patterns = runtime_instructions .include_patterns or self .agent_instructions .include_patterns ,
267- exclude_patterns = runtime_instructions .exclude_patterns or self .agent_instructions .exclude_patterns ,
268- focus_modules = runtime_instructions .focus_modules or self .agent_instructions .focus_modules ,
276+ include_patterns = runtime_instructions .include_patterns
277+ or self .agent_instructions .include_patterns ,
278+ exclude_patterns = runtime_instructions .exclude_patterns
279+ or self .agent_instructions .exclude_patterns ,
280+ focus_modules = runtime_instructions .focus_modules
281+ or self .agent_instructions .focus_modules ,
269282 doc_type = runtime_instructions .doc_type or self .agent_instructions .doc_type ,
270- custom_instructions = runtime_instructions .custom_instructions or self .agent_instructions .custom_instructions ,
283+ custom_instructions = runtime_instructions .custom_instructions
284+ or self .agent_instructions .custom_instructions ,
271285 )
272-
286+
273287 return Config .from_cli (
274288 repo_path = repo_path ,
275289 output_dir = output_dir ,
0 commit comments