Skip to content

Commit 008b651

Browse files
authored
Merge pull request #30 from FSoft-AI4Code/feat/custom-instruction
Feat/custom instruction
2 parents 60355ae + 12ced52 commit 008b651

File tree

18 files changed

+693
-33
lines changed

18 files changed

+693
-33
lines changed

DEVELOPMENT.md

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,13 @@ pip install -r requirements.txt
109109

110110
#### Command Structure (`cli/commands/`)
111111

112-
- `config.py`: Configuration management
113-
- `generate.py`: Documentation generation
112+
- `config.py`: Configuration management (API settings + agent instructions)
113+
- `generate.py`: Documentation generation with customization options
114+
115+
#### Models (`cli/models/`)
116+
117+
- `config.py`: Configuration data models including `AgentInstructions`
118+
- `job.py`: Job tracking models
114119

115120
#### Utilities (`cli/utils/`)
116121

@@ -119,6 +124,54 @@ pip install -r requirements.txt
119124
- `progress.py`: Progress tracking
120125
- `logging.py`: Logging configuration
121126

127+
### Agent Instructions System
128+
129+
The `AgentInstructions` model (`cli/models/config.py`) enables customization:
130+
131+
```python
132+
@dataclass
133+
class AgentInstructions:
134+
include_patterns: Optional[List[str]] = None # e.g., ["*.cs"]
135+
exclude_patterns: Optional[List[str]] = None # e.g., ["*Tests*"]
136+
focus_modules: Optional[List[str]] = None # e.g., ["src/core"]
137+
doc_type: Optional[str] = None # api, architecture, etc.
138+
custom_instructions: Optional[str] = None # Free-form text
139+
```
140+
141+
**How it flows through the system:**
142+
143+
1. **CLI Options** (`generate.py`) → Runtime `AgentInstructions`
144+
2. **Persistent Config** (`~/.codewiki/config.json`) → Default `AgentInstructions`
145+
3. **Backend Config** (`src/config.py`) → `agent_instructions` dict
146+
4. **Dependency Analyzer** → Uses `include_patterns` and `exclude_patterns` for file filtering
147+
5. **Agent Orchestrator** → Injects `custom_instructions` into LLM prompts
148+
149+
## Extending Agent Instructions
150+
151+
To add new customization options to the agent instructions system:
152+
153+
1. **Update the model** in `cli/models/config.py`:
154+
155+
```python
156+
@dataclass
157+
class AgentInstructions:
158+
# ... existing fields ...
159+
new_option: Optional[str] = None # Add new field
160+
```
161+
162+
2. **Update serialization methods** (`to_dict`, `from_dict`, `is_empty`, `get_prompt_addition`)
163+
164+
3. **Add CLI options** in `cli/commands/generate.py` and `cli/commands/config.py`
165+
166+
4. **Update backend Config** if the option affects analysis (`src/config.py`)
167+
168+
5. **Use in relevant components**:
169+
- File filtering → `dependency_analyzer/ast_parser.py`
170+
- Prompts → `be/prompt_template.py`
171+
- Agent creation → `be/agent_orchestrator.py`
172+
173+
---
174+
122175
## Adding Support for New Languages
123176

124177
To add support for a new programming language:

README.md

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,10 +134,72 @@ codewiki generate --verbose
134134
codewiki generate --create-branch --github-pages --verbose
135135
```
136136

137+
### Customization Options
138+
139+
CodeWiki supports customization for language-specific projects and documentation styles:
140+
141+
```bash
142+
# C# project: only analyze .cs files, exclude test directories
143+
codewiki generate --include "*.cs" --exclude "Tests,Specs,*.test.cs"
144+
145+
# Focus on specific modules with architecture-style docs
146+
codewiki generate --focus "src/core,src/api" --doc-type architecture
147+
148+
# Add custom instructions for the AI agent
149+
codewiki generate --instructions "Focus on public APIs and include usage examples"
150+
```
151+
152+
#### Pattern Behavior (Important!)
153+
154+
- **`--include`**: When specified, **ONLY** these patterns are used (replaces defaults completely)
155+
- Example: `--include "*.cs"` will analyze ONLY `.cs` files
156+
- If omitted, all supported file types are analyzed
157+
- Supports glob patterns: `*.py`, `src/**/*.ts`, `*.{js,jsx}`
158+
159+
- **`--exclude`**: When specified, patterns are **MERGED** with default ignore patterns
160+
- Example: `--exclude "Tests,Specs"` will exclude these directories AND still exclude `.git`, `__pycache__`, `node_modules`, etc.
161+
- Default patterns include: `.git`, `node_modules`, `__pycache__`, `*.pyc`, `bin/`, `dist/`, and many more
162+
- Supports multiple formats:
163+
- Exact names: `Tests`, `.env`, `config.local`
164+
- Glob patterns: `*.test.js`, `*_test.py`, `*.min.*`
165+
- Directory patterns: `build/`, `dist/`, `coverage/`
166+
167+
#### Setting Persistent Defaults
168+
169+
Save your preferred settings as defaults:
170+
171+
```bash
172+
# Set include patterns for C# projects
173+
codewiki config agent --include "*.cs"
174+
175+
# Exclude test projects by default (merged with default excludes)
176+
codewiki config agent --exclude "Tests,Specs,*.test.cs"
177+
178+
# Set focus modules
179+
codewiki config agent --focus "src/core,src/api"
180+
181+
# Set default documentation type
182+
codewiki config agent --doc-type architecture
183+
184+
# View current agent settings
185+
codewiki config agent
186+
187+
# Clear all agent settings
188+
codewiki config agent --clear
189+
```
190+
191+
| Option | Description | Behavior | Example |
192+
|--------|-------------|----------|---------|
193+
| `--include` | File patterns to include | **Replaces** defaults | `*.cs`, `*.py`, `src/**/*.ts` |
194+
| `--exclude` | Patterns to exclude | **Merges** with defaults | `Tests,Specs`, `*.test.js`, `build/` |
195+
| `--focus` | Modules to document in detail | Standalone option | `src/core,src/api` |
196+
| `--doc-type` | Documentation style | Standalone option | `api`, `architecture`, `user-guide`, `developer` |
197+
| `--instructions` | Custom agent instructions | Standalone option | Free-form text |
198+
137199
### Configuration Storage
138200

139201
- **API keys**: Securely stored in system keychain (macOS Keychain, Windows Credential Manager, Linux Secret Service)
140-
- **Settings**: `~/.codewiki/config.json`
202+
- **Settings & Agent Instructions**: `~/.codewiki/config.json`
141203

142204
---
143205

codewiki/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
This package provides a CLI tool for generating documentation from code repositories.
55
"""
66

7-
__version__ = "1.0.0"
7+
__version__ = "1.0.1"
88
__author__ = "CodeWiki Contributors"
99
__license__ = "MIT"
1010

codewiki/cli/adapters/doc_generator.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,8 @@ def generate(self) -> DocumentationJob:
136136
llm_api_key=self.config.get('api_key'),
137137
main_model=self.config.get('main_model'),
138138
cluster_model=self.config.get('cluster_model'),
139-
fallback_model=self.config.get('fallback_model')
139+
fallback_model=self.config.get('fallback_model'),
140+
agent_instructions=self.config.get('agent_instructions')
140141
)
141142

142143
# Run backend documentation generation

codewiki/cli/commands/config.py

Lines changed: 194 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@
55
import json
66
import sys
77
import click
8-
from typing import Optional
8+
from typing import Optional, List
99

1010
from codewiki.cli.config_manager import ConfigManager
11+
from codewiki.cli.models.config import AgentInstructions
1112
from codewiki.cli.utils.errors import (
1213
ConfigurationError,
1314
handle_error,
@@ -23,6 +24,13 @@
2324
)
2425

2526

27+
def parse_patterns(patterns_str: str) -> List[str]:
28+
"""Parse comma-separated patterns into a list."""
29+
if not patterns_str:
30+
return []
31+
return [p.strip() for p in patterns_str.split(',') if p.strip()]
32+
33+
2634
@click.group(name="config")
2735
def config_group():
2836
"""Manage CodeWiki configuration (API credentials and settings)."""
@@ -207,6 +215,7 @@ def config_show(output_json: bool):
207215
"cluster_model": config.cluster_model if config else "",
208216
"fallback_model": config.fallback_model if config else "glm-4p5",
209217
"default_output": config.default_output if config else "docs",
218+
"agent_instructions": config.agent_instructions.to_dict() if config and config.agent_instructions else {},
210219
"config_file": str(manager.config_file_path)
211220
}
212221
click.echo(json.dumps(output, indent=2))
@@ -239,6 +248,23 @@ def config_show(output_json: bool):
239248
if config:
240249
click.echo(f" Default Output: {config.default_output}")
241250

251+
click.echo()
252+
click.secho("Agent Instructions", fg="cyan", bold=True)
253+
if config and config.agent_instructions and not config.agent_instructions.is_empty():
254+
agent = config.agent_instructions
255+
if agent.include_patterns:
256+
click.echo(f" Include patterns: {', '.join(agent.include_patterns)}")
257+
if agent.exclude_patterns:
258+
click.echo(f" Exclude patterns: {', '.join(agent.exclude_patterns)}")
259+
if agent.focus_modules:
260+
click.echo(f" Focus modules: {', '.join(agent.focus_modules)}")
261+
if agent.doc_type:
262+
click.echo(f" Doc type: {agent.doc_type}")
263+
if agent.custom_instructions:
264+
click.echo(f" Custom instructions: {agent.custom_instructions[:50]}...")
265+
else:
266+
click.secho(" Using defaults (no custom settings)", fg="yellow")
267+
242268
click.echo()
243269
click.echo(f"Configuration file: {manager.config_file_path}")
244270
click.echo()
@@ -396,3 +422,170 @@ def config_validate(quick: bool, verbose: bool):
396422
except Exception as e:
397423
sys.exit(handle_error(e, verbose=verbose))
398424

425+
426+
@config_group.command(name="agent")
427+
@click.option(
428+
"--include",
429+
"-i",
430+
type=str,
431+
default=None,
432+
help="Comma-separated file patterns to include (e.g., '*.cs,*.py')",
433+
)
434+
@click.option(
435+
"--exclude",
436+
"-e",
437+
type=str,
438+
default=None,
439+
help="Comma-separated patterns to exclude (e.g., '*Tests*,*Specs*')",
440+
)
441+
@click.option(
442+
"--focus",
443+
"-f",
444+
type=str,
445+
default=None,
446+
help="Comma-separated modules/paths to focus on (e.g., 'src/core,src/api')",
447+
)
448+
@click.option(
449+
"--doc-type",
450+
"-t",
451+
type=click.Choice(['api', 'architecture', 'user-guide', 'developer'], case_sensitive=False),
452+
default=None,
453+
help="Default type of documentation to generate",
454+
)
455+
@click.option(
456+
"--instructions",
457+
type=str,
458+
default=None,
459+
help="Custom instructions for the documentation agent",
460+
)
461+
@click.option(
462+
"--clear",
463+
is_flag=True,
464+
help="Clear all agent instructions",
465+
)
466+
def config_agent(
467+
include: Optional[str],
468+
exclude: Optional[str],
469+
focus: Optional[str],
470+
doc_type: Optional[str],
471+
instructions: Optional[str],
472+
clear: bool
473+
):
474+
"""
475+
Configure default agent instructions for documentation generation.
476+
477+
These settings are used as defaults when running 'codewiki generate'.
478+
Runtime options (--include, --exclude, etc.) override these defaults.
479+
480+
Examples:
481+
482+
\b
483+
# Set include patterns for C# projects
484+
$ codewiki config agent --include "*.cs"
485+
486+
\b
487+
# Exclude test projects
488+
$ codewiki config agent --exclude "*Tests*,*Specs*,test_*"
489+
490+
\b
491+
# Focus on specific modules
492+
$ codewiki config agent --focus "src/core,src/api"
493+
494+
\b
495+
# Set default doc type
496+
$ codewiki config agent --doc-type architecture
497+
498+
\b
499+
# Add custom instructions
500+
$ codewiki config agent --instructions "Focus on public APIs and include usage examples"
501+
502+
\b
503+
# Clear all agent instructions
504+
$ codewiki config agent --clear
505+
"""
506+
try:
507+
manager = ConfigManager()
508+
509+
if not manager.load():
510+
click.secho("\n✗ Configuration not found.", fg="red", err=True)
511+
click.echo("\nPlease run 'codewiki config set' first to configure your API credentials.")
512+
sys.exit(EXIT_CONFIG_ERROR)
513+
514+
config = manager.get_config()
515+
516+
if clear:
517+
# Clear all agent instructions
518+
config.agent_instructions = AgentInstructions()
519+
manager.save()
520+
click.echo()
521+
click.secho("✓ Agent instructions cleared", fg="green")
522+
click.echo()
523+
return
524+
525+
# Check if at least one option is provided
526+
if not any([include, exclude, focus, doc_type, instructions]):
527+
# Display current settings
528+
click.echo()
529+
click.secho("Agent Instructions", fg="blue", bold=True)
530+
click.echo("━" * 40)
531+
click.echo()
532+
533+
agent = config.agent_instructions
534+
if agent and not agent.is_empty():
535+
if agent.include_patterns:
536+
click.echo(f" Include patterns: {', '.join(agent.include_patterns)}")
537+
if agent.exclude_patterns:
538+
click.echo(f" Exclude patterns: {', '.join(agent.exclude_patterns)}")
539+
if agent.focus_modules:
540+
click.echo(f" Focus modules: {', '.join(agent.focus_modules)}")
541+
if agent.doc_type:
542+
click.echo(f" Doc type: {agent.doc_type}")
543+
if agent.custom_instructions:
544+
click.echo(f" Custom instructions: {agent.custom_instructions}")
545+
else:
546+
click.secho(" No agent instructions configured (using defaults)", fg="yellow")
547+
548+
click.echo()
549+
click.echo("Use 'codewiki config agent --help' for usage information.")
550+
click.echo()
551+
return
552+
553+
# Update agent instructions
554+
current = config.agent_instructions or AgentInstructions()
555+
556+
if include is not None:
557+
current.include_patterns = parse_patterns(include) if include else None
558+
if exclude is not None:
559+
current.exclude_patterns = parse_patterns(exclude) if exclude else None
560+
if focus is not None:
561+
current.focus_modules = parse_patterns(focus) if focus else None
562+
if doc_type is not None:
563+
current.doc_type = doc_type if doc_type else None
564+
if instructions is not None:
565+
current.custom_instructions = instructions if instructions else None
566+
567+
config.agent_instructions = current
568+
manager.save()
569+
570+
# Display success messages
571+
click.echo()
572+
if include:
573+
click.secho(f"✓ Include patterns: {parse_patterns(include)}", fg="green")
574+
if exclude:
575+
click.secho(f"✓ Exclude patterns: {parse_patterns(exclude)}", fg="green")
576+
if focus:
577+
click.secho(f"✓ Focus modules: {parse_patterns(focus)}", fg="green")
578+
if doc_type:
579+
click.secho(f"✓ Doc type: {doc_type}", fg="green")
580+
if instructions:
581+
click.secho(f"✓ Custom instructions set", fg="green")
582+
583+
click.echo("\n" + click.style("Agent instructions updated successfully.", fg="green", bold=True))
584+
click.echo()
585+
586+
except ConfigurationError as e:
587+
click.secho(f"\n✗ Configuration error: {e.message}", fg="red", err=True)
588+
sys.exit(e.exit_code)
589+
except Exception as e:
590+
sys.exit(handle_error(e))
591+

0 commit comments

Comments
 (0)