From d6a48b7823098eb7ad88a87c3c61d1f5f6a76c11 Mon Sep 17 00:00:00 2001 From: Ishan Lakhwani Date: Sun, 22 Jun 2025 13:22:46 +0530 Subject: [PATCH 1/2] feat: default skills for single prompt agent generation --- app/admin/generator/README.md | 18 +++++++++- app/admin/generator/skill_processor.py | 48 ++++++++++++++++++++++++-- app/config/config.py | 4 +++ example.env | 5 +++ 4 files changed, 72 insertions(+), 3 deletions(-) diff --git a/app/admin/generator/README.md b/app/admin/generator/README.md index 0be33bb8..a22ca081 100644 --- a/app/admin/generator/README.md +++ b/app/admin/generator/README.md @@ -2,12 +2,28 @@ AI-powered system for generating IntentKit agent schemas from natural language prompts with project-based conversation history and automatic tag generation. +## Configuration + +### Default Skills + +The Agent Generator can automatically include default skills in all generated agents: + +```env +# Enable default skills (disabled by default) +GENERATOR_ADD_DEFAULT_SKILLS=true + +# Specify which skills to include as defaults (comma-separated) +GENERATOR_DEFAULT_SKILLS=common,tavily,cdp +``` + +When enabled, these skills will be automatically added to every generated agent schema with appropriate default configurations from their schemas. Identified skills from prompts will take precedence over defaults. + ## Architecture ``` generator/ ├── agent_generator.py # Main orchestrator -├── skill_processor.py # Skill identification +├── skill_processor.py # Skill identification + default skills ├── validation.py # Schema validation ├── ai_assistant.py # AI operations + conversation history ├── llm_logger.py # Individual LLM call tracking diff --git a/app/admin/generator/skill_processor.py b/app/admin/generator/skill_processor.py index a929baaa..69a37dec 100644 --- a/app/admin/generator/skill_processor.py +++ b/app/admin/generator/skill_processor.py @@ -14,6 +14,7 @@ from openai import OpenAI +from app.config.config import config from skills import __all__ as available_skill_categories if TYPE_CHECKING: @@ -30,6 +31,38 @@ _skill_schemas_cache: Dict[str, Dict[str, Any]] = {} +def get_default_skills_config() -> Dict[str, Any]: + """Get default skills configuration based on config settings. + + Returns: + Dict containing default skills configurations + """ + if not config.generator_add_default_skills: + return {} + + default_skills = {} + all_real_skills = get_all_real_skills() + + for skill_name in config.generator_default_skills: + skill_name = skill_name.strip() + if skill_name in all_real_skills: + # Get states with schema-based defaults + states_dict = {} + for state in all_real_skills[skill_name]: + states_dict[state] = get_skill_state_default(skill_name, state) + + default_skills[skill_name] = { + "enabled": True, + "states": states_dict, + "api_key_provider": get_skill_default_api_key_provider(skill_name), + } + logger.debug(f"Added default skill: {skill_name}") + else: + logger.warning(f"Default skill '{skill_name}' not found in available skills") + + return default_skills + + def load_skill_schema(skill_name: str) -> Optional[Dict[str, Any]]: """Load schema.json for a specific skill.""" if skill_name in _skill_schemas_cache: @@ -434,11 +467,22 @@ async def identify_skills( Returns: Dict containing skill configurations with only real skill states """ - # Use keyword matching first - skills_config = keyword_match_skills(prompt) + # Start with default skills if enabled + skills_config = get_default_skills_config() + + # Use keyword matching + keyword_skills = keyword_match_skills(prompt) + + # Merge keyword skills with defaults (keyword skills take precedence) + for skill_name, skill_config in keyword_skills.items(): + skills_config[skill_name] = skill_config # Add skills mentioned by exact name skills_config = add_skill_by_name(prompt, skills_config) + + if config.generator_add_default_skills and skills_config: + logger.info(f"Added default skills: {list(get_default_skills_config().keys())}") + return skills_config diff --git a/app/config/config.py b/app/config/config.py index 657e6cd8..8c5ab812 100644 --- a/app/config/config.py +++ b/app/config/config.py @@ -147,6 +147,10 @@ def __init__(self): self.nation_api_key = self.load("NATION_API_KEY") self.nation_api_url = self.load("NATION_API_URL", "") + # Agent Generator - Default Skills + self.generator_add_default_skills = self.load("GENERATOR_ADD_DEFAULT_SKILLS", "false") == "true" + self.generator_default_skills = self.load("GENERATOR_DEFAULT_SKILLS", "common,tavily").split(",") + # ===== config loaded # Now we know the env, set up logging setup_logging(self.env, self.debug) diff --git a/example.env b/example.env index f42657bf..7e5a3b02 100644 --- a/example.env +++ b/example.env @@ -30,6 +30,11 @@ TWITTER_OAUTH2_CLIENT_SECRET= TWITTER_OAUTH2_REDIRECT_URI=http://localhost:8000/callback/auth/twitter TWITTER_ENTRYPOINT_INTERVAL=1 +# Set to true to automatically add default skills to generated agents +GENERATOR_ADD_DEFAULT_SKILLS=false +# Comma-separated list of skill categories to add as defaults +GENERATOR_DEFAULT_SKILLS=common,tavily + DAPPLOOKER_API_KEY= UNREALSPEECH_API_KEY= From 5bf186b8fe1800f7edcc249b148def5bd69e3e79 Mon Sep 17 00:00:00 2001 From: Ishan Lakhwani Date: Sun, 22 Jun 2025 13:27:44 +0530 Subject: [PATCH 2/2] feat: default skills lint fixes --- app/admin/generator/skill_processor.py | 18 ++++++++++-------- app/config/config.py | 8 ++++++-- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/app/admin/generator/skill_processor.py b/app/admin/generator/skill_processor.py index 69a37dec..f1aa9fc5 100644 --- a/app/admin/generator/skill_processor.py +++ b/app/admin/generator/skill_processor.py @@ -33,16 +33,16 @@ def get_default_skills_config() -> Dict[str, Any]: """Get default skills configuration based on config settings. - + Returns: Dict containing default skills configurations """ if not config.generator_add_default_skills: return {} - + default_skills = {} all_real_skills = get_all_real_skills() - + for skill_name in config.generator_default_skills: skill_name = skill_name.strip() if skill_name in all_real_skills: @@ -58,8 +58,10 @@ def get_default_skills_config() -> Dict[str, Any]: } logger.debug(f"Added default skill: {skill_name}") else: - logger.warning(f"Default skill '{skill_name}' not found in available skills") - + logger.warning( + f"Default skill '{skill_name}' not found in available skills" + ) + return default_skills @@ -472,17 +474,17 @@ async def identify_skills( # Use keyword matching keyword_skills = keyword_match_skills(prompt) - + # Merge keyword skills with defaults (keyword skills take precedence) for skill_name, skill_config in keyword_skills.items(): skills_config[skill_name] = skill_config # Add skills mentioned by exact name skills_config = add_skill_by_name(prompt, skills_config) - + if config.generator_add_default_skills and skills_config: logger.info(f"Added default skills: {list(get_default_skills_config().keys())}") - + return skills_config diff --git a/app/config/config.py b/app/config/config.py index 8c5ab812..21254ead 100644 --- a/app/config/config.py +++ b/app/config/config.py @@ -148,8 +148,12 @@ def __init__(self): self.nation_api_url = self.load("NATION_API_URL", "") # Agent Generator - Default Skills - self.generator_add_default_skills = self.load("GENERATOR_ADD_DEFAULT_SKILLS", "false") == "true" - self.generator_default_skills = self.load("GENERATOR_DEFAULT_SKILLS", "common,tavily").split(",") + self.generator_add_default_skills = ( + self.load("GENERATOR_ADD_DEFAULT_SKILLS", "false") == "true" + ) + self.generator_default_skills = self.load( + "GENERATOR_DEFAULT_SKILLS", "common,tavily" + ).split(",") # ===== config loaded # Now we know the env, set up logging