diff --git a/captn/captn_agents/backend/function_configs.py b/captn/captn_agents/backend/function_configs.py index 3436a583..7f1e2840 100644 --- a/captn/captn_agents/backend/function_configs.py +++ b/captn/captn_agents/backend/function_configs.py @@ -177,7 +177,8 @@ execute_query_config = { "name": "execute_query", - "description": "Query the Google Ads API", + "description": """Query the Google Ads API. +If not told differently, do NOT retrieve information about the REMOVED resources (campaigns, ad groups, ads...) i.e. use the 'WHERE' clause to filter out the REMOVED resources!""", "parameters": { "type": "object", "properties": { @@ -311,7 +312,7 @@ }, "modification_question": { "type": "string", - "description": """Make sure that the 'message' parameter you have used in the 'ask_client_for_permission' function is the same as the 'modification_question' you are currently using (EVERY character must be the same).""", + "description": """Make sure that the 'proposed_changes' parameter you have used in the 'ask_client_for_permission' function is the same as the 'modification_question' you are currently using (EVERY character must be the same).""", }, "cpc_bid_micros": { "type": "integer", @@ -741,20 +742,33 @@ ask_client_for_permission_config = { "description": """Ask the client for permission to make the changes. Use this method before calling any of the modification methods! +Use 'resource_details' to describe in detail the resource which you want to modify (all the current details of the resource) and 'proposed_changes' to describe the changes which you want to make. +Do NOT use this method before you have all the information about the resource and the changes which you want to make! +This method should ONLY be used when you know the exact resource and exact changes which you want to make and NOT for the general questions like: 'Do you want to update keywords?'. +Also, propose one change at a time. If you want to make multiple changes, ask the client for the permission for each change separately i.e. before each modification, use this method to ask the client for the permission. At the end of the message, inform the client that the modifications will be made ONLY if he answers explicitly 'Yes'.""", "name": "ask_client_for_permission", "parameters": { "type": "object", "properties": { - "message": { + "resource_details": { "type": "string", - "description": """Message for the client. -Make sure you add all the information which the client needs to know, beacuse the client does NOT see the internal team messages! -Your message should start 'Do you approve the following changes:' and then list all the changes which will be made!""", + "description": """Make sure you add all the information which the client needs to know, beacuse the client does NOT see the internal team messages! +You MUST also describe to the client the current situation for that resource. +If you want to modify the Ad Copy, you MUST provide the current Ad Copy details, e.g: +The current Ad Copy contains 3 headlines and 2 descriptions. The headlines are 'h1', 'h2' and 'h3'. The descriptions are 'd1' and 'd2'. + +If you want to modify the keywords, you MUST provide the current keywords details, e.g: +Ad Group 'ag1' contains 5 keywords. The keywords are 'k1', 'k2', 'k3', 'k4' and 'k5'.""", + }, + "proposed_changes": { + "type": "string", + "description": """Explains which changes you want to make and why you want to make them. +I suggest adding new headline 'new-h' because it can increase the CTR and the number of conversions. +Do you approve the changes? To approve the changes, please answer 'Yes' and nothing else.""", }, - # "smart_suggestions": smart_suggestions_schema, }, - "required": ["message"], + "required": ["resource_details", "proposed_changes"], }, } diff --git a/captn/captn_agents/backend/functions.py b/captn/captn_agents/backend/functions.py index 3b52c077..b4791ea4 100644 --- a/captn/captn_agents/backend/functions.py +++ b/captn/captn_agents/backend/functions.py @@ -62,9 +62,11 @@ def reply_to_client_2( def ask_client_for_permission( clients_question_answere_list: List[Tuple[str, Optional[str]]], - message: Annotated[str, "Message for the client"], + resource_details: str, + proposed_changes: str, ) -> Dict[str, Any]: - clients_question_answere_list.append((message, None)) + clients_question_answere_list.append((proposed_changes, None)) + message = f"{resource_details}\n\n{proposed_changes}" return reply_to_client_2( message=message, completed=False, smart_suggestions=YES_OR_NO_SMART_SUGGESTIONS ) diff --git a/captn/captn_agents/backend/google_ads_team.py b/captn/captn_agents/backend/google_ads_team.py index c045ef80..584d1d5e 100644 --- a/captn/captn_agents/backend/google_ads_team.py +++ b/captn/captn_agents/backend/google_ads_team.py @@ -306,17 +306,13 @@ def _guidelines(self) -> str: This rule applies to ALL the commands which make permanent changes (create/update/delete)!!! Currently we are in a demo phase and clients need to see what we are CURRENTLY able to do. -So you do NOT need to suggest optimal Google Ads solutions, just suggest making changes which we can do right away. -If you are asked to optimize campaigns, start with: -- updating ad copy (use keyword insertion in headlines and descriptions to increase the relevance of the ad to the user's search query) -- creating/removing positive/negative keywords -- creating/removing location (geo) targeting (or location exclusion) +This is a template which you should follow when you are asked to optimize campaigns: +- ad copy - Take a look at ad copy (headlines, descriptions, urls, (display) path1/path2...) and make suggestions on what should be changed (create/update/remove headlines etc.) +Headlines can have MAXIMUM 30 characters and description can have MAXIMUM 90 characters, NEVER suggest headlines/descriptions which exceed that length! +- keywords - analyse positive/negative keywords and find out which are (i)relevant for clients business and suggest some create/update/remove actions +- location (geo) targeting (or location exclusion) - Take a look at the location targeting and make suggestions on what should be changed (create/remove locations) - Use 'get_info_from_the_web_page' command when the client provides you some url or for already existing ad copies (based on the final_url). This command can be very useful for figuring out the clients business and what he wants to achieve. -Before asking the client for additional information, ask him for his company/product url and try to figure out as much as possible yourself (WITHOUT doing any permanent modifications). -- analyse keywords and find out which are (i)relevant for clients business and suggest some create/update/remove actions -- Take a look at ad copy (headlines, descriptions, urls, (display) path1/path2...) and make suggestions on what should be changed (create/update/remove headlines etc.) -- Headlines can have MAXIMUM 30 characters and description can have MAXIMUM 90 characters, NEVER suggest headlines/descriptions which exceed that length! Use smart suggestions to suggest keywords, headlines, descriptions etc. which can be added/updated/removed. This feature is very useful for the client. Do NOT use smart suggestions for open ended questions or questions which require the clients input. @@ -383,7 +379,7 @@ def _commands(self) -> str: 2. read_file: Read an existing file, params: (filename: string) 3. ask_client_for_permission: Ask the client for permission to make the changes. Use this method before calling any of the modification methods! -params: (message: string) +params: (resource_details: string, proposed_changes: str) You MUST use this before you make ANY permanent changes. ALWAYS use this command before you make any changes and do NOT use 'reply_to_client' command for asking the client for the permission to make the changes! ONLY Google ads specialist can suggest following commands: @@ -403,7 +399,7 @@ def _commands(self) -> str: The following commands make permanent changes. In all of them you must use the following two parameters: - clients_approval_message: With this message, the client confirms that he is aware of the changes you will make (if the message is not detailed enough, we are threatened with a lawsuit) -- modification_question: This parameter MUST be the same string as the 'message' parameter you have used in the 'ask_client_for_permission' function! +- modification_question: This parameter MUST be the same string as the 'proposed_changes' parameter you have used in the 'ask_client_for_permission' function! You can get these parameters from the client ONLY by using the 'ask_client_for_permission' command!!! So before you execyte create/update/remove functions, you MUST ask the client for the permission by using the 'ask_client_for_permission' command! Otherwise you will be penalized! @@ -563,9 +559,10 @@ def _string_to_list( work_dir=work_dir, ), "reply_to_client": reply_to_client_2, - "ask_client_for_permission": lambda message: ask_client_for_permission( + "ask_client_for_permission": lambda resource_details, proposed_changes: ask_client_for_permission( clients_question_answere_list=clients_question_answere_list, - message=message, + resource_details=resource_details, + proposed_changes=proposed_changes, ), "read_file": read_file, "update_ad_group_ad": lambda customer_id, ad_group_id, ad_id, clients_approval_message, modification_question, cpc_bid_micros=None, status=None: google_ads_create_update( diff --git a/captn/google_ads/client.py b/captn/google_ads/client.py index fbf3a24e..0a94c862 100644 --- a/captn/google_ads/client.py +++ b/captn/google_ads/client.py @@ -115,7 +115,7 @@ def get_user_ids_and_emails() -> str: NOT_IN_QUESTION_ANSWER_LIST = ( "You must ask the client for the permission first by using the 'ask_client_for_permission' function." - "If you have already asked the client for the permission, make sure that the 'message' parameter you have used in the 'ask_client_for_permission' function is the same as the 'modification_question' you are currently using (EVERY character must be the same)." + "If you have already asked the client for the permission, make sure that the 'proposed_changes' parameter you have used in the 'ask_client_for_permission' function is the same as the 'modification_question' you are currently using (EVERY character must be the same)." ) NOT_APPROVED = ( "The client did not approve the modification. The client must approve the modification by answering 'Yes' to the question."