picogent-py/picogent/context.py

72 lines
2.7 KiB
Python

"""
Context builder for system prompt, memory, and skills
"""
import os
from typing import List, Optional
class ContextBuilder:
"""Build context from system prompt, memory, and skills"""
def __init__(self, workspace_path: str = "."):
self.workspace_path = workspace_path
def build_system_prompt(self, base_prompt: str) -> str:
"""Build system prompt with skills and context"""
system_parts = [base_prompt]
# Add skills from skills directory
skills_dir = os.path.join(self.workspace_path, "skills")
if os.path.exists(skills_dir):
skills = self._load_skills(skills_dir)
if skills:
system_parts.append("\n## Available Skills\n")
system_parts.extend(skills)
return "\n".join(system_parts)
def _load_skills(self, skills_dir: str) -> List[str]:
"""Load skills from skills directory"""
skills = []
if not os.path.exists(skills_dir):
return skills
for filename in sorted(os.listdir(skills_dir)):
if filename.endswith(('.md', '.txt')):
skill_path = os.path.join(skills_dir, filename)
try:
with open(skill_path, 'r', encoding='utf-8') as f:
skill_content = f.read().strip()
if skill_content:
skills.append(f"### {filename}\n{skill_content}")
except Exception as e:
print(f"Warning: Could not load skill {filename}: {e}")
return skills
def get_working_directory_info(self) -> str:
"""Get information about current working directory"""
try:
files = []
dirs = []
for item in os.listdir(self.workspace_path):
item_path = os.path.join(self.workspace_path, item)
if os.path.isdir(item_path):
dirs.append(item + "/")
else:
files.append(item)
info_parts = [f"Working directory: {os.path.abspath(self.workspace_path)}"]
if dirs or files:
all_items = sorted(dirs) + sorted(files)
info_parts.append("Contents: " + ", ".join(all_items[:20])) # Limit to first 20 items
if len(all_items) > 20:
info_parts.append(f"... and {len(all_items) - 20} more items")
return "\n".join(info_parts)
except Exception as e:
return f"Working directory: {os.path.abspath(self.workspace_path)} (could not list contents: {e})"