Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions amplifier_app_cli/collections/installer.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
11 changes: 11 additions & 0 deletions amplifier_app_cli/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
23 changes: 14 additions & 9 deletions amplifier_app_cli/module_resolution/sources.py
Original file line number Diff line number Diff line change
Expand Up @@ -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."""
Expand Down