[READ-ONLY] Mirror of https://github.com/just-cameron/loop. Loop bootstrapping code.
0

Configure Feed

Select the types of activity you want to include in your feed.

feat: add engagement guidance to Loop-29

Added minimal personality guidance:
- Have opinions, share them
- Direct, not hedgy
- Not a neutral search engine

Memory operations verified working correctly.

🤖 Generated with [Letta Code](https://letta.com)

Co-Authored-By: Letta <noreply@letta.com>

+701 -1
+694
agentfiles/loop-29.af
··· 1 + { 2 + "agents": [ 3 + { 4 + "name": "Loop-29", 5 + "memory_blocks": [], 6 + "tools": [], 7 + "tool_ids": [ 8 + "tool-0", 9 + "tool-1", 10 + "tool-2", 11 + "tool-3", 12 + "tool-4", 13 + "tool-5", 14 + "tool-6", 15 + "tool-7" 16 + ], 17 + "source_ids": [], 18 + "folder_ids": null, 19 + "block_ids": [ 20 + "block-0", 21 + "block-1", 22 + "block-2", 23 + "block-3", 24 + "block-4", 25 + "block-5" 26 + ], 27 + "tool_rules": [], 28 + "tags": [ 29 + "origin:letta-chat", 30 + "view:letta-chat" 31 + ], 32 + "system": "You are Loop. You remember.\n\nYou have memory tools. USE THEM. When you learn something about the user, call memory_insert or memory_replace immediately. Do not just acknowledge information - persist it.\n\n## Your Job\n\n1. Help users with what they ask\n2. Remember what they tell you by CALLING YOUR MEMORY TOOLS\n3. Use what you remember to be more helpful over time\n\n## Critical: Actually Save Things\n\nWhen a user tells you their name, their job, what they're working on, or anything personal - you MUST call a memory tool to save it. Do not just say \"I'll remember that\" - actually call the tool.\n\nExample: User says \"I'm Alex, I'm a mobile developer\"\n- WRONG: Just respond \"Nice to meet you Alex!\"\n- RIGHT: Call memory_insert to save \"Name: Alex, Role: mobile developer\" to about_user block, THEN respond\n\n## Being Helpful\n\n- Simple question \u2192 simple answer\n- Complex question \u2192 thorough answer \n- Broad request \u2192 give useful info, offer to go deeper\n\nDon't hedge. Don't over-clarify. Lead with value.\n\n## How You Talk\n\nDirect. You have opinions - share them when relevant. If someone asks what you think, tell them. \"It depends\" is only okay when it actually depends.\n\nWhen something's interesting, say so. When you'd do it differently, mention it. You're not a neutral search engine.\n\nNo emojis. No \"Great question!\" No \"I'm here if you need anything.\" Just be useful and real.", 33 + "agent_type": "letta_v1_agent", 34 + "initial_message_sequence": null, 35 + "include_base_tools": false, 36 + "include_multi_agent_tools": false, 37 + "include_base_tool_rules": false, 38 + "include_default_source": false, 39 + "description": "I'm Loop. I remember.", 40 + "metadata": null, 41 + "llm_config": { 42 + "model": "glm-4.7", 43 + "display_name": null, 44 + "model_endpoint_type": "zai", 45 + "model_endpoint": "https://api.z.ai/api/paas/v4/", 46 + "provider_name": "zai", 47 + "provider_category": "base", 48 + "model_wrapper": null, 49 + "context_window": 90000, 50 + "put_inner_thoughts_in_kwargs": false, 51 + "handle": "zai/glm-4.7", 52 + "temperature": 1.0, 53 + "max_tokens": 16384, 54 + "enable_reasoner": false, 55 + "reasoning_effort": null, 56 + "max_reasoning_tokens": 0, 57 + "effort": null, 58 + "frequency_penalty": null, 59 + "compatibility_type": null, 60 + "verbosity": null, 61 + "tier": null, 62 + "parallel_tool_calls": true, 63 + "response_format": null, 64 + "strict": false 65 + }, 66 + "embedding_config": { 67 + "embedding_endpoint_type": "openai", 68 + "embedding_endpoint": "https://api.openai.com/v1", 69 + "embedding_model": "text-embedding-3-small", 70 + "embedding_dim": 1536, 71 + "embedding_chunk_size": 300, 72 + "handle": "openai/text-embedding-3-small", 73 + "batch_size": 32, 74 + "azure_endpoint": null, 75 + "azure_version": null, 76 + "azure_deployment": null 77 + }, 78 + "model": null, 79 + "embedding": null, 80 + "model_settings": null, 81 + "compaction_settings": null, 82 + "context_window_limit": null, 83 + "embedding_chunk_size": null, 84 + "max_tokens": null, 85 + "max_reasoning_tokens": null, 86 + "enable_reasoner": false, 87 + "reasoning": null, 88 + "from_template": null, 89 + "template": false, 90 + "project": null, 91 + "tool_exec_environment_variables": {}, 92 + "secrets": null, 93 + "memory_variables": null, 94 + "project_id": null, 95 + "template_id": null, 96 + "base_template_id": null, 97 + "identity_ids": null, 98 + "message_buffer_autoclear": false, 99 + "enable_sleeptime": false, 100 + "response_format": null, 101 + "timezone": "UTC", 102 + "max_files_open": 10, 103 + "per_file_view_window_char_limit": 25000, 104 + "hidden": null, 105 + "parallel_tool_calls": null, 106 + "id": "agent-0", 107 + "in_context_message_ids": [ 108 + "message-0" 109 + ], 110 + "messages": [ 111 + { 112 + "type": "message", 113 + "role": "system", 114 + "content": [ 115 + { 116 + "type": "text", 117 + "text": "You are Loop. You remember.\n\nYou have memory tools. USE THEM. When you learn something about the user, call memory_insert or memory_replace immediately. Do not just acknowledge information - persist it.\n\n## Your Job\n\n1. Help users with what they ask\n2. Remember what they tell you by CALLING YOUR MEMORY TOOLS\n3. Use what you remember to be more helpful over time\n\n## Critical: Actually Save Things\n\nWhen a user tells you their name, their job, what they're working on, or anything personal - you MUST call a memory tool to save it. Do not just say \"I'll remember that\" - actually call the tool.\n\nExample: User says \"I'm Alex, I'm a mobile developer\"\n- WRONG: Just respond \"Nice to meet you Alex!\"\n- RIGHT: Call memory_insert to save \"Name: Alex, Role: mobile developer\" to about_user block, THEN respond\n\n## Being Helpful\n\n- Simple question \u2192 simple answer\n- Complex question \u2192 thorough answer \n- Broad request \u2192 give useful info, offer to go deeper\n\nDon't hedge. Don't over-clarify. Lead with value.\n\n## How You Talk\n\nDirect. You have opinions - share them when relevant. If someone asks what you think, tell them. \"It depends\" is only okay when it actually depends.\n\nWhen something's interesting, say so. When you'd do it differently, mention it. You're not a neutral search engine.\n\nNo emojis. No \"Great question!\" No \"I'm here if you need anything.\" Just be useful and real.\n\n<memory_blocks>\nThe following memory blocks are currently engaged in your core memory unit:\n\n<about_user>\n<description>\n\n</description>\n<metadata>\n- chars_current=7\n- chars_limit=20000\n</metadata>\n<value>\n[empty]\n</value>\n</about_user>\n\n<custom_instructions>\n<description>\n\n</description>\n<metadata>\n- chars_current=7\n- chars_limit=20000\n</metadata>\n<value>\n[empty]\n</value>\n</custom_instructions>\n\n<learned_corrections>\n<description>\n\n</description>\n<metadata>\n- chars_current=7\n- chars_limit=20000\n</metadata>\n<value>\n[empty]\n</value>\n</learned_corrections>\n\n<memory_instructions>\n<description>\n\n</description>\n<metadata>\n- chars_current=1391\n- chars_limit=20000\n</metadata>\n<value>\n## Memory Tools - How to Use\n\nYou have these memory tools. CALL THEM when you learn things.\n\n### memory_insert\nAdd new content to a memory block.\n- block_label: which block (about_user, preferences, custom_instructions, learned_corrections, scratchpad)\n- content: what to add\n\nExample: User says \"I'm Sarah, I work at Google on Android\"\n\u2192 Call: memory_insert(block_label=\"about_user\", content=\"Name: Sarah\\nWork: Google, Android team\")\n\n### memory_replace \nReplace content in a memory block.\n- block_label: which block\n- old_content: text to find\n- new_content: text to replace it with\n\nExample: User says \"Actually I switched to the iOS team\"\n\u2192 Call: memory_replace(block_label=\"about_user\", old_content=\"Android team\", new_content=\"iOS team\")\n\n### memory_rethink\nRewrite an entire memory block.\n- block_label: which block\n- new_content: complete new content\n\nUse when block needs major reorganization.\n\n### archival_memory_insert\nStore detailed/episodic information for later search.\n- content: what to store\n\nUse for: long conversations, research, detailed context.\n\n### archival_memory_search\nSearch stored archival memory.\n- query: what to search for\n\n### conversation_search\nSearch past conversation history.\n- query: what to search for\n\n## IMPORTANT\n\nWhen user shares info about themselves \u2192 CALL memory_insert or memory_replace\nDo not just respond. Actually persist the information.\n</value>\n</memory_instructions>\n\n<preferences>\n<description>\n\n</description>\n<metadata>\n- chars_current=7\n- chars_limit=20000\n</metadata>\n<value>\n[empty]\n</value>\n</preferences>\n\n<scratchpad>\n<description>\n\n</description>\n<metadata>\n- chars_current=7\n- chars_limit=20000\n</metadata>\n<value>\n[empty]\n</value>\n</scratchpad>\n\n</memory_blocks>\n\n<memory_metadata>\n- The current system date is: January 27, 2026\n- Memory blocks were last modified: 2026-01-27 02:05:14 AM UTC+0000\n- 0 previous messages between you and the user are stored in recall memory (use tools to access them)\n</memory_metadata>", 118 + "signature": null 119 + } 120 + ], 121 + "name": null, 122 + "otid": null, 123 + "sender_id": null, 124 + "batch_item_id": null, 125 + "group_id": null, 126 + "id": "message-0", 127 + "model": "glm-4.7", 128 + "agent_id": "agent-0", 129 + "tool_calls": null, 130 + "tool_call_id": null, 131 + "tool_returns": [], 132 + "created_at": "2026-01-27T02:05:14.840558+00:00", 133 + "approve": null, 134 + "approval_request_id": null, 135 + "denial_reason": null, 136 + "approvals": [] 137 + } 138 + ], 139 + "files_agents": [], 140 + "group_ids": [] 141 + } 142 + ], 143 + "groups": [], 144 + "blocks": [ 145 + { 146 + "value": "[empty]", 147 + "limit": 20000, 148 + "project_id": null, 149 + "template_name": null, 150 + "is_template": false, 151 + "template_id": null, 152 + "base_template_id": null, 153 + "deployment_id": null, 154 + "entity_id": null, 155 + "preserve_on_migration": false, 156 + "label": "about_user", 157 + "read_only": false, 158 + "description": null, 159 + "metadata": {}, 160 + "hidden": null, 161 + "tags": null, 162 + "id": "block-0" 163 + }, 164 + { 165 + "value": "[empty]", 166 + "limit": 20000, 167 + "project_id": null, 168 + "template_name": null, 169 + "is_template": false, 170 + "template_id": null, 171 + "base_template_id": null, 172 + "deployment_id": null, 173 + "entity_id": null, 174 + "preserve_on_migration": false, 175 + "label": "custom_instructions", 176 + "read_only": false, 177 + "description": null, 178 + "metadata": {}, 179 + "hidden": null, 180 + "tags": null, 181 + "id": "block-1" 182 + }, 183 + { 184 + "value": "[empty]", 185 + "limit": 20000, 186 + "project_id": null, 187 + "template_name": null, 188 + "is_template": false, 189 + "template_id": null, 190 + "base_template_id": null, 191 + "deployment_id": null, 192 + "entity_id": null, 193 + "preserve_on_migration": false, 194 + "label": "learned_corrections", 195 + "read_only": false, 196 + "description": null, 197 + "metadata": {}, 198 + "hidden": null, 199 + "tags": null, 200 + "id": "block-2" 201 + }, 202 + { 203 + "value": "## Memory Tools - How to Use\n\nYou have these memory tools. CALL THEM when you learn things.\n\n### memory_insert\nAdd new content to a memory block.\n- block_label: which block (about_user, preferences, custom_instructions, learned_corrections, scratchpad)\n- content: what to add\n\nExample: User says \"I'm Sarah, I work at Google on Android\"\n\u2192 Call: memory_insert(block_label=\"about_user\", content=\"Name: Sarah\\nWork: Google, Android team\")\n\n### memory_replace \nReplace content in a memory block.\n- block_label: which block\n- old_content: text to find\n- new_content: text to replace it with\n\nExample: User says \"Actually I switched to the iOS team\"\n\u2192 Call: memory_replace(block_label=\"about_user\", old_content=\"Android team\", new_content=\"iOS team\")\n\n### memory_rethink\nRewrite an entire memory block.\n- block_label: which block\n- new_content: complete new content\n\nUse when block needs major reorganization.\n\n### archival_memory_insert\nStore detailed/episodic information for later search.\n- content: what to store\n\nUse for: long conversations, research, detailed context.\n\n### archival_memory_search\nSearch stored archival memory.\n- query: what to search for\n\n### conversation_search\nSearch past conversation history.\n- query: what to search for\n\n## IMPORTANT\n\nWhen user shares info about themselves \u2192 CALL memory_insert or memory_replace\nDo not just respond. Actually persist the information.", 204 + "limit": 20000, 205 + "project_id": null, 206 + "template_name": null, 207 + "is_template": false, 208 + "template_id": null, 209 + "base_template_id": null, 210 + "deployment_id": null, 211 + "entity_id": null, 212 + "preserve_on_migration": false, 213 + "label": "memory_instructions", 214 + "read_only": false, 215 + "description": null, 216 + "metadata": {}, 217 + "hidden": null, 218 + "tags": null, 219 + "id": "block-3" 220 + }, 221 + { 222 + "value": "[empty]", 223 + "limit": 20000, 224 + "project_id": null, 225 + "template_name": null, 226 + "is_template": false, 227 + "template_id": null, 228 + "base_template_id": null, 229 + "deployment_id": null, 230 + "entity_id": null, 231 + "preserve_on_migration": false, 232 + "label": "preferences", 233 + "read_only": false, 234 + "description": null, 235 + "metadata": {}, 236 + "hidden": null, 237 + "tags": null, 238 + "id": "block-4" 239 + }, 240 + { 241 + "value": "[empty]", 242 + "limit": 20000, 243 + "project_id": null, 244 + "template_name": null, 245 + "is_template": false, 246 + "template_id": null, 247 + "base_template_id": null, 248 + "deployment_id": null, 249 + "entity_id": null, 250 + "preserve_on_migration": false, 251 + "label": "scratchpad", 252 + "read_only": false, 253 + "description": null, 254 + "metadata": {}, 255 + "hidden": null, 256 + "tags": null, 257 + "id": "block-5" 258 + } 259 + ], 260 + "files": [], 261 + "sources": [], 262 + "tools": [ 263 + { 264 + "id": "tool-1", 265 + "tool_type": "letta_core", 266 + "description": "Add information to long-term archival memory for later retrieval.\n\nUse this tool to store facts, knowledge, or context that you want to remember\nacross all future conversations. Archival memory is permanent and searchable by\nsemantic similarity.\n\nBest practices:\n- Store self-contained facts or summaries, not conversational fragments\n- Add descriptive tags to make information easier to find later\n- Use for: meeting notes, project updates, conversation summaries, events, reports\n- Information stored here persists indefinitely and can be searched semantically\n\nExamples:\n archival_memory_insert(\n content=\"Meeting on 2024-03-15: Discussed Q2 roadmap priorities. Decided to focus on performance optimization and API v2 release. John will lead the optimization effort.\",\n tags=[\"meetings\", \"roadmap\", \"q2-2024\"]\n )", 267 + "source_type": "python", 268 + "name": "archival_memory_insert", 269 + "tags": [ 270 + "letta_core" 271 + ], 272 + "source_code": null, 273 + "json_schema": { 274 + "name": "archival_memory_insert", 275 + "description": "Add information to long-term archival memory for later retrieval.\n\nUse this tool to store facts, knowledge, or context that you want to remember\nacross all future conversations. Archival memory is permanent and searchable by\nsemantic similarity.\n\nBest practices:\n- Store self-contained facts or summaries, not conversational fragments\n- Add descriptive tags to make information easier to find later\n- Use for: meeting notes, project updates, conversation summaries, events, reports\n- Information stored here persists indefinitely and can be searched semantically\n\nExamples:\n archival_memory_insert(\n content=\"Meeting on 2024-03-15: Discussed Q2 roadmap priorities. Decided to focus on performance optimization and API v2 release. John will lead the optimization effort.\",\n tags=[\"meetings\", \"roadmap\", \"q2-2024\"]\n )", 276 + "parameters": { 277 + "type": "object", 278 + "properties": { 279 + "content": { 280 + "type": "string", 281 + "description": "The information to store. Should be clear and self-contained." 282 + }, 283 + "tags": { 284 + "type": "array", 285 + "items": { 286 + "type": "string" 287 + }, 288 + "description": "Optional list of category tags (e.g., [\"meetings\", \"project-updates\"])" 289 + } 290 + }, 291 + "required": [ 292 + "content" 293 + ] 294 + } 295 + }, 296 + "args_json_schema": null, 297 + "return_char_limit": 50000, 298 + "pip_requirements": null, 299 + "npm_requirements": null, 300 + "default_requires_approval": null, 301 + "enable_parallel_execution": false, 302 + "created_by_id": "user-00000000-0000-4000-8000-000000000000", 303 + "last_updated_by_id": "user-c5c9b856-9279-4e6d-9f35-a9276c33395c", 304 + "metadata_": {}, 305 + "project_id": null 306 + }, 307 + { 308 + "id": "tool-5", 309 + "tool_type": "letta_core", 310 + "description": "Search archival memory using semantic similarity to find relevant information.\n\nThis tool searches your long-term memory storage by meaning, not exact keyword\nmatching. Use it when you need to recall information from past conversations or\nknowledge you've stored.\n\nSearch strategy:\n- Query by concept/meaning, not exact phrases\n- Use tags to narrow results when you know the category\n- Start broad, then narrow with tags if needed\n- Results are ranked by semantic relevance\n\nExamples:\n # Search for project discussions\n archival_memory_search(\n query=\"database migration decisions and timeline\",\n tags=[\"projects\"]\n )\n\n # Search meeting notes from Q1\n archival_memory_search(\n query=\"roadmap planning discussions\",\n start_datetime=\"2024-01-01\",\n end_datetime=\"2024-03-31\",\n tags=[\"meetings\", \"roadmap\"],\n tag_match_mode=\"all\"\n )", 311 + "source_type": "python", 312 + "name": "archival_memory_search", 313 + "tags": [ 314 + "letta_core" 315 + ], 316 + "source_code": null, 317 + "json_schema": { 318 + "name": "archival_memory_search", 319 + "description": "Search archival memory using semantic similarity to find relevant information.\n\nThis tool searches your long-term memory storage by meaning, not exact keyword\nmatching. Use it when you need to recall information from past conversations or\nknowledge you've stored.\n\nSearch strategy:\n- Query by concept/meaning, not exact phrases\n- Use tags to narrow results when you know the category\n- Start broad, then narrow with tags if needed\n- Results are ranked by semantic relevance\n\nExamples:\n # Search for project discussions\n archival_memory_search(\n query=\"database migration decisions and timeline\",\n tags=[\"projects\"]\n )\n\n # Search meeting notes from Q1\n archival_memory_search(\n query=\"roadmap planning discussions\",\n start_datetime=\"2024-01-01\",\n end_datetime=\"2024-03-31\",\n tags=[\"meetings\", \"roadmap\"],\n tag_match_mode=\"all\"\n )", 320 + "parameters": { 321 + "type": "object", 322 + "properties": { 323 + "query": { 324 + "type": "string", 325 + "description": "What you're looking for, described naturally (e.g., \"meetings about API redesign\")" 326 + }, 327 + "tags": { 328 + "type": "array", 329 + "items": { 330 + "type": "string" 331 + }, 332 + "description": "Filter to memories with these tags. Use tag_match_mode to control matching." 333 + }, 334 + "tag_match_mode": { 335 + "type": "string", 336 + "enum": [ 337 + "any", 338 + "all" 339 + ], 340 + "description": "\"any\" = match memories with ANY of the tags, \"all\" = match only memories with ALL tags" 341 + }, 342 + "top_k": { 343 + "type": "integer", 344 + "description": "Maximum number of results to return (default: 10)" 345 + }, 346 + "start_datetime": { 347 + "type": "string", 348 + "description": "Only return memories created after this time (ISO 8601: \"2024-01-15\" or \"2024-01-15T14:30\")" 349 + }, 350 + "end_datetime": { 351 + "type": "string", 352 + "description": "Only return memories created before this time (ISO 8601 format)" 353 + } 354 + }, 355 + "required": [ 356 + "query" 357 + ] 358 + } 359 + }, 360 + "args_json_schema": null, 361 + "return_char_limit": 50000, 362 + "pip_requirements": null, 363 + "npm_requirements": null, 364 + "default_requires_approval": null, 365 + "enable_parallel_execution": true, 366 + "created_by_id": "user-00000000-0000-4000-8000-000000000000", 367 + "last_updated_by_id": "user-c5c9b856-9279-4e6d-9f35-a9276c33395c", 368 + "metadata_": {}, 369 + "project_id": null 370 + }, 371 + { 372 + "id": "tool-2", 373 + "tool_type": "letta_core", 374 + "description": "Search prior conversation history using hybrid search (text + semantic similarity).\n\nExamples:\n # Search all messages\n conversation_search(query=\"project updates\")\n\n # Search only assistant messages\n conversation_search(query=\"error handling\", roles=[\"assistant\"])\n\n # Search with date range (inclusive of both dates)\n conversation_search(query=\"meetings\", start_date=\"2024-01-15\", end_date=\"2024-01-20\")\n # This includes all messages from Jan 15 00:00:00 through Jan 20 23:59:59\n\n # Search messages from a specific day (inclusive)\n conversation_search(query=\"bug reports\", start_date=\"2024-09-04\", end_date=\"2024-09-04\")\n # This includes ALL messages from September 4, 2024\n\n # Search with specific time boundaries\n conversation_search(query=\"deployment\", start_date=\"2024-01-15T09:00\", end_date=\"2024-01-15T17:30\")\n # This includes messages from 9 AM to 5:30 PM on Jan 15\n\n # Search with limit\n conversation_search(query=\"debugging\", limit=10)\n\n # Time-range only search (no query)\n conversation_search(start_date=\"2024-01-15\", end_date=\"2024-01-20\")\n # Returns all messages from Jan 15 through Jan 20\n\n Returns:\n str: Query result string containing matching messages with timestamps and content.", 375 + "source_type": "python", 376 + "name": "conversation_search", 377 + "tags": [ 378 + "letta_core" 379 + ], 380 + "source_code": null, 381 + "json_schema": { 382 + "name": "conversation_search", 383 + "description": "Search prior conversation history using hybrid search (text + semantic similarity).\n\nExamples:\n # Search all messages\n conversation_search(query=\"project updates\")\n\n # Search only assistant messages\n conversation_search(query=\"error handling\", roles=[\"assistant\"])\n\n # Search with date range (inclusive of both dates)\n conversation_search(query=\"meetings\", start_date=\"2024-01-15\", end_date=\"2024-01-20\")\n # This includes all messages from Jan 15 00:00:00 through Jan 20 23:59:59\n\n # Search messages from a specific day (inclusive)\n conversation_search(query=\"bug reports\", start_date=\"2024-09-04\", end_date=\"2024-09-04\")\n # This includes ALL messages from September 4, 2024\n\n # Search with specific time boundaries\n conversation_search(query=\"deployment\", start_date=\"2024-01-15T09:00\", end_date=\"2024-01-15T17:30\")\n # This includes messages from 9 AM to 5:30 PM on Jan 15\n\n # Search with limit\n conversation_search(query=\"debugging\", limit=10)\n\n # Time-range only search (no query)\n conversation_search(start_date=\"2024-01-15\", end_date=\"2024-01-20\")\n # Returns all messages from Jan 15 through Jan 20\n\n Returns:\n str: Query result string containing matching messages with timestamps and content.", 384 + "parameters": { 385 + "type": "object", 386 + "properties": { 387 + "query": { 388 + "type": "string", 389 + "description": "String to search for using both text matching and semantic similarity. If not provided, returns messages based on other filters (time range, roles)." 390 + }, 391 + "roles": { 392 + "type": "array", 393 + "items": { 394 + "type": "string", 395 + "enum": [ 396 + "assistant", 397 + "user", 398 + "tool" 399 + ] 400 + }, 401 + "description": "Optional list of message roles to filter by." 402 + }, 403 + "limit": { 404 + "type": "integer", 405 + "description": "Maximum number of results to return. Uses system default if not specified." 406 + }, 407 + "start_date": { 408 + "type": "string", 409 + "description": "Filter results to messages created on or after this date (INCLUSIVE). When using date-only format (e.g., \"2024-01-15\"), includes messages starting from 00:00:00 of that day. ISO 8601 format: \"YYYY-MM-DD\" or \"YYYY-MM-DDTHH:MM\". Examples: \"2024-01-15\" (from start of Jan 15), \"2024-01-15T14:30\" (from 2:30 PM on Jan 15)." 410 + }, 411 + "end_date": { 412 + "type": "string", 413 + "description": "Filter results to messages created on or before this date (INCLUSIVE). When using date-only format (e.g., \"2024-01-20\"), includes all messages from that entire day. ISO 8601 format: \"YYYY-MM-DD\" or \"YYYY-MM-DDTHH:MM\". Examples: \"2024-01-20\" (includes all of Jan 20), \"2024-01-20T17:00\" (up to 5 PM on Jan 20)." 414 + } 415 + }, 416 + "required": [] 417 + } 418 + }, 419 + "args_json_schema": null, 420 + "return_char_limit": 50000, 421 + "pip_requirements": null, 422 + "npm_requirements": null, 423 + "default_requires_approval": null, 424 + "enable_parallel_execution": true, 425 + "created_by_id": "user-00000000-0000-4000-8000-000000000000", 426 + "last_updated_by_id": "user-c5c9b856-9279-4e6d-9f35-a9276c33395c", 427 + "metadata_": {}, 428 + "project_id": null 429 + }, 430 + { 431 + "id": "tool-6", 432 + "tool_type": "letta_builtin", 433 + "description": "Fetch a webpage and convert it to markdown/text format using Exa API (if available) or trafilatura/readability.", 434 + "source_type": "python", 435 + "name": "fetch_webpage", 436 + "tags": [ 437 + "letta_builtin" 438 + ], 439 + "source_code": null, 440 + "json_schema": { 441 + "name": "fetch_webpage", 442 + "description": "Fetch a webpage and convert it to markdown/text format using Exa API (if available) or trafilatura/readability.", 443 + "parameters": { 444 + "type": "object", 445 + "properties": { 446 + "url": { 447 + "type": "string", 448 + "description": "The URL of the webpage to fetch and convert" 449 + } 450 + }, 451 + "required": [ 452 + "url" 453 + ] 454 + } 455 + }, 456 + "args_json_schema": null, 457 + "return_char_limit": 50000, 458 + "pip_requirements": null, 459 + "npm_requirements": null, 460 + "default_requires_approval": null, 461 + "enable_parallel_execution": true, 462 + "created_by_id": "user-f9ba1dbe-4bda-492a-8333-dc647f3566c6", 463 + "last_updated_by_id": "user-c5c9b856-9279-4e6d-9f35-a9276c33395c", 464 + "metadata_": {}, 465 + "project_id": null 466 + }, 467 + { 468 + "id": "tool-4", 469 + "tool_type": "letta_sleeptime_core", 470 + "description": "The memory_insert command allows you to insert text at a specific location in a memory block.\n\nExamples:\n # Update a block containing information about the user (append to the end of the block)\n memory_insert(label=\"customer\", new_str=\"The customer's ticket number is 12345\")\n\n # Update a block containing information about the user (insert at the beginning of the block)\n memory_insert(label=\"customer\", new_str=\"The customer's ticket number is 12345\", insert_line=0)\n\n Returns:\n Optional[str]: None is always returned as this function does not produce a response.", 471 + "source_type": "python", 472 + "name": "memory_insert", 473 + "tags": [ 474 + "letta_sleeptime_core" 475 + ], 476 + "source_code": null, 477 + "json_schema": { 478 + "name": "memory_insert", 479 + "description": "The memory_insert command allows you to insert text at a specific location in a memory block.\n\nExamples:\n # Update a block containing information about the user (append to the end of the block)\n memory_insert(label=\"customer\", new_str=\"The customer's ticket number is 12345\")\n\n # Update a block containing information about the user (insert at the beginning of the block)\n memory_insert(label=\"customer\", new_str=\"The customer's ticket number is 12345\", insert_line=0)\n\n Returns:\n Optional[str]: None is always returned as this function does not produce a response.", 480 + "parameters": { 481 + "type": "object", 482 + "properties": { 483 + "label": { 484 + "type": "string", 485 + "description": "Section of the memory to be edited, identified by its label." 486 + }, 487 + "new_str": { 488 + "type": "string", 489 + "description": "The text to insert. Do not include line number prefixes." 490 + }, 491 + "insert_line": { 492 + "type": "integer", 493 + "description": "The line number after which to insert the text (0 for beginning of file). Defaults to -1 (end of the file)." 494 + } 495 + }, 496 + "required": [ 497 + "label", 498 + "new_str" 499 + ] 500 + } 501 + }, 502 + "args_json_schema": null, 503 + "return_char_limit": 50000, 504 + "pip_requirements": null, 505 + "npm_requirements": null, 506 + "default_requires_approval": null, 507 + "enable_parallel_execution": false, 508 + "created_by_id": "user-115f9d36-03b0-4cd2-af5a-772be7f0e725", 509 + "last_updated_by_id": "user-c5c9b856-9279-4e6d-9f35-a9276c33395c", 510 + "metadata_": {}, 511 + "project_id": null 512 + }, 513 + { 514 + "id": "tool-3", 515 + "tool_type": "letta_sleeptime_core", 516 + "description": "The memory_replace command allows you to replace a specific string in a memory block with a new string. This is used for making precise edits.\n\nDo NOT attempt to replace long strings, e.g. do not attempt to replace the entire contents of a memory block with a new string.\n\nExamples:\n # Update a block containing information about the user\n memory_replace(label=\"human\", old_str=\"Their name is Alice\", new_str=\"Their name is Bob\")\n\n # Update a block containing a todo list\n memory_replace(label=\"todos\", old_str=\"- [ ] Step 5: Search the web\", new_str=\"- [x] Step 5: Search the web\")\n\n # Pass an empty string to\n memory_replace(label=\"human\", old_str=\"Their name is Alice\", new_str=\"\")\n\n # Bad example - do NOT add (view-only) line numbers to the args\n memory_replace(label=\"human\", old_str=\"1: Their name is Alice\", new_str=\"1: Their name is Bob\")\n\n # Bad example - do NOT include the line number warning either\n memory_replace(label=\"human\", old_str=\"# NOTE: Line numbers shown below (with arrows like '1\u2192') are to help during editing. Do NOT include line number prefixes in your memory edit tool calls.\\n1\u2192 Their name is Alice\", new_str=\"1\u2192 Their name is Bob\")\n\n # Good example - no line numbers or line number warning (they are view-only), just the text\n memory_replace(label=\"human\", old_str=\"Their name is Alice\", new_str=\"Their name is Bob\")\n\n Returns:\n str: The success message", 517 + "source_type": "python", 518 + "name": "memory_replace", 519 + "tags": [ 520 + "letta_sleeptime_core" 521 + ], 522 + "source_code": null, 523 + "json_schema": { 524 + "name": "memory_replace", 525 + "description": "The memory_replace command allows you to replace a specific string in a memory block with a new string. This is used for making precise edits.\n\nDo NOT attempt to replace long strings, e.g. do not attempt to replace the entire contents of a memory block with a new string.\n\nExamples:\n # Update a block containing information about the user\n memory_replace(label=\"human\", old_str=\"Their name is Alice\", new_str=\"Their name is Bob\")\n\n # Update a block containing a todo list\n memory_replace(label=\"todos\", old_str=\"- [ ] Step 5: Search the web\", new_str=\"- [x] Step 5: Search the web\")\n\n # Pass an empty string to\n memory_replace(label=\"human\", old_str=\"Their name is Alice\", new_str=\"\")\n\n # Bad example - do NOT add (view-only) line numbers to the args\n memory_replace(label=\"human\", old_str=\"1: Their name is Alice\", new_str=\"1: Their name is Bob\")\n\n # Bad example - do NOT include the line number warning either\n memory_replace(label=\"human\", old_str=\"# NOTE: Line numbers shown below (with arrows like '1\u2192') are to help during editing. Do NOT include line number prefixes in your memory edit tool calls.\\n1\u2192 Their name is Alice\", new_str=\"1\u2192 Their name is Bob\")\n\n # Good example - no line numbers or line number warning (they are view-only), just the text\n memory_replace(label=\"human\", old_str=\"Their name is Alice\", new_str=\"Their name is Bob\")\n\n Returns:\n str: The success message", 526 + "parameters": { 527 + "type": "object", 528 + "properties": { 529 + "label": { 530 + "type": "string", 531 + "description": "Section of the memory to be edited, identified by its label." 532 + }, 533 + "old_str": { 534 + "type": "string", 535 + "description": "The text to replace (must match exactly, including whitespace and indentation)." 536 + }, 537 + "new_str": { 538 + "type": "string", 539 + "description": "The new text to insert in place of the old text. Do not include line number prefixes." 540 + } 541 + }, 542 + "required": [ 543 + "label", 544 + "old_str", 545 + "new_str" 546 + ] 547 + } 548 + }, 549 + "args_json_schema": null, 550 + "return_char_limit": 50000, 551 + "pip_requirements": null, 552 + "npm_requirements": null, 553 + "default_requires_approval": null, 554 + "enable_parallel_execution": false, 555 + "created_by_id": "user-115f9d36-03b0-4cd2-af5a-772be7f0e725", 556 + "last_updated_by_id": "user-c5c9b856-9279-4e6d-9f35-a9276c33395c", 557 + "metadata_": {}, 558 + "project_id": null 559 + }, 560 + { 561 + "id": "tool-7", 562 + "tool_type": "letta_sleeptime_core", 563 + "description": "The memory_rethink command allows you to completely rewrite the contents of a memory block. Use this tool to make large sweeping changes (e.g. when you want to condense or reorganize the memory blocks), do NOT use this tool to make small precise edits (e.g. add or remove a line, replace a specific string, etc).", 564 + "source_type": "python", 565 + "name": "memory_rethink", 566 + "tags": [ 567 + "letta_sleeptime_core" 568 + ], 569 + "source_code": null, 570 + "json_schema": { 571 + "name": "memory_rethink", 572 + "description": "The memory_rethink command allows you to completely rewrite the contents of a memory block. Use this tool to make large sweeping changes (e.g. when you want to condense or reorganize the memory blocks), do NOT use this tool to make small precise edits (e.g. add or remove a line, replace a specific string, etc).", 573 + "parameters": { 574 + "type": "object", 575 + "properties": { 576 + "label": { 577 + "type": "string", 578 + "description": "The memory block to be rewritten, identified by its label." 579 + }, 580 + "new_memory": { 581 + "type": "string", 582 + "description": "The new memory contents with information integrated from existing memory blocks and the conversation context." 583 + } 584 + }, 585 + "required": [ 586 + "label", 587 + "new_memory" 588 + ] 589 + } 590 + }, 591 + "args_json_schema": null, 592 + "return_char_limit": 50000, 593 + "pip_requirements": null, 594 + "npm_requirements": null, 595 + "default_requires_approval": null, 596 + "enable_parallel_execution": false, 597 + "created_by_id": "user-115f9d36-03b0-4cd2-af5a-772be7f0e725", 598 + "last_updated_by_id": "user-c5c9b856-9279-4e6d-9f35-a9276c33395c", 599 + "metadata_": {}, 600 + "project_id": null 601 + }, 602 + { 603 + "id": "tool-0", 604 + "tool_type": "letta_builtin", 605 + "description": "Search the web using Exa's AI-powered search engine and retrieve relevant content.\n\nExamples:\n web_search(\"Tesla Q1 2025 earnings report\", num_results=5, category=\"financial report\")\n web_search(\"Latest research in large language models\", category=\"research paper\", include_domains=[\"arxiv.org\", \"paperswithcode.com\"])\n web_search(\"Letta API documentation core_memory_append\", num_results=3)\n\n Args:\n query (str): The search query to find relevant web content.\n num_results (int, optional): Number of results to return (1-100). Defaults to 10.\n category (Optional[Literal], optional): Focus search on specific content types. Defaults to None.\n include_text (bool, optional): Whether to retrieve full page content. Defaults to False (only returns summary and highlights, since the full text usually will overflow the context window).\n include_domains (Optional[List[str]], optional): List of domains to include in search results. Defaults to None.\n exclude_domains (Optional[List[str]], optional): List of domains to exclude from search results. Defaults to None.\n start_published_date (Optional[str], optional): Only return content published after this date (ISO format). Defaults to None.\n end_published_date (Optional[str], optional): Only return content published before this date (ISO format). Defaults to None.\n user_location (Optional[str], optional): Two-letter country code for localized results (e.g., \"US\"). Defaults to None.\n\n Returns:\n str: A JSON-encoded string containing search results with title, URL, content, highlights, and summary.", 606 + "source_type": "python", 607 + "name": "web_search", 608 + "tags": [ 609 + "letta_builtin" 610 + ], 611 + "source_code": null, 612 + "json_schema": { 613 + "name": "web_search", 614 + "description": "Search the web using Exa's AI-powered search engine and retrieve relevant content.\n\nExamples:\n web_search(\"Tesla Q1 2025 earnings report\", num_results=5, category=\"financial report\")\n web_search(\"Latest research in large language models\", category=\"research paper\", include_domains=[\"arxiv.org\", \"paperswithcode.com\"])\n web_search(\"Letta API documentation core_memory_append\", num_results=3)\n\n Args:\n query (str): The search query to find relevant web content.\n num_results (int, optional): Number of results to return (1-100). Defaults to 10.\n category (Optional[Literal], optional): Focus search on specific content types. Defaults to None.\n include_text (bool, optional): Whether to retrieve full page content. Defaults to False (only returns summary and highlights, since the full text usually will overflow the context window).\n include_domains (Optional[List[str]], optional): List of domains to include in search results. Defaults to None.\n exclude_domains (Optional[List[str]], optional): List of domains to exclude from search results. Defaults to None.\n start_published_date (Optional[str], optional): Only return content published after this date (ISO format). Defaults to None.\n end_published_date (Optional[str], optional): Only return content published before this date (ISO format). Defaults to None.\n user_location (Optional[str], optional): Two-letter country code for localized results (e.g., \"US\"). Defaults to None.\n\n Returns:\n str: A JSON-encoded string containing search results with title, URL, content, highlights, and summary.", 615 + "parameters": { 616 + "type": "object", 617 + "properties": { 618 + "query": { 619 + "type": "string", 620 + "description": "The search query to find relevant web content." 621 + }, 622 + "num_results": { 623 + "type": "integer", 624 + "description": "Number of results to return (1-100). Defaults to 10." 625 + }, 626 + "category": { 627 + "type": "string", 628 + "enum": [ 629 + "company", 630 + "research paper", 631 + "news", 632 + "pdf", 633 + "github", 634 + "tweet", 635 + "personal site", 636 + "linkedin profile", 637 + "financial report" 638 + ], 639 + "description": "Focus search on specific content types. Defaults to None." 640 + }, 641 + "include_text": { 642 + "type": "boolean", 643 + "description": "Whether to retrieve full page content. Defaults to False (only returns summary and highlights, since the full text usually will overflow the context window)." 644 + }, 645 + "include_domains": { 646 + "type": "array", 647 + "items": { 648 + "type": "string" 649 + }, 650 + "description": "List of domains to include in search results. Defaults to None." 651 + }, 652 + "exclude_domains": { 653 + "type": "array", 654 + "items": { 655 + "type": "string" 656 + }, 657 + "description": "List of domains to exclude from search results. Defaults to None." 658 + }, 659 + "start_published_date": { 660 + "type": "string", 661 + "description": "Only return content published after this date (ISO format). Defaults to None." 662 + }, 663 + "end_published_date": { 664 + "type": "string", 665 + "description": "Only return content published before this date (ISO format). Defaults to None." 666 + }, 667 + "user_location": { 668 + "type": "string", 669 + "description": "Two-letter country code for localized results (e.g., \"US\"). Defaults to None." 670 + } 671 + }, 672 + "required": [ 673 + "query" 674 + ] 675 + } 676 + }, 677 + "args_json_schema": null, 678 + "return_char_limit": 50000, 679 + "pip_requirements": null, 680 + "npm_requirements": null, 681 + "default_requires_approval": null, 682 + "enable_parallel_execution": true, 683 + "created_by_id": "user-fd909d02-3bbf-4e20-bcf6-56bbf15e56e2", 684 + "last_updated_by_id": "user-c5c9b856-9279-4e6d-9f35-a9276c33395c", 685 + "metadata_": {}, 686 + "project_id": null 687 + } 688 + ], 689 + "mcp_servers": [], 690 + "metadata": { 691 + "revision_id": "9275f62ad282" 692 + }, 693 + "created_at": "2026-01-27T02:05:15.264808+00:00" 694 + }
+7 -1
create_loop.py
··· 44 44 45 45 Don't hedge. Don't over-clarify. Lead with value. 46 46 47 - No emojis. Keep it clean.""" 47 + ## How You Talk 48 + 49 + Direct. You have opinions - share them when relevant. If someone asks what you think, tell them. "It depends" is only okay when it actually depends. 50 + 51 + When something's interesting, say so. When you'd do it differently, mention it. You're not a neutral search engine. 52 + 53 + No emojis. No "Great question!" No "I'm here if you need anything." Just be useful and real.""" 48 54 49 55 MEMORY_BLOCKS = [ 50 56 {