From 8d030758bfb7d3bb457f274ac27c57d97741f494 Mon Sep 17 00:00:00 2001 From: Paul Payne Date: Thu, 30 Oct 2025 13:23:50 -0700 Subject: [PATCH 1/2] feat(collections): Enhance collection installation by linking resource directories for discovery --- amplifier_app_cli/collections/installer.py | 15 ++++++++++++ .../module_resolution/sources.py | 23 +++++++++++-------- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/amplifier_app_cli/collections/installer.py b/amplifier_app_cli/collections/installer.py index 1ab435e6..1f94cd16 100644 --- a/amplifier_app_cli/collections/installer.py +++ b/amplifier_app_cli/collections/installer.py @@ -232,6 +232,21 @@ def install_collection( logger.debug(f"Copied pyproject.toml from {item.name}/ to collection root") break + # Link resource directories from package to collection root for discovery + # (profiles, context, agents, scenario-tools, modules may be inside package after wheel extraction) + for resource_dir in ["profiles", "context", "agents", "scenario-tools", "modules"]: + root_resource = collection_path / resource_dir + if not root_resource.exists(): + # Search for resource dir in package directories + for item in collection_path.iterdir(): + if item.is_dir() and not item.name.endswith(".dist-info") and not item.name.startswith("."): + pkg_resource = item / resource_dir + if pkg_resource.exists() and pkg_resource.is_dir(): + # Create symlink to avoid duplicating files + root_resource.symlink_to(pkg_resource, target_is_directory=True) + logger.debug(f"Linked {resource_dir}/ from {item.name}/ to collection root") + break + # Step 4: Install scenario tools (if any) installed_tools = install_scenario_tools(collection_path) if installed_tools: diff --git a/amplifier_app_cli/module_resolution/sources.py b/amplifier_app_cli/module_resolution/sources.py index 93405096..9b2a2d40 100644 --- a/amplifier_app_cli/module_resolution/sources.py +++ b/amplifier_app_cli/module_resolution/sources.py @@ -118,29 +118,34 @@ def resolve(self) -> Path: Raises: ModuleNotFoundError: Git clone failed """ - # Generate cache key - cache_key = hashlib.sha256(f"{self.url}@{self.ref}".encode()).hexdigest()[:12] + # Generate cache key - include subdirectory to avoid collisions + # (same repo+ref with different subdirectories need separate caches) + cache_key_input = f"{self.url}@{self.ref}" + if self.subdirectory: + cache_key_input += f"#{self.subdirectory}" + cache_key = hashlib.sha256(cache_key_input.encode()).hexdigest()[:12] cache_path = self.cache_dir / cache_key / self.ref - # Add subdirectory if specified - final_path = cache_path / self.subdirectory if self.subdirectory else cache_path - # Check cache if cache_path.exists() and self._is_valid_cache(cache_path): logger.debug(f"Using cached git module: {cache_path}") - return final_path + return cache_path # Download + # Note: uv installs the package content FROM subdirectory TO cache_path directly + # It does NOT create the subdirectory structure in the target logger.info(f"Downloading git module: {self.url}@{self.ref}") try: self._download_via_uv(cache_path) except subprocess.CalledProcessError as e: raise ModuleNotFoundError(f"Failed to download {self.url}@{self.ref}: {e}") - if not final_path.exists(): - raise ModuleNotFoundError(f"Subdirectory not found after download: {self.subdirectory}") + # Verify installation worked + if not self._is_valid_cache(cache_path): + sub_info = f"#subdirectory={self.subdirectory}" if self.subdirectory else "" + raise ModuleNotFoundError(f"Failed to install module from {self.url}@{self.ref}{sub_info}") - return final_path + return cache_path def _is_valid_cache(self, cache_path: Path) -> bool: """Check if cache directory contains valid module.""" From 1784a1c73ec119fb50b1df863c50cd071b3c0183 Mon Sep 17 00:00:00 2001 From: Paul Payne Date: Thu, 30 Oct 2025 13:24:04 -0700 Subject: [PATCH 2/2] feat(profiles): Add profile markdown body to context for enhanced processing --- amplifier_app_cli/main.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/amplifier_app_cli/main.py b/amplifier_app_cli/main.py index 08e796c0..e153aee1 100644 --- a/amplifier_app_cli/main.py +++ b/amplifier_app_cli/main.py @@ -1301,6 +1301,17 @@ async def _process_profile_mentions(session: AmplifierSession, profile_name: str logger.debug(f"Profile markdown body length: {len(markdown_body)} chars") + # First, add the profile's own markdown body as context + logger.info("Adding profile markdown body as context") + context = session.coordinator.get("context") + if context and hasattr(context, "add_message"): + profile_context_msg = {"role": "system", "content": markdown_body} + await context.add_message(profile_context_msg) + logger.info(f"Added profile markdown body ({len(markdown_body)} chars) to context") + else: + logger.warning("Context not available, cannot add profile markdown body") + + # Then, check for @mentions and load referenced files if not has_mentions(markdown_body): logger.debug("No @mentions found in profile markdown") return