IncludeCPP 3.2.1__tar.gz → 3.2.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {includecpp-3.2.1 → includecpp-3.2.2}/IncludeCPP.egg-info/PKG-INFO +7 -2
- {includecpp-3.2.1 → includecpp-3.2.2}/PKG-INFO +7 -2
- {includecpp-3.2.1 → includecpp-3.2.2}/README.md +6 -1
- {includecpp-3.2.1 → includecpp-3.2.2}/includecpp/__init__.py +1 -1
- {includecpp-3.2.1 → includecpp-3.2.2}/includecpp/cli/commands.py +116 -1
- {includecpp-3.2.1 → includecpp-3.2.2}/includecpp/core/ai_integration.py +134 -17
- {includecpp-3.2.1 → includecpp-3.2.2}/pyproject.toml +1 -1
- {includecpp-3.2.1 → includecpp-3.2.2}/IncludeCPP.egg-info/SOURCES.txt +0 -0
- {includecpp-3.2.1 → includecpp-3.2.2}/IncludeCPP.egg-info/dependency_links.txt +0 -0
- {includecpp-3.2.1 → includecpp-3.2.2}/IncludeCPP.egg-info/entry_points.txt +0 -0
- {includecpp-3.2.1 → includecpp-3.2.2}/IncludeCPP.egg-info/requires.txt +0 -0
- {includecpp-3.2.1 → includecpp-3.2.2}/IncludeCPP.egg-info/top_level.txt +0 -0
- {includecpp-3.2.1 → includecpp-3.2.2}/LICENSE +0 -0
- {includecpp-3.2.1 → includecpp-3.2.2}/MANIFEST.in +0 -0
- {includecpp-3.2.1 → includecpp-3.2.2}/includecpp/__init__.pyi +0 -0
- {includecpp-3.2.1 → includecpp-3.2.2}/includecpp/__main__.py +0 -0
- {includecpp-3.2.1 → includecpp-3.2.2}/includecpp/cli/__init__.py +0 -0
- {includecpp-3.2.1 → includecpp-3.2.2}/includecpp/cli/config_parser.py +0 -0
- {includecpp-3.2.1 → includecpp-3.2.2}/includecpp/core/__init__.py +0 -0
- {includecpp-3.2.1 → includecpp-3.2.2}/includecpp/core/build_manager.py +0 -0
- {includecpp-3.2.1 → includecpp-3.2.2}/includecpp/core/cpp_api.py +0 -0
- {includecpp-3.2.1 → includecpp-3.2.2}/includecpp/core/cpp_api.pyi +0 -0
- {includecpp-3.2.1 → includecpp-3.2.2}/includecpp/core/error_catalog.py +0 -0
- {includecpp-3.2.1 → includecpp-3.2.2}/includecpp/core/error_formatter.py +0 -0
- {includecpp-3.2.1 → includecpp-3.2.2}/includecpp/core/exceptions.py +0 -0
- {includecpp-3.2.1 → includecpp-3.2.2}/includecpp/core/path_discovery.py +0 -0
- {includecpp-3.2.1 → includecpp-3.2.2}/includecpp/core/settings_ui.py +0 -0
- {includecpp-3.2.1 → includecpp-3.2.2}/includecpp/generator/__init__.py +0 -0
- {includecpp-3.2.1 → includecpp-3.2.2}/includecpp/generator/parser.cpp +0 -0
- {includecpp-3.2.1 → includecpp-3.2.2}/includecpp/generator/parser.h +0 -0
- {includecpp-3.2.1 → includecpp-3.2.2}/includecpp/generator/type_resolver.cpp +0 -0
- {includecpp-3.2.1 → includecpp-3.2.2}/includecpp/generator/type_resolver.h +0 -0
- {includecpp-3.2.1 → includecpp-3.2.2}/includecpp/py.typed +0 -0
- {includecpp-3.2.1 → includecpp-3.2.2}/includecpp/templates/cpp.proj.template +0 -0
- {includecpp-3.2.1 → includecpp-3.2.2}/requirements.txt +0 -0
- {includecpp-3.2.1 → includecpp-3.2.2}/setup.cfg +0 -0
- {includecpp-3.2.1 → includecpp-3.2.2}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: IncludeCPP
|
|
3
|
-
Version: 3.2.
|
|
3
|
+
Version: 3.2.2
|
|
4
4
|
Summary: Professional C++ Python bindings with type-generic templates, pystubs and native threading
|
|
5
5
|
Home-page: https://github.com/includecpp/includecpp
|
|
6
6
|
Author: IncludeCPP Team
|
|
@@ -470,6 +470,11 @@ Options:
|
|
|
470
470
|
|
|
471
471
|
# Changelog
|
|
472
472
|
|
|
473
|
+
## v3.2.2
|
|
474
|
+
- Plugin command now detects comma-separated field declarations (e.g., `double x, y, z;` generates 3 FIELD entries)
|
|
475
|
+
- Fixed `ai optimize` timeout for multi-file operations (increased to 5 minutes)
|
|
476
|
+
- AI `ask` now extracts relevant CLI implementation when asking about commands/flags
|
|
477
|
+
|
|
473
478
|
## v3.2.1
|
|
474
479
|
- Fixed encoding error in `ai ask` output on Windows (GPT Unicode characters like non-breaking hyphen)
|
|
475
480
|
|
|
@@ -511,4 +516,4 @@ Options:
|
|
|
511
516
|
|
|
512
517
|
---
|
|
513
518
|
|
|
514
|
-
MIT License | v3.2.
|
|
519
|
+
MIT License | v3.2.2 | [GitHub](https://github.com/liliassg/IncludeCPP)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: IncludeCPP
|
|
3
|
-
Version: 3.2.
|
|
3
|
+
Version: 3.2.2
|
|
4
4
|
Summary: Professional C++ Python bindings with type-generic templates, pystubs and native threading
|
|
5
5
|
Home-page: https://github.com/includecpp/includecpp
|
|
6
6
|
Author: IncludeCPP Team
|
|
@@ -470,6 +470,11 @@ Options:
|
|
|
470
470
|
|
|
471
471
|
# Changelog
|
|
472
472
|
|
|
473
|
+
## v3.2.2
|
|
474
|
+
- Plugin command now detects comma-separated field declarations (e.g., `double x, y, z;` generates 3 FIELD entries)
|
|
475
|
+
- Fixed `ai optimize` timeout for multi-file operations (increased to 5 minutes)
|
|
476
|
+
- AI `ask` now extracts relevant CLI implementation when asking about commands/flags
|
|
477
|
+
|
|
473
478
|
## v3.2.1
|
|
474
479
|
- Fixed encoding error in `ai ask` output on Windows (GPT Unicode characters like non-breaking hyphen)
|
|
475
480
|
|
|
@@ -511,4 +516,4 @@ Options:
|
|
|
511
516
|
|
|
512
517
|
---
|
|
513
518
|
|
|
514
|
-
MIT License | v3.2.
|
|
519
|
+
MIT License | v3.2.2 | [GitHub](https://github.com/liliassg/IncludeCPP)
|
|
@@ -433,6 +433,11 @@ Options:
|
|
|
433
433
|
|
|
434
434
|
# Changelog
|
|
435
435
|
|
|
436
|
+
## v3.2.2
|
|
437
|
+
- Plugin command now detects comma-separated field declarations (e.g., `double x, y, z;` generates 3 FIELD entries)
|
|
438
|
+
- Fixed `ai optimize` timeout for multi-file operations (increased to 5 minutes)
|
|
439
|
+
- AI `ask` now extracts relevant CLI implementation when asking about commands/flags
|
|
440
|
+
|
|
436
441
|
## v3.2.1
|
|
437
442
|
- Fixed encoding error in `ai ask` output on Windows (GPT Unicode characters like non-breaking hyphen)
|
|
438
443
|
|
|
@@ -474,4 +479,4 @@ Options:
|
|
|
474
479
|
|
|
475
480
|
---
|
|
476
481
|
|
|
477
|
-
MIT License | v3.2.
|
|
482
|
+
MIT License | v3.2.2 | [GitHub](https://github.com/liliassg/IncludeCPP)
|
|
@@ -2524,6 +2524,107 @@ def plugin(plugin_name, files, private):
|
|
|
2524
2524
|
|
|
2525
2525
|
return methods, constructor_signatures, method_signatures
|
|
2526
2526
|
|
|
2527
|
+
def extract_fields(public_section, class_name):
|
|
2528
|
+
"""Extract member variable declarations from public section.
|
|
2529
|
+
|
|
2530
|
+
v3.2.2: Handles comma-separated field declarations like:
|
|
2531
|
+
double x, y, z; -> [('double', 'x'), ('double', 'y'), ('double', 'z')]
|
|
2532
|
+
"""
|
|
2533
|
+
fields = []
|
|
2534
|
+
|
|
2535
|
+
# Pattern to match field declarations
|
|
2536
|
+
# Matches: type name; OR type name1, name2, name3;
|
|
2537
|
+
# Handles: int x; double x, y, z; std::vector<int> items; const float PI = 3.14;
|
|
2538
|
+
field_pattern = re.compile(
|
|
2539
|
+
r'^\s*' # Start of line, optional whitespace
|
|
2540
|
+
r'(?:static\s+)?' # Optional static
|
|
2541
|
+
r'(const\s+)?' # Optional const (group 1)
|
|
2542
|
+
r'([a-zA-Z_][\w:]*(?:<[^<>]*(?:<[^<>]*>[^<>]*)*>)?)' # Type (group 2) - handles nested templates
|
|
2543
|
+
r'(\s*[&*])?' # Optional reference/pointer (group 3)
|
|
2544
|
+
r'\s+' # Required whitespace
|
|
2545
|
+
r'([^;(=]+)' # Names part - everything until ; ( or = (group 4)
|
|
2546
|
+
r'\s*(?:=\s*[^;]+)?' # Optional initializer
|
|
2547
|
+
r'\s*;', # Semicolon
|
|
2548
|
+
re.MULTILINE
|
|
2549
|
+
)
|
|
2550
|
+
|
|
2551
|
+
cpp_keywords = {
|
|
2552
|
+
'return', 'new', 'delete', 'throw', 'if', 'else', 'for', 'while', 'switch',
|
|
2553
|
+
'case', 'break', 'continue', 'class', 'struct', 'enum', 'typedef', 'using',
|
|
2554
|
+
'namespace', 'template', 'typename', 'virtual', 'override', 'final', 'public',
|
|
2555
|
+
'private', 'protected', 'friend', 'operator', 'sizeof', 'alignof', 'decltype',
|
|
2556
|
+
'auto', 'register', 'extern', 'mutable', 'thread_local', 'constexpr', 'consteval',
|
|
2557
|
+
'constinit', 'inline', 'volatile'
|
|
2558
|
+
}
|
|
2559
|
+
|
|
2560
|
+
# Process line by line to handle function body context
|
|
2561
|
+
lines = public_section.split('\n')
|
|
2562
|
+
brace_depth = 0
|
|
2563
|
+
|
|
2564
|
+
for line in lines:
|
|
2565
|
+
# Track brace depth to skip function bodies
|
|
2566
|
+
brace_depth += line.count('{') - line.count('}')
|
|
2567
|
+
if brace_depth > 0:
|
|
2568
|
+
continue # Inside a function body
|
|
2569
|
+
|
|
2570
|
+
# Skip lines that look like function declarations/definitions
|
|
2571
|
+
stripped = line.strip()
|
|
2572
|
+
if '(' in stripped and ')' in stripped:
|
|
2573
|
+
continue
|
|
2574
|
+
|
|
2575
|
+
match = field_pattern.match(line)
|
|
2576
|
+
if match:
|
|
2577
|
+
is_const = match.group(1) is not None
|
|
2578
|
+
base_type = match.group(2).strip()
|
|
2579
|
+
ref_ptr = (match.group(3) or '').strip()
|
|
2580
|
+
names_part = match.group(4).strip()
|
|
2581
|
+
|
|
2582
|
+
# Skip if type looks like a keyword or constructor
|
|
2583
|
+
if base_type.lower() in cpp_keywords:
|
|
2584
|
+
continue
|
|
2585
|
+
if base_type == class_name:
|
|
2586
|
+
continue # Constructor, not a field
|
|
2587
|
+
|
|
2588
|
+
# Build full type
|
|
2589
|
+
full_type = ''
|
|
2590
|
+
if is_const:
|
|
2591
|
+
full_type = 'const '
|
|
2592
|
+
full_type += base_type
|
|
2593
|
+
if ref_ptr:
|
|
2594
|
+
full_type += ref_ptr
|
|
2595
|
+
|
|
2596
|
+
# Split comma-separated names: "x, y, z" -> ["x", "y", "z"]
|
|
2597
|
+
# Handle cases like: "*ptr1, *ptr2" or "&ref1, &ref2"
|
|
2598
|
+
name_parts = names_part.split(',')
|
|
2599
|
+
|
|
2600
|
+
for name in name_parts:
|
|
2601
|
+
name = name.strip()
|
|
2602
|
+
if not name:
|
|
2603
|
+
continue
|
|
2604
|
+
|
|
2605
|
+
# Handle pointer/reference attached to variable name
|
|
2606
|
+
actual_type = full_type
|
|
2607
|
+
if name.startswith('*'):
|
|
2608
|
+
name = name[1:].strip()
|
|
2609
|
+
if '*' not in actual_type:
|
|
2610
|
+
actual_type += '*'
|
|
2611
|
+
elif name.startswith('&'):
|
|
2612
|
+
name = name[1:].strip()
|
|
2613
|
+
if '&' not in actual_type:
|
|
2614
|
+
actual_type += '&'
|
|
2615
|
+
|
|
2616
|
+
# Remove array brackets if present
|
|
2617
|
+
if '[' in name:
|
|
2618
|
+
name = name[:name.find('[')]
|
|
2619
|
+
|
|
2620
|
+
# Validate field name
|
|
2621
|
+
if name and re.match(r'^[a-zA-Z_]\w*$', name):
|
|
2622
|
+
# Skip if name is a keyword
|
|
2623
|
+
if name.lower() not in cpp_keywords:
|
|
2624
|
+
fields.append((actual_type, name))
|
|
2625
|
+
|
|
2626
|
+
return fields
|
|
2627
|
+
|
|
2527
2628
|
all_files = cpp_files + h_files
|
|
2528
2629
|
|
|
2529
2630
|
for file in all_files:
|
|
@@ -2570,7 +2671,7 @@ def plugin(plugin_name, files, private):
|
|
|
2570
2671
|
public_section = extract_public_section(class_body, is_struct)
|
|
2571
2672
|
|
|
2572
2673
|
if class_name not in classes:
|
|
2573
|
-
classes[class_name] = {'methods': set(), 'constructors': [], 'method_signatures': {}}
|
|
2674
|
+
classes[class_name] = {'methods': set(), 'constructors': [], 'method_signatures': {}, 'fields': []}
|
|
2574
2675
|
|
|
2575
2676
|
methods, constructor_sigs, method_sigs = extract_methods(public_section, class_name)
|
|
2576
2677
|
classes[class_name]['methods'].update(methods)
|
|
@@ -2588,6 +2689,12 @@ def plugin(plugin_name, files, private):
|
|
|
2588
2689
|
classes[class_name]['constructors'].append(sig)
|
|
2589
2690
|
existing_ctors.add(sig)
|
|
2590
2691
|
|
|
2692
|
+
# v3.2.2: Extract fields (including comma-separated declarations)
|
|
2693
|
+
field_list = extract_fields(public_section, class_name)
|
|
2694
|
+
for field_type, field_name in field_list:
|
|
2695
|
+
if (field_type, field_name) not in classes[class_name]['fields']:
|
|
2696
|
+
classes[class_name]['fields'].append((field_type, field_name))
|
|
2697
|
+
|
|
2591
2698
|
# Find free functions (not inside class bodies)
|
|
2592
2699
|
# First, remove all class bodies from content to avoid matching class methods
|
|
2593
2700
|
content_no_classes = content
|
|
@@ -2718,6 +2825,11 @@ def plugin(plugin_name, files, private):
|
|
|
2718
2825
|
for method in sorted(cls_info['methods']):
|
|
2719
2826
|
f.write(f' METHOD({method})\n')
|
|
2720
2827
|
|
|
2828
|
+
# v3.2.2: Write fields
|
|
2829
|
+
if cls_info.get('fields'):
|
|
2830
|
+
for field_type, field_name in cls_info['fields']:
|
|
2831
|
+
f.write(f' FIELD({field_type}, {field_name})\n')
|
|
2832
|
+
|
|
2721
2833
|
f.write(f' }}\n')
|
|
2722
2834
|
|
|
2723
2835
|
if classes and (public_functions or template_functions):
|
|
@@ -2741,6 +2853,9 @@ def plugin(plugin_name, files, private):
|
|
|
2741
2853
|
|
|
2742
2854
|
click.secho(f"Generated plugin: {cp_file}", fg='green', bold=True)
|
|
2743
2855
|
click.echo(f"Classes found: {len(classes)}")
|
|
2856
|
+
total_fields = sum(len(c.get('fields', [])) for c in classes.values())
|
|
2857
|
+
if total_fields:
|
|
2858
|
+
click.echo(f"Fields found: {total_fields}")
|
|
2744
2859
|
click.echo(f"Template functions: {len(template_functions)}")
|
|
2745
2860
|
click.echo(f"Public functions: {len(public_functions)}")
|
|
2746
2861
|
if private_set:
|
|
@@ -29,20 +29,36 @@ CONTEXT_LIMITS = {
|
|
|
29
29
|
|
|
30
30
|
INCLUDECPP_CONTEXT = '''
|
|
31
31
|
CRITICAL KNOWLEDGE FOR INCLUDECPP:
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
32
|
+
|
|
33
|
+
1. NAMESPACE REQUIREMENT:
|
|
34
|
+
ALL C++ code MUST be inside `namespace includecpp { }` - this is REQUIRED, not optional.
|
|
35
|
+
|
|
36
|
+
2. PLUGIN FILE (.cp) FORMAT:
|
|
37
|
+
SOURCE(file.cpp) module_name
|
|
38
|
+
PUBLIC:
|
|
39
|
+
module_name CLASS(MyClass) {
|
|
40
|
+
CONSTRUCTOR()
|
|
41
|
+
CONSTRUCTOR(int, double)
|
|
42
|
+
METHOD(foo)
|
|
43
|
+
METHOD_CONST(bar, const std::string&)
|
|
44
|
+
FIELD(double, x)
|
|
45
|
+
}
|
|
46
|
+
module_name FUNC(standalone_function)
|
|
47
|
+
module_name TEMPLATE_FUNC(generic_func) TYPES(int, float, double)
|
|
48
|
+
module_name STRUCT(Point) { FIELD(double, x) FIELD(double, y) }
|
|
49
|
+
|
|
50
|
+
3. BUILD OUTPUT:
|
|
51
|
+
~/.includecpp/builds/ (Windows: %APPDATA%/IncludeCPP/)
|
|
52
|
+
|
|
53
|
+
4. COMMON ERRORS AND FIXES:
|
|
54
|
+
* "undefined reference" -> Code not in namespace includecpp { }, or missing FUNC() in .cp
|
|
55
|
+
* "no matching function" -> Wrong parameter types in .cp METHOD() definition
|
|
56
|
+
* "template instantiation" -> Missing TEMPLATE_FUNC() with TYPES() in .cp file
|
|
57
|
+
* "namespace includecpp not found" -> Source file missing namespace wrapper
|
|
58
|
+
* "no member named X" -> Method not in class public section, or missing METHOD() in .cp
|
|
59
|
+
|
|
60
|
+
5. FIELD DECLARATIONS:
|
|
61
|
+
Comma-separated fields like `double x, y, z;` are parsed as separate fields.
|
|
46
62
|
'''
|
|
47
63
|
|
|
48
64
|
SYSTEM_PROMPT_OPTIMIZE = '''You are a C++ expert specializing in pybind11 bindings and the IncludeCPP framework.
|
|
@@ -313,12 +329,27 @@ REASON: <why>
|
|
|
313
329
|
Be thorough. This is professional-grade analysis.'''
|
|
314
330
|
|
|
315
331
|
|
|
332
|
+
CLI_KEYWORDS = {
|
|
333
|
+
'plugin': ['def plugin', '@cli.command', 'plugin_name', 'extract_fields', 'extract_methods'],
|
|
334
|
+
'rebuild': ['def rebuild', 'build_manager', '--fast', '--clean', '--auto-ai'],
|
|
335
|
+
'build': ['def build', 'build_manager'],
|
|
336
|
+
'auto': ['def auto', 'auto_plugins', '--all'],
|
|
337
|
+
'fix': ['def fix', 'fix_code', '--ai', 'ai_mgr'],
|
|
338
|
+
'init': ['def init', 'cpp.proj', 'plugins/', 'include/'],
|
|
339
|
+
'ai': ['@ai.command', 'ai_mgr', 'get_ai_manager', 'ai ask', 'ai edit', 'ai optimize'],
|
|
340
|
+
'settings': ['def settings', 'settings_ui', 'PyQt6'],
|
|
341
|
+
'flag': ['@click.option', 'is_flag', '--think', '--websearch', '--confirm'],
|
|
342
|
+
'command': ['@cli.command', '@click.argument', '@click.option'],
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
|
|
316
346
|
class AIManager:
|
|
317
347
|
def __init__(self):
|
|
318
348
|
self.secret_dir = Path.home() / '.includecpp'
|
|
319
349
|
self.secret_path = self.secret_dir / '.secret'
|
|
320
350
|
self.config = self._load_config()
|
|
321
351
|
self._doc_cache = None
|
|
352
|
+
self._cli_cache = None
|
|
322
353
|
|
|
323
354
|
def _get_documentation(self) -> str:
|
|
324
355
|
if self._doc_cache:
|
|
@@ -359,6 +390,85 @@ class AIManager:
|
|
|
359
390
|
return '\n\nBUILD CONTEXT (user\'s projects):\n' + '\n'.join(info_parts[:5])
|
|
360
391
|
return ''
|
|
361
392
|
|
|
393
|
+
def _get_cli_context(self, question: str) -> str:
|
|
394
|
+
"""Extract relevant CLI implementation context based on the question.
|
|
395
|
+
|
|
396
|
+
Only extracts code sections matching keywords from the question to save tokens.
|
|
397
|
+
"""
|
|
398
|
+
question_lower = question.lower()
|
|
399
|
+
|
|
400
|
+
# Check if question is about CLI/commands
|
|
401
|
+
cli_terms = ['command', 'flag', 'option', 'cli', 'includecpp', '--', 'how to', 'usage']
|
|
402
|
+
if not any(term in question_lower for term in cli_terms):
|
|
403
|
+
return ''
|
|
404
|
+
|
|
405
|
+
# Find which CLI topics are relevant
|
|
406
|
+
relevant_keywords = set()
|
|
407
|
+
for topic, keywords in CLI_KEYWORDS.items():
|
|
408
|
+
if topic in question_lower:
|
|
409
|
+
relevant_keywords.update(keywords)
|
|
410
|
+
|
|
411
|
+
# Add generic command keywords if asking about flags/options
|
|
412
|
+
if '--' in question or 'flag' in question_lower or 'option' in question_lower:
|
|
413
|
+
relevant_keywords.update(CLI_KEYWORDS['flag'])
|
|
414
|
+
|
|
415
|
+
if not relevant_keywords:
|
|
416
|
+
return ''
|
|
417
|
+
|
|
418
|
+
# Load CLI source if not cached
|
|
419
|
+
if self._cli_cache is None:
|
|
420
|
+
try:
|
|
421
|
+
cli_path = Path(__file__).parent.parent / 'cli' / 'commands.py'
|
|
422
|
+
if cli_path.exists():
|
|
423
|
+
self._cli_cache = cli_path.read_text(encoding='utf-8')
|
|
424
|
+
except:
|
|
425
|
+
return ''
|
|
426
|
+
|
|
427
|
+
if not self._cli_cache:
|
|
428
|
+
return ''
|
|
429
|
+
|
|
430
|
+
# Extract relevant sections (functions/decorators containing keywords)
|
|
431
|
+
lines = self._cli_cache.split('\n')
|
|
432
|
+
extracted = []
|
|
433
|
+
in_relevant_block = False
|
|
434
|
+
block_lines = []
|
|
435
|
+
indent_level = 0
|
|
436
|
+
|
|
437
|
+
for i, line in enumerate(lines):
|
|
438
|
+
stripped = line.strip()
|
|
439
|
+
|
|
440
|
+
# Check for function/decorator start
|
|
441
|
+
if stripped.startswith('@') or stripped.startswith('def '):
|
|
442
|
+
# Save previous block if relevant
|
|
443
|
+
if in_relevant_block and block_lines:
|
|
444
|
+
extracted.extend(block_lines[:50]) # Max 50 lines per block
|
|
445
|
+
extracted.append(' # ... (truncated)\n')
|
|
446
|
+
|
|
447
|
+
# Check if new block is relevant
|
|
448
|
+
in_relevant_block = any(kw in line for kw in relevant_keywords)
|
|
449
|
+
block_lines = [f'{i+1}: {line}'] if in_relevant_block else []
|
|
450
|
+
indent_level = len(line) - len(line.lstrip())
|
|
451
|
+
|
|
452
|
+
elif in_relevant_block:
|
|
453
|
+
# Continue block until dedent
|
|
454
|
+
current_indent = len(line) - len(line.lstrip()) if stripped else indent_level + 1
|
|
455
|
+
if stripped and current_indent <= indent_level and not stripped.startswith('@'):
|
|
456
|
+
# Block ended
|
|
457
|
+
if block_lines:
|
|
458
|
+
extracted.extend(block_lines[:50])
|
|
459
|
+
if len(block_lines) > 50:
|
|
460
|
+
extracted.append(' # ... (truncated)\n')
|
|
461
|
+
in_relevant_block = False
|
|
462
|
+
block_lines = []
|
|
463
|
+
else:
|
|
464
|
+
block_lines.append(f'{i+1}: {line}')
|
|
465
|
+
|
|
466
|
+
# Limit total context
|
|
467
|
+
if extracted:
|
|
468
|
+
context = '\n'.join(extracted[:200]) # Max 200 lines total
|
|
469
|
+
return f'\n\nCLI IMPLEMENTATION (relevant sections):\n```python\n{context}\n```'
|
|
470
|
+
return ''
|
|
471
|
+
|
|
362
472
|
def _get_context_limit(self, think: bool = False, think_twice: bool = False,
|
|
363
473
|
think_three: bool = False) -> int:
|
|
364
474
|
"""Get the appropriate context limit based on thinking mode."""
|
|
@@ -646,7 +756,8 @@ class AIManager:
|
|
|
646
756
|
self.config['daily_usage']['tokens'] = self.config['daily_usage'].get('tokens', 0) + tokens
|
|
647
757
|
self._save_config()
|
|
648
758
|
|
|
649
|
-
def query(self, system_prompt: str, user_prompt: str, temperature: float = 0.3
|
|
759
|
+
def query(self, system_prompt: str, user_prompt: str, temperature: float = 0.3,
|
|
760
|
+
timeout: int = 180) -> Tuple[bool, str]:
|
|
650
761
|
if not self.config.get('api_key'):
|
|
651
762
|
return False, 'No API key configured'
|
|
652
763
|
can_proceed, limit_warning = self._check_daily_limit()
|
|
@@ -672,7 +783,7 @@ class AIManager:
|
|
|
672
783
|
data['max_tokens'] = token_limit
|
|
673
784
|
data['temperature'] = temperature
|
|
674
785
|
try:
|
|
675
|
-
response = requests.post(OPENAI_API_URL, headers=headers, json=data, timeout=
|
|
786
|
+
response = requests.post(OPENAI_API_URL, headers=headers, json=data, timeout=timeout)
|
|
676
787
|
if response.status_code == 200:
|
|
677
788
|
result = response.json()
|
|
678
789
|
content = result['choices'][0]['message']['content']
|
|
@@ -724,7 +835,9 @@ class AIManager:
|
|
|
724
835
|
prompt = f'Optimize the following C++ files for performance, safety, and pybind11 compatibility:\n{file_content}'
|
|
725
836
|
system = SYSTEM_PROMPT_OPTIMIZE
|
|
726
837
|
prompt = self._build_prompt_with_docs(prompt)
|
|
727
|
-
|
|
838
|
+
# v3.2.2: Use longer timeout (5 min) for optimize operations with multiple files
|
|
839
|
+
timeout = 300 if len(files) > 1 else 180
|
|
840
|
+
success, response = self.query(system, prompt, timeout=timeout)
|
|
728
841
|
if not success:
|
|
729
842
|
return False, response, []
|
|
730
843
|
changes = self._parse_file_changes(response)
|
|
@@ -889,6 +1002,10 @@ class AIManager:
|
|
|
889
1002
|
context_parts.append('\nPlugin definitions:')
|
|
890
1003
|
for path, content in plugins.items():
|
|
891
1004
|
context_parts.append(f'\nPLUGIN: {path}\n```\n{content}\n```')
|
|
1005
|
+
# v3.2.2: Add CLI context for questions about commands/flags
|
|
1006
|
+
cli_context = self._get_cli_context(question)
|
|
1007
|
+
if cli_context:
|
|
1008
|
+
context_parts.append(cli_context)
|
|
892
1009
|
context = '\n'.join(context_parts)
|
|
893
1010
|
prompt = f'Question: {question}\n\n{context}'
|
|
894
1011
|
if think_three:
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "IncludeCPP"
|
|
7
|
-
version = "3.2.
|
|
7
|
+
version = "3.2.2"
|
|
8
8
|
description = "Professional C++ Python bindings with type-generic templates, pystubs and native threading"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.8"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|