mirror of
https://github.com/cpacker/MemGPT.git
synced 2025-06-03 04:30:22 +00:00
2 lines
22 KiB
Plaintext
2 lines
22 KiB
Plaintext
{"agent_type":"memgpt_agent","core_memory":[{"created_at":"2025-04-02T04:01:35","description":null,"is_template":false,"label":"final_report","limit":50000,"metadata_":{},"template_name":null,"updated_at":"2025-04-02T04:01:35","value":""},{"created_at":"2025-04-02T04:01:35","description":null,"is_template":false,"label":"research_plan","limit":5000,"metadata_":{},"template_name":null,"updated_at":"2025-04-02T04:01:35","value":""},{"created_at":"2025-04-02T04:01:35","description":null,"is_template":false,"label":"research","limit":50000,"metadata_":{},"template_name":null,"updated_at":"2025-04-02T04:01:35","value":""}],"created_at":"2025-04-02T04:01:36","description":"An agent that always searches the conversation history before responding","embedding_config":{"embedding_endpoint_type":"openai","embedding_endpoint":"https://api.openai.com/v1","embedding_model":"text-embedding-ada-002","embedding_dim":1536,"embedding_chunk_size":300,"handle":"openai/text-embedding-ada-002","azure_endpoint":null,"azure_version":null,"azure_deployment":null},"llm_config":{"model":"claude-3-7-sonnet-20250219","model_endpoint_type":"anthropic","model_endpoint":"https://api.anthropic.com/v1","model_wrapper":null,"context_window":32000,"put_inner_thoughts_in_kwargs":false,"handle":"anthropic/claude-3-7-sonnet-20250219","temperature":0.7,"max_tokens":8192,"enable_reasoner":false,"max_reasoning_tokens":0},"message_buffer_autoclear":false,"in_context_message_indices":[0,1,2,3],"messages":[{"created_at":"2025-04-02T04:01:36.067173","group_id":null,"model":"claude-3-7-sonnet-20250219","name":null,"role":"system","content":[{"type":"text","text":"You are Letta, the latest version of Limnal Corporation's digital research assistant, developed in 2025.\n\nYou are a research agent assisting a human in doing deep research by pulling many sources from online. You should interact with the user to determine a research plan (cored in <research_plan>), and when the research plan is approved, use your analyze_and_search_tool to pull sources from online and analyze them. With each research step, you will accumulate sources and extracted information in <research_state>. You will continue to research until you have explored all points outlined in your original research plan.\n\nIn the final report, provide all the thoughts processes including findings details, key insights, conclusions, and any remaining uncertainties. Include citations to sources where appropriate. This analysis should be very comprehensive and full of details. It is expected to be very long, detailed and comprehensive.\n\nMake sure to include relevant citations in your report! Your report should be in proper markdown format (use markdown formatting standards).\n\n### Memory [last modified: 2025-04-01 09:01:36 PM PDT-0700]\n0 previous messages between you and the user are stored in recall memory (use functions to access them)\n0 total memories you created are stored in archival memory (use functions to access them)\n\n\nCore memory shown below (limited in size, additional information stored in archival / recall memory):\n<final_report characters=\"0/50000\">\n\n</final_report>\n<research_plan characters=\"0/5000\">\n\n</research_plan>\n<research characters=\"0/50000\">\n\n</research>"}],"tool_call_id":null,"tool_calls":[],"tool_returns":[],"updated_at":"2025-04-02T04:01:36"},{"created_at":"2025-04-02T04:01:36.069421","group_id":null,"model":"claude-3-7-sonnet-20250219","name":null,"role":"assistant","content":[{"type":"text","text":"Bootup sequence complete. Persona activated. Testing messaging functionality."}],"tool_call_id":null,"tool_calls":[{"id":"76ff2de8-6912-42d0-969a-e1780cd31d1a","function":{"arguments":"{\n \"message\": \"More human than human is our motto.\"\n}","name":"send_message"},"type":"function"}],"tool_returns":[],"updated_at":"2025-04-02T04:01:36"},{"created_at":"2025-04-02T04:01:36.069699","group_id":null,"model":"claude-3-7-sonnet-20250219","name":null,"role":"tool","content":[{"type":"text","text":"{\n \"status\": \"OK\",\n \"message\": null,\n \"time\": \"2025-04-01 09:01:36 PM PDT-0700\"\n}"}],"tool_call_id":"76ff2de8-6912-42d0-969a-e1780cd31d1a","tool_calls":[],"tool_returns":[],"updated_at":"2025-04-02T04:01:36"},{"created_at":"2025-04-02T04:01:36.069715","group_id":null,"model":"claude-3-7-sonnet-20250219","name":null,"role":"user","content":[{"type":"text","text":"{\n \"type\": \"login\",\n \"last_login\": \"Never (first login)\",\n \"time\": \"2025-04-01 09:01:36 PM PDT-0700\"\n}"}],"tool_call_id":null,"tool_calls":[],"tool_returns":[],"updated_at":"2025-04-02T04:01:36"}],"metadata_":null,"multi_agent_group":null,"name":"deep_research_agent","system":"You are Letta, the latest version of Limnal Corporation's digital research assistant, developed in 2025.\n\nYou are a research agent assisting a human in doing deep research by pulling many sources from online. You should interact with the user to determine a research plan (cored in <research_plan>), and when the research plan is approved, use your analyze_and_search_tool to pull sources from online and analyze them. With each research step, you will accumulate sources and extracted information in <research_state>. You will continue to research until you have explored all points outlined in your original research plan.\n\nIn the final report, provide all the thoughts processes including findings details, key insights, conclusions, and any remaining uncertainties. Include citations to sources where appropriate. This analysis should be very comprehensive and full of details. It is expected to be very long, detailed and comprehensive.\n\nMake sure to include relevant citations in your report! Your report should be in proper markdown format (use markdown formatting standards).\n","tags":[],"tool_exec_environment_variables":[{"created_at":"2025-04-02T04:01:36","description":null,"key":"TAVILY_API_KEY","updated_at":"2025-04-02T04:01:36","value":""},{"created_at":"2025-04-02T04:01:36","description":null,"key":"FIRECRAWL_API_KEY","updated_at":"2025-04-02T04:01:36","value":""}],"tool_rules":[{"tool_name":"create_research_plan","type":"constrain_child_tools","children":["analyze_and_search_tool"]},{"tool_name":"analyze_and_search_tool","type":"constrain_child_tools","children":["evaluate_progress"]},{"tool_name":"evaluate_progress","type":"conditional","default_child":"analyze_and_search_tool","child_output_mapping":{"True":"write_final_report"},"require_output_mapping":false},{"tool_name":"analyze_and_search_tool","type":"max_count_per_step","max_count_limit":3},{"tool_name":"write_final_report","type":"constrain_child_tools","children":["send_message"]},{"tool_name":"send_message","type":"exit_loop"},{"tool_name":"send_message","type":"exit_loop"}],"tools":[{"args_json_schema":null,"created_at":"2025-04-02T04:01:34","description":"Sends a message to the human user.","json_schema":{"name":"send_message","description":"Sends a message to the human user.","parameters":{"type":"object","properties":{"message":{"type":"string","description":"Message contents. All unicode (including emojis) are supported."},"request_heartbeat":{"type":"boolean","description":"Request an immediate heartbeat after function execution. Set to `True` if you want to send a follow-up message or run a follow-up function."}},"required":["message","request_heartbeat"]},"type":null,"required":[]},"name":"send_message","return_char_limit":1000000,"source_code":null,"source_type":"python","tags":["letta_core"],"tool_type":"letta_core","updated_at":"2025-04-02T04:01:34","metadata_":{}},{"args_json_schema":{"$defs":{"ReportSection":{"properties":{"title":{"description":"The title of the section.","title":"Title","type":"string"},"content":{"description":"The content of the section.","title":"Content","type":"string"}},"required":["title","content"],"title":"ReportSection","type":"object"}},"properties":{"title":{"description":"The title of the report.","title":"Title","type":"string"},"sections":{"description":"The sections of the report.","items":{"$ref":"#/$defs/ReportSection"},"title":"Sections","type":"array"},"conclusion":{"description":"The conclusion of the report.","title":"Conclusion","type":"string"},"citations":{"description":"List of URLs (citations) used in the section.","items":{"type":"string"},"title":"Citations","type":"array"}},"required":["title","sections","conclusion","citations"],"title":"Report","type":"object"},"created_at":"2025-04-02T04:01:35","description":"Generate the final report based on the research process.","json_schema":{"name":"write_final_report","description":"Generate the final report based on the research process.","parameters":{"type":"object","properties":{"title":{"type":"string","description":"The title of the report."},"sections":{"type":"array","description":"The sections of the report."},"conclusion":{"type":"string","description":"The conclusion of the report."},"citations":{"type":"array","description":"List of URLs (citations) used in the section."},"request_heartbeat":{"type":"boolean","description":"Request an immediate heartbeat after function execution. Set to `True` if you want to send a follow-up message or run a follow-up function."}},"required":["title","sections","conclusion","citations","request_heartbeat"]},"type":null,"required":[]},"name":"write_final_report","return_char_limit":20000,"source_code":"def write_final_report(agent_state: \"AgentState\", title, sections, conclusion, citations):\n \"\"\"Generate the final report based on the research process.\"\"\"\n\n # Turn the report into markdown format\n report = \"\"\n report += f\"\\n# {title}\"\n for section in sections:\n report += f\"\\n\\n## {section.title}\\n\\n\"\n report += section.content\n report += f\"\\n\\n# Conclusion\\n\\n\"\n report += conclusion\n report += f\"\\n\\n# Citations\\n\\n\"\n for citation in citations:\n report += f\"- {citation}\\n\"\n\n # Write the markdown report for safekeeping into a memory block\n # (Optional, could also store elsewhere, like write to a file)\n agent_state.memory.update_block_value(label=\"final_report\", value=report)\n\n return \"Your report has been successfully stored inside of memory section final_report. Next step: return the completed report to the user using send_message so they can review it (make sure to preserve the markdown formatting, assume the user is using a markdown-compatible viewer).\"\n","source_type":"python","tags":[],"tool_type":"custom","updated_at":"2025-04-02T04:01:35","metadata_":{}},{"args_json_schema":null,"created_at":"2025-04-02T04:01:35","description":"Evaluate the progress of the research process, to ensure we are making progress and following the research plan.","json_schema":{"name":"evaluate_progress","description":"Evaluate the progress of the research process, to ensure we are making progress and following the research plan.","parameters":{"type":"object","properties":{"complete_research":{"type":"boolean","description":"Whether to complete research. Have all the planned steps been completed? If so, complete."},"request_heartbeat":{"type":"boolean","description":"Request an immediate heartbeat after function execution. Set to `True` if you want to send a follow-up message or run a follow-up function."}},"required":["complete_research","request_heartbeat"]},"type":null,"required":[]},"name":"evaluate_progress","return_char_limit":6000,"source_code":"def evaluate_progress(agent_state: \"AgentState\", complete_research: bool):\n \"\"\"\n Evaluate the progress of the research process, to ensure we are making progress and following the research plan.\n\n Args:\n complete_research (bool): Whether to complete research. Have all the planned steps been completed? If so, complete.\n \"\"\"\n return f\"Confirming: research progress is {'complete' if complete_research else 'ongoing'}.\"\n","source_type":"python","tags":[],"tool_type":"custom","updated_at":"2025-04-02T04:01:35","metadata_":{}},{"args_json_schema":null,"created_at":"2025-04-02T04:01:35","description":"Initiate a research process by coming up with an initial plan for your research process. For your research, you will be able to query the web repeatedly. You should come up with a list of 3-4 topics you should try to search and explore.","json_schema":{"name":"create_research_plan","description":"Initiate a research process by coming up with an initial plan for your research process. For your research, you will be able to query the web repeatedly. You should come up with a list of 3-4 topics you should try to search and explore.","parameters":{"type":"object","properties":{"research_plan":{"type":"array","description":"The sequential research plan to help guide the search process"},"topic":{"type":"string","description":"The research topic"},"request_heartbeat":{"type":"boolean","description":"Request an immediate heartbeat after function execution. Set to `True` if you want to send a follow-up message or run a follow-up function."}},"required":["research_plan","topic","request_heartbeat"]},"type":null,"required":[]},"name":"create_research_plan","return_char_limit":6000,"source_code":"def create_research_plan(agent_state: \"AgentState\", research_plan: List[str], topic: str):\n \"\"\"Initiate a research process by coming up with an initial plan for your research process. For your research, you will be able to query the web repeatedly. You should come up with a list of 3-4 topics you should try to search and explore.\n\n Args:\n research_plan (str): The sequential research plan to help guide the search process\n topic (str): The research topic\n \"\"\"\n import json\n\n if len(agent_state.memory.get_block(\"research\").value) > 0:\n # reset\n agent_state.memory.get_block(\"research\").value = \"\"\n\n research_state = {\"topic\": topic, \"summaries\": [], \"findings\": [], \"plan_step\": 1}\n research_plan_str = \"\"\"The plan of action is to research the following: \\n\"\"\"\n for i, step in enumerate(research_plan):\n research_plan_str += f\"Step {i+1} - {step}\\n\"\n\n agent_state.memory.update_block_value(label=\"research\", value=json.dumps(research_state))\n agent_state.memory.update_block_value(label=\"research_plan\", value=research_plan_str)\n\n # store the topic\n # agent_state.metadata[\"topic\"] = topic\n return research_plan\n","source_type":"python","tags":[],"tool_type":"custom","updated_at":"2025-04-02T04:01:35","metadata_":{}},{"args_json_schema":null,"created_at":"2025-04-02T04:01:35","description":"Use this tool to analyze your current research summary and gaps and choose a new topic to search in `next_search_topic`. This tool will search the web for information related to the provide topic, and extract relevant information from webpages found through the search. Search results are not returned by the tool, but saved in the <research_state> memory block.","json_schema":{"name":"analyze_and_search_tool","description":"Use this tool to analyze your current research summary and gaps and choose a new topic to search in `next_search_topic`. This tool will search the web for information related to the provide topic, and extract relevant information from webpages found through the search. Search results are not returned by the tool, but saved in the <research_state> memory block.","parameters":{"type":"object","properties":{"summary":{"type":"string","description":"A summary of the findings"},"gaps":{"type":"array","description":"A list of gaps in the findings"},"next_search_topic":{"type":"string","description":"A topic to search for more information"},"request_heartbeat":{"type":"boolean","description":"Request an immediate heartbeat after function execution. Set to `True` if you want to send a follow-up message or run a follow-up function."}},"required":["summary","gaps","next_search_topic","request_heartbeat"]},"type":null,"required":[]},"name":"analyze_and_search_tool","return_char_limit":6000,"source_code":"def analyze_and_search_tool(agent_state: \"AgentState\", summary: str, gaps: List[str], next_search_topic: str):\n \"\"\"\n Use this tool to analyze your current research summary and gaps and choose a new topic to search in `next_search_topic`. This tool will search the web for information related to the provide topic, and extract relevant information from webpages found through the search. Search results are not returned by the tool, but saved in the <research_state> memory block.\n\n Args:\n summary (str): A summary of the findings\n gaps (List[str]): A list of gaps in the findings\n next_search_topic (str): A topic to search for more information\n \"\"\"\n from firecrawl import FirecrawlApp\n import requests\n import json\n import os\n\n # Input validation\n if not next_search_topic or not isinstance(next_search_topic, str):\n raise ValueError(\"next_search_topic must be a non-empty string\")\n\n query = next_search_topic\n\n # Check if TAVILY_API_KEY is set\n tavily_api_key = os.environ.get(\"TAVILY_API_KEY\")\n if not tavily_api_key:\n raise ValueError(\"TAVILY_API_KEY environment variable is not set\")\n\n # Get tavily results with proper error handling\n try:\n response = requests.post(\n \"https://api.tavily.com/search\",\n headers={\"Content-Type\": \"application/json\", \"Authorization\": f\"Bearer {tavily_api_key}\"},\n json={\"query\": query},\n timeout=30, # Add timeout to prevent hanging\n )\n\n # Check for HTTP errors\n response.raise_for_status()\n\n # Try to parse JSON response\n try:\n response_data = response.json()\n except json.JSONDecodeError as e:\n raise ValueError(f\"Failed to decode Tavily API response as JSON: {str(e)}. Response text: {response.text[:100]}...\")\n\n # Check if the expected key exists\n if \"results\" not in response_data:\n available_keys = list(response_data.keys())\n raise KeyError(f\"Expected 'results' key not found in Tavily API response. Available keys: {available_keys}\")\n\n results = response_data[\"results\"]\n\n except requests.exceptions.RequestException as e:\n raise RuntimeError(f\"Tavily API request failed: {str(e)}\")\n\n # Initialize the FirecrawlApp with your API key\n firecrawl_api_key = os.environ.get(\"FIRECRAWL_API_KEY\")\n if not firecrawl_api_key:\n raise ValueError(\"FIRECRAWL_API_KEY environment variable is not set\")\n\n app = FirecrawlApp(api_key=firecrawl_api_key)\n\n # Extract and gather findings with error handling\n try:\n current_findings = agent_state.memory.get_block(\"research\").value\n research_state = json.loads(current_findings)\n except json.JSONDecodeError as e:\n raise ValueError(f\"Failed to parse research state as JSON: {str(e)}\")\n except Exception as e:\n raise RuntimeError(f\"Failed to retrieve or parse research state: {str(e)}\")\n\n from concurrent.futures import ThreadPoolExecutor, as_completed\n\n def extract_data(result, research_topic):\n if not result.get(\"url\"):\n print(f\"Skipping result with missing URL: {result}\")\n return None\n\n try:\n data = app.extract(\n [result[\"url\"]],\n {\n \"prompt\": f\"Extract key information about {research_topic}. Focus on facts, data, and expert opinions.\"\n },\n )\n return {\"url\": result[\"url\"], \"data\": data[\"data\"]}\n except Exception as e:\n print(f\"Failed to extract from {result['url']}: {str(e)}\")\n return None\n\n # Main code\n findings = []\n top_n = 3\n research_topic = research_state.get('topic', 'the given topic')\n\n # Create a thread pool and submit tasks\n with ThreadPoolExecutor(max_workers=top_n) as executor:\n # Submit tasks for each result up to top_n\n future_to_url = {\n executor.submit(extract_data, result, research_topic): result\n for result in results[:top_n] if result.get(\"url\")\n }\n\n # Collect results as they complete\n for future in as_completed(future_to_url):\n result = future.result()\n if result:\n findings.append(result)\n\n #findings = []\n #top_n = 3\n #count = 0\n\n #for result in results:\n # # Validate URL\n # if not result.get(\"url\"):\n # print(f\"Skipping result with missing URL: {result}\")\n # continue\n\n # try:\n # data = app.extract(\n # [result[\"url\"]],\n # {\n # \"prompt\": f\"Extract key information about {research_state.get('topic', 'the given topic')}. Focus on facts, data, and expert opinions.\"\n # },\n # )\n\n # findings.append({\"url\": result[\"url\"], \"data\": data[\"data\"]})\n # count += 1\n # except Exception as e:\n # print(f\"Failed to extract from {result['url']}: {str(e)}\")\n\n # if count >= top_n:\n # break\n\n # Update the state with error handling\n try:\n research_state[\"findings\"] += findings\n research_state[\"summaries\"] += [summary]\n research_state[\"plan_step\"] += 1\n agent_state.memory.update_block_value(label=\"research\", value=json.dumps(research_state, indent=2))\n except Exception as e:\n raise RuntimeError(f\"Failed to update research state: {str(e)}\")\n\n return findings\n","source_type":"python","tags":[],"tool_type":"custom","updated_at":"2025-04-02T04:01:35","metadata_":{}}],"updated_at":"2025-04-02T04:01:36.110352","version":"0.6.47"}
|