From fc593d688a99d2d397752f85aea9f2de714afeac Mon Sep 17 00:00:00 2001 From: cocktailpeanut Date: Fri, 24 Jan 2025 04:11:14 -0500 Subject: [PATCH] finegrained activities config customization --- .../activities/activity_post_a_tweet.py | 31 +++++++++++++++--- .../activity_post_recent_memory_tweet.py | 32 ++++++++++++++++--- .../config_sample/activity_constraints.json | 6 +++- .../config_sample/skills_config.json | 11 ++++++- my_digital_being/static/onboarding.js | 5 ++- 5 files changed, 73 insertions(+), 12 deletions(-) diff --git a/my_digital_being/activities/activity_post_a_tweet.py b/my_digital_being/activities/activity_post_a_tweet.py index b7368a6..f51fca8 100644 --- a/my_digital_being/activities/activity_post_a_tweet.py +++ b/my_digital_being/activities/activity_post_a_tweet.py @@ -42,10 +42,11 @@ async def execute(self, shared_data) -> ActivityResult: success=False, error="Failed to initialize chat skill" ) - # 2) Gather personality + recent tweets + # 2) Load system_prompt + twitter memory from acitivyt config, and personality + recent tweets + self._sync_activity_config() character_config = self._get_character_config(shared_data) personality_data = character_config.get("personality", {}) - recent_tweets = self._get_recent_tweets(shared_data, limit=10) + recent_tweets = self._get_recent_tweets(shared_data, limit=self.num_activities_to_fetch) # 3) Generate tweet text with chat skill prompt_text = self._build_chat_prompt(personality_data, recent_tweets) @@ -96,6 +97,29 @@ async def execute(self, shared_data) -> ActivityResult: logger.error(f"Failed to post tweet: {e}", exc_info=True) return ActivityResult(success=False, error=str(e)) + def _sync_activity_config(self): + """ + synchronize activity config + """ + # Load the config from the being + from framework.main import DigitalBeing + being = DigitalBeing() + being.initialize() + system_prompt = ( + f"Write a new short tweet (under {self.max_length} chars), consistent with the above, " + f"but not repeating old tweets. Avoid hashtags or repeated phrases." + ) + num_activities_to_fetch = 10 + if "activity_constraints" in being.configs and \ + "activities_config" in being.configs["activity_constraints"] and \ + "PostTweetActivity" in being.configs["activity_constraints"]["activities_config"]: + activities_config = being.configs["activity_constraints"]["activities_config"]["PostTweetActivity"] + system_prompt = constraints_cfg["PostTweetActivity"].get("system_prompt", system_prompt) + num_activities_to_fetch = activities_config.get("num_activities_to_fetch", num_activities_to_fetch) + self.system_prompt = system_prompt + self.num_activities_to_fetch = num_activities_to_fetch + + def _get_character_config(self, shared_data) -> Dict[str, Any]: """ Retrieve character_config from SharedData['system'] or re-init the Being if not found. @@ -155,8 +179,7 @@ def _build_chat_prompt( f"{personality_str}\n\n" f"Here are recent tweets:\n" f"{last_tweets_str}\n\n" - f"Write a new short tweet (under 280 chars), consistent with the above, " - f"but not repeating old tweets. Avoid hashtags or repeated phrases.\n" + f"{self.system_prompt}\n" ) def _post_tweet_via_composio(self, tweet_text: str) -> Dict[str, Any]: diff --git a/my_digital_being/activities/activity_post_recent_memory_tweet.py b/my_digital_being/activities/activity_post_recent_memory_tweet.py index 7d32632..cb80ad8 100644 --- a/my_digital_being/activities/activity_post_recent_memory_tweet.py +++ b/my_digital_being/activities/activity_post_recent_memory_tweet.py @@ -48,7 +48,8 @@ async def execute(self, shared_data) -> ActivityResult: success=False, error="Failed to initialize chat skill" ) - # 2) Load personality + objectives from character config + # 2) Load system_prompt + twitter memory from acitivyt config, and personality + objectives from character config + self._sync_activity_config() character_config = self._get_character_config(shared_data) personality_data = character_config.get("personality", {}) objectives_data = character_config.get("objectives", {}) @@ -158,7 +159,7 @@ def _get_memories_used_last_time(self, shared_data) -> List[str]: memory_obj = being.memory # Search in the last ~10 runs for this activity - recent_activities = memory_obj.get_recent_activities(limit=10, offset=0) + recent_activities = memory_obj.get_recent_activities(limit=self.num_activities_to_fetch, offset=0) for act in recent_activities: if act.get( "activity_type" @@ -168,6 +169,29 @@ def _get_memories_used_last_time(self, shared_data) -> List[str]: return used return [] + def _sync_activity_config(self): + """ + synchronize activity config + """ + # Load the config from the being + from framework.main import DigitalBeing + being = DigitalBeing() + being.initialize() + system_prompt = ( + f"Please craft a short tweet (under {self.max_length} chars) that references these memories, " + f"reflects the personality and objectives, and ensures it's not repetitive or dull. " + f"Keep it interesting, cohesive, and mindful of the overall tone.\n" + ) + num_activities_to_fetch = 10 + if "activity_constraints" in being.configs and \ + "activities_config" in being.configs["activity_constraints"] and \ + "PostRecentMemoriesTweetActivity" in being.configs["activity_constraints"]["activities_config"]: + activities_config = being.configs["activity_constraints"]["activities_config"]["PostRecentMemoriesTweetActivity"] + system_prompt = activities_config.get("system_prompt", system_prompt) + num_activities_to_fetch = activities_config.get("num_activities_to_fetch", num_activities_to_fetch) + self.system_prompt = system_prompt + self.num_activities_to_fetch = num_activities_to_fetch + def _get_character_config(self, shared_data) -> Dict[str, Any]: """ Retrieve character_config from SharedData['system'] or re-init the Being if not found. @@ -253,9 +277,7 @@ def _build_chat_prompt( f"{objectives_str}\n\n" f"Here are some new memories:\n" f"{memories_str}\n\n" - f"Please craft a short tweet (under 280 chars) that references these memories, " - f"reflects the personality and objectives, and ensures it's not repetitive or dull. " - f"Keep it interesting, cohesive, and mindful of the overall tone.\n" + f"{self.system_prompt}\n" ) return prompt diff --git a/my_digital_being/config_sample/activity_constraints.json b/my_digital_being/config_sample/activity_constraints.json index 398b7d3..3a20378 100644 --- a/my_digital_being/config_sample/activity_constraints.json +++ b/my_digital_being/config_sample/activity_constraints.json @@ -66,13 +66,17 @@ "enabled": false }, "PostTweetActivity": { + "system_prompt": "Write a new short tweet (under 280 chars), consistent with the above, but not repeating old tweets. Avoid hashtags or repeated phrases.", + "num_activities_to_fetch": 10, "enabled": false }, "PostRecentMemoriesTweetActivity": { + "system_prompt": "Please craft a short tweet (under 280 chars) that references these memories, reflects the personality and objectives, and ensures it's not repetitive or dull. Keep it interesting, cohesive, and mindful of the overall tone.", + "num_activities_to_fetch": 10, "enabled": false }, "AnalyzeNewCommitsActivity": { "enabled": false } } -} \ No newline at end of file +} diff --git a/my_digital_being/config_sample/skills_config.json b/my_digital_being/config_sample/skills_config.json index 7434047..d882b32 100644 --- a/my_digital_being/config_sample/skills_config.json +++ b/my_digital_being/config_sample/skills_config.json @@ -28,5 +28,14 @@ "model_name": "openai/gpt-4o-mini", "required_api_keys": [], "api_key_mapping": {} + }, + "twitter_posting": { + "enabled": true, + "required_api_keys": [ + "TWITTER" + ], + "api_key_mapping": { + "TWITTER": "TWITTER_API_KEY" + } } -} \ No newline at end of file +} diff --git a/my_digital_being/static/onboarding.js b/my_digital_being/static/onboarding.js index 90c007e..32299a8 100644 --- a/my_digital_being/static/onboarding.js +++ b/my_digital_being/static/onboarding.js @@ -10,6 +10,7 @@ // We'll store the loaded activity list globally so we can build checkboxes. let discoveredActivities = {}; + let loadedConfigs; document.addEventListener('DOMContentLoaded', () => { // Insert a button in the overview tab for the wizard @@ -141,6 +142,7 @@ const charCfg = cfg.character_config || {}; const skillCfg = cfg.skills_config || {}; const constraintsCfg = cfg.activity_constraints || {}; + loadedConfigs = cfg // Fill in the fields populateCharacterFields(charCfg); @@ -308,7 +310,8 @@ const checkboxId = `activity_checkbox_${moduleName}`; const boxEl = document.getElementById(checkboxId); const isChecked = boxEl ? boxEl.checked : true; - activities_config[className] = { "enabled": isChecked }; + activities_config[className] = loadedConfigs.activity_constraints.activities_config[className] + activities_config[className].enabled = isChecked }); }