CONPORT implementation - Autotest fix
This commit is contained in:
parent
85e94a3d0d
commit
ca92c72070
45
.roo/mcp.json
Normal file
45
.roo/mcp.json
Normal file
@ -0,0 +1,45 @@
|
||||
{
|
||||
"mcpServers": {
|
||||
"conport": {
|
||||
"command": "C:\\Users\\theis\\context-portal\\.venv\\Scripts\\python.exe",
|
||||
"args": [
|
||||
"C:\\Users\\theis\\context-portal\\src\\context_portal_mcp\\main.py",
|
||||
"--mode",
|
||||
"stdio",
|
||||
"--workspace_id",
|
||||
"${workspaceFolder}"
|
||||
],
|
||||
"alwaysAllow": [
|
||||
"get_product_context",
|
||||
"update_product_context",
|
||||
"get_active_context",
|
||||
"update_active_context",
|
||||
"log_decision",
|
||||
"get_decisions",
|
||||
"search_decisions_fts",
|
||||
"log_progress",
|
||||
"get_progress",
|
||||
"update_progress",
|
||||
"delete_progress_by_id",
|
||||
"log_system_pattern",
|
||||
"get_system_patterns",
|
||||
"log_custom_data",
|
||||
"get_custom_data",
|
||||
"delete_custom_data",
|
||||
"search_project_glossary_fts",
|
||||
"export_conport_to_markdown",
|
||||
"import_markdown_to_conport",
|
||||
"link_conport_items",
|
||||
"search_custom_data_value_fts",
|
||||
"get_linked_items",
|
||||
"batch_log_items",
|
||||
"get_item_history",
|
||||
"delete_decision_by_id",
|
||||
"delete_system_pattern_by_id",
|
||||
"get_conport_schema",
|
||||
"get_recent_activity_summary",
|
||||
"semantic_search_conport"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -26,7 +26,7 @@
|
||||
},
|
||||
{
|
||||
"file_path": "BoucleChunky001_DISP_1K_METALNESS.png",
|
||||
"item_type": "MAP_DISP",
|
||||
"item_type": "EXTRA",
|
||||
"target_asset_name_override": "BoucleChunky001"
|
||||
},
|
||||
{
|
||||
|
||||
108
autotest.py
108
autotest.py
@ -584,63 +584,59 @@ class AutoTester(QObject):
|
||||
logger.error(f"Value mismatch for field '{key}' in {item_type_name} ({current_context}): Actual='{actual_value}', Expected='{expected_value}'.")
|
||||
item_match = False
|
||||
|
||||
return item_match
|
||||
|
||||
def _compare_list_of_rules(self, actual_list: List[Dict[str, Any]], expected_list: List[Dict[str, Any]], item_type_name: str, parent_context: str, item_key_field: str) -> bool:
|
||||
"""
|
||||
Compares a list of actual rule items against a list of expected rule items.
|
||||
Items are matched by a key field (e.g., 'asset_name' or 'file_path').
|
||||
Order independent for matching, but logs count mismatches.
|
||||
"""
|
||||
list_match = True # Corrected indentation
|
||||
if not isinstance(actual_list, list) or not isinstance(expected_list, list):
|
||||
logger.error(f"Type mismatch for list of {item_type_name}s in {parent_context}. Expected lists.")
|
||||
return False
|
||||
|
||||
if len(actual_list) != len(expected_list):
|
||||
logger.error(f"Mismatch in number of {item_type_name}s for {parent_context}. Actual: {len(actual_list)}, Expected: {len(expected_list)}.")
|
||||
list_match = False # Count mismatch is an error
|
||||
# If counts differ, we still try to match what we can to provide more detailed feedback,
|
||||
# but the overall list_match will remain False.
|
||||
|
||||
actual_items_map = {item.get(item_key_field): item for item in actual_list if item.get(item_key_field) is not None}
|
||||
|
||||
# Keep track of expected items that found a match to identify missing ones more easily
|
||||
matched_expected_keys = set()
|
||||
|
||||
for expected_item in expected_list:
|
||||
expected_key_value = expected_item.get(item_key_field)
|
||||
if expected_key_value is None:
|
||||
logger.error(f"Expected {item_type_name} in {parent_context} is missing key field '{item_key_field}'. Cannot compare this item: {expected_item}")
|
||||
list_match = False # This specific expected item cannot be processed
|
||||
continue
|
||||
|
||||
actual_item = actual_items_map.get(expected_key_value)
|
||||
if actual_item:
|
||||
matched_expected_keys.add(expected_key_value)
|
||||
if not self._compare_rule_item(actual_item, expected_item, item_type_name, parent_context):
|
||||
list_match = False # Individual item comparison failed
|
||||
else:
|
||||
logger.error(f"Expected {item_type_name} with {item_key_field} '{expected_key_value}' not found in actual items for {parent_context}.")
|
||||
list_match = False
|
||||
|
||||
# Identify actual items that were not matched by any expected item
|
||||
# This is useful if len(actual_list) >= len(expected_list) but some actual items are "extra"
|
||||
for actual_key_value, actual_item_data in actual_items_map.items():
|
||||
if actual_key_value not in matched_expected_keys:
|
||||
logger.debug(f"Extra actual {item_type_name} with {item_key_field} '{actual_key_value}' found in {parent_context} (not in expected list or already matched).")
|
||||
if len(actual_list) != len(expected_list): # If counts already flagged a mismatch, this is just detail
|
||||
pass
|
||||
else: # Counts matched, but content didn't align perfectly by key
|
||||
list_match = False
|
||||
|
||||
|
||||
return list_match # Corrected indentation
|
||||
|
||||
def _compare_rules(self, actual_rules_data: Dict[str, Any], expected_rules_data: Dict[str, Any]) -> bool: # Corrected structure: moved out
|
||||
item_match = False
|
||||
|
||||
return item_match
|
||||
|
||||
def _compare_list_of_rules(self, actual_list: List[Dict[str, Any]], expected_list: List[Dict[str, Any]], item_type_name: str, parent_context: str, item_key_field: str) -> bool:
|
||||
"""
|
||||
Compares a list of actual rule items against a list of expected rule items.
|
||||
Items are matched by a key field (e.g., 'asset_name' or 'file_path').
|
||||
Order independent for matching, but logs count mismatches.
|
||||
"""
|
||||
list_match = True
|
||||
if not isinstance(actual_list, list) or not isinstance(expected_list, list):
|
||||
logger.error(f"Type mismatch for list of {item_type_name}s in {parent_context}. Expected lists.")
|
||||
return False
|
||||
|
||||
if len(actual_list) != len(expected_list):
|
||||
logger.error(f"Mismatch in number of {item_type_name}s for {parent_context}. Actual: {len(actual_list)}, Expected: {len(expected_list)}.")
|
||||
list_match = False # Count mismatch is an error
|
||||
# If counts differ, we still try to match what we can to provide more detailed feedback,
|
||||
# but the overall list_match will remain False.
|
||||
|
||||
actual_items_map = {item.get(item_key_field): item for item in actual_list if item.get(item_key_field) is not None}
|
||||
|
||||
# Keep track of expected items that found a match to identify missing ones more easily
|
||||
matched_expected_keys = set()
|
||||
|
||||
for expected_item in expected_list:
|
||||
expected_key_value = expected_item.get(item_key_field)
|
||||
if expected_key_value is None:
|
||||
logger.error(f"Expected {item_type_name} in {parent_context} is missing key field '{item_key_field}'. Cannot compare this item: {expected_item}")
|
||||
list_match = False # This specific expected item cannot be processed
|
||||
continue
|
||||
|
||||
actual_item = actual_items_map.get(expected_key_value)
|
||||
if actual_item:
|
||||
matched_expected_keys.add(expected_key_value)
|
||||
if not self._compare_rule_item(actual_item, expected_item, item_type_name, parent_context):
|
||||
list_match = False # Individual item comparison failed
|
||||
else:
|
||||
logger.error(f"Expected {item_type_name} with {item_key_field} '{expected_key_value}' not found in actual items for {parent_context}.")
|
||||
list_match = False
|
||||
|
||||
# Identify actual items that were not matched by any expected item
|
||||
# This is useful if len(actual_list) >= len(expected_list) but some actual items are "extra"
|
||||
for actual_key_value, actual_item_data in actual_items_map.items():
|
||||
if actual_key_value not in matched_expected_keys:
|
||||
logger.debug(f"Extra actual {item_type_name} with {item_key_field} '{actual_key_value}' found in {parent_context} (not in expected list or already matched).")
|
||||
if len(actual_list) != len(expected_list): # If counts already flagged a mismatch, this is just detail
|
||||
pass
|
||||
else: # Counts matched, but content didn't align perfectly by key
|
||||
list_match = False
|
||||
|
||||
|
||||
return list_match
|
||||
|
||||
|
||||
def _compare_rules(self, actual_rules_data: Dict[str, Any], expected_rules_data: Dict[str, Any]) -> bool:
|
||||
"""
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
context_portal/conport_vector_data/chroma.sqlite3
Normal file
BIN
context_portal/conport_vector_data/chroma.sqlite3
Normal file
Binary file not shown.
BIN
context_portal/context.db
Normal file
BIN
context_portal/context.db
Normal file
Binary file not shown.
44
projectBrief.md
Normal file
44
projectBrief.md
Normal file
@ -0,0 +1,44 @@
|
||||
# Project Brief: Asset Processor Tool
|
||||
|
||||
## 1. Main Goal & Purpose
|
||||
|
||||
The primary goal of the Asset Processor Tool is to provide **CG artists and 3D content teams with a friendly, fast, and flexible interface to process and organize 3D asset source files into a standardized library format.** It automates repetitive and complex tasks involved in preparing assets from various suppliers for use in production pipelines.
|
||||
|
||||
## 2. Key Features & Components
|
||||
|
||||
* **Automated Asset Processing:** Ingests 3D asset source files (texture sets, models, etc.) from `.zip`, `.rar`, `.7z` archives, or folders.
|
||||
* **Preset-Driven Workflow:** Utilizes configurable JSON presets to interpret different asset sources (e.g., from various online vendors or internal standards), defining rules for file classification and processing.
|
||||
* **Comprehensive File Operations:**
|
||||
* **Classification:** Automatically identifies map types (Color, Normal, Roughness, etc.), models, and other file categories based on preset rules.
|
||||
* **Image Processing:** Performs tasks like image resizing (to standard resolutions like 1K, 2K, 4K, avoiding upscaling), glossiness-to-roughness conversion, normal map green channel inversion (OpenGL/DirectX handling), alpha channel extraction, bit-depth adjustments, and low-resolution fallback generation for small source images.
|
||||
* **Channel Merging:** Combines channels from different source maps into packed textures (e.g., Normal + Roughness + Metallic into a single NRMRGH map).
|
||||
* **Metadata Generation:** Creates a detailed `metadata.json` file for each processed asset, containing information about maps, categories, processing settings, and more, for downstream tool integration.
|
||||
* **Flexible Output Organization:** Generates a clean, structured output directory based on user-configurable naming patterns and tokens.
|
||||
* **Multiple User Interfaces:**
|
||||
* **Graphical User Interface (GUI):** The primary interface, designed to be user-friendly, offering drag-and-drop functionality, an integrated preset editor, a live preview table for rule validation and overrides, and clear processing controls.
|
||||
* **Directory Monitor:** An automated script that watches a specified folder for new asset archives and processes them based on preset names embedded in the archive filename.
|
||||
* **Command-Line Interface (CLI):** Intended for batch processing and scripting (currently with limited core functionality).
|
||||
* **Optional Blender Integration:** Can automatically run Blender scripts post-processing to create PBR node groups and materials in specified `.blend` files, linking to the newly processed textures.
|
||||
* **Hierarchical Rule System:** Allows for dynamic, granular overrides of preset configurations at the source, asset, or individual file level via the GUI.
|
||||
* **Experimental LLM Prediction:** Includes an option to use a Large Language Model for file interpretation and rule prediction.
|
||||
|
||||
## 3. Target Audience
|
||||
|
||||
* **CG Artists:** Individual artists looking for an efficient way to manage and prepare their personal or downloaded asset libraries.
|
||||
* **3D Content Creation Teams:** Studios or groups needing a standardized pipeline for processing and organizing assets from multiple sources.
|
||||
* **Technical Artists/Pipeline Developers:** Who may extend or integrate the tool into broader production workflows.
|
||||
|
||||
## 4. Overall Architectural Style & Key Technologies
|
||||
|
||||
* **Core Language:** Python
|
||||
* **GUI Framework:** PySide6
|
||||
* **Configuration:** Primarily JSON-based (application settings, user overrides, type definitions, supplier settings, presets, LLM settings).
|
||||
* **Processing Architecture:** A modular, staged processing pipeline orchestrated by a central engine. Each stage performs a discrete task on an `AssetProcessingContext` object.
|
||||
* **Key Libraries:** OpenCV (image processing), NumPy (numerical operations), py7zr/rarfile (archive handling), watchdog (directory monitoring).
|
||||
* **Design Principles:** Modularity, configurability, and user-friendliness (especially for the GUI).
|
||||
|
||||
## 5. Foundational Information
|
||||
|
||||
* The tool aims to significantly reduce manual effort and ensure consistency in asset preparation.
|
||||
* It is designed to be adaptable to various asset sources and pipeline requirements through its extensive configuration options and preset system.
|
||||
* The output `metadata.json` is key for enabling further automation and integration with other tools or digital content creation (DCC) applications.
|
||||
Loading…
x
Reference in New Issue
Block a user