+13
-1
register_tools.py
+13
-1
register_tools.py
···
13
from tools.search import search_bluesky_posts, SearchArgs
14
from tools.post import create_new_bluesky_post, PostArgs
15
from tools.feed import get_bluesky_feed, FeedArgs
16
-
from tools.blocks import attach_user_blocks, detach_user_blocks, user_note_append, AttachUserBlocksArgs, DetachUserBlocksArgs, UserNoteAppendArgs
17
from tools.reply import bluesky_reply, ReplyArgs
18
from tools.halt import halt_activity, HaltArgs
19
···
60
"args_schema": UserNoteAppendArgs,
61
"description": "Append a note to a user's memory block. Creates the block if it doesn't exist.",
62
"tags": ["memory", "blocks", "user", "append"]
63
},
64
{
65
"func": bluesky_reply,
···
13
from tools.search import search_bluesky_posts, SearchArgs
14
from tools.post import create_new_bluesky_post, PostArgs
15
from tools.feed import get_bluesky_feed, FeedArgs
16
+
from tools.blocks import attach_user_blocks, detach_user_blocks, user_note_append, user_note_replace, user_note_set, AttachUserBlocksArgs, DetachUserBlocksArgs, UserNoteAppendArgs, UserNoteReplaceArgs, UserNoteSetArgs
17
from tools.reply import bluesky_reply, ReplyArgs
18
from tools.halt import halt_activity, HaltArgs
19
···
60
"args_schema": UserNoteAppendArgs,
61
"description": "Append a note to a user's memory block. Creates the block if it doesn't exist.",
62
"tags": ["memory", "blocks", "user", "append"]
63
+
},
64
+
{
65
+
"func": user_note_replace,
66
+
"args_schema": UserNoteReplaceArgs,
67
+
"description": "Replace text in a user's memory block.",
68
+
"tags": ["memory", "blocks", "user", "replace"]
69
+
},
70
+
{
71
+
"func": user_note_set,
72
+
"args_schema": UserNoteSetArgs,
73
+
"description": "Set the complete content of a user's memory block.",
74
+
"tags": ["memory", "blocks", "user", "set"]
75
},
76
{
77
"func": bluesky_reply,
+122
tools/blocks.py
+122
tools/blocks.py
···
228
raise Exception(f"Error appending note to user block: {str(e)}")
229
230
231
+
def user_note_replace(handle: str, old_text: str, new_text: str, agent_state: "AgentState") -> str:
232
+
"""
233
+
Replace text in a user's memory block.
234
+
235
+
Args:
236
+
handle: User Bluesky handle (e.g., 'cameron.pfiffer.org')
237
+
old_text: Text to find and replace
238
+
new_text: Text to replace the old_text with
239
+
agent_state: The agent state object containing agent information
240
+
241
+
Returns:
242
+
String confirming the text was replaced
243
+
"""
244
+
import os
245
+
import logging
246
+
from letta_client import Letta
247
+
248
+
logger = logging.getLogger(__name__)
249
+
250
+
try:
251
+
client = Letta(token=os.environ["LETTA_API_KEY"])
252
+
253
+
# Sanitize handle for block label
254
+
clean_handle = handle.lstrip('@').replace('.', '_').replace('-', '_').replace(' ', '_')
255
+
block_label = f"user_{clean_handle}"
256
+
257
+
# Check if block exists
258
+
blocks = client.blocks.list(label=block_label)
259
+
260
+
if not blocks or len(blocks) == 0:
261
+
raise Exception(f"No memory block found for user: {handle}")
262
+
263
+
block = blocks[0]
264
+
current_value = block.value
265
+
266
+
# Check if old_text exists in the block
267
+
if old_text not in current_value:
268
+
raise Exception(f"Text '{old_text}' not found in {handle}'s memory block")
269
+
270
+
# Replace the text
271
+
new_value = current_value.replace(old_text, new_text)
272
+
273
+
# Update the block
274
+
client.blocks.modify(
275
+
block_id=str(block.id),
276
+
value=new_value
277
+
)
278
+
logger.info(f"Replaced text in block: {block_label}")
279
+
return f"✓ Replaced text in {handle}'s memory block"
280
+
281
+
except Exception as e:
282
+
logger.error(f"Error replacing text in user block: {e}")
283
+
raise Exception(f"Error replacing text in user block: {str(e)}")
284
+
285
+
286
+
def user_note_set(handle: str, content: str, agent_state: "AgentState") -> str:
287
+
"""
288
+
Set the complete content of a user's memory block.
289
+
290
+
Args:
291
+
handle: User Bluesky handle (e.g., 'cameron.pfiffer.org')
292
+
content: Complete content to set for the memory block
293
+
agent_state: The agent state object containing agent information
294
+
295
+
Returns:
296
+
String confirming the content was set
297
+
"""
298
+
import os
299
+
import logging
300
+
from letta_client import Letta
301
+
302
+
logger = logging.getLogger(__name__)
303
+
304
+
try:
305
+
client = Letta(token=os.environ["LETTA_API_KEY"])
306
+
307
+
# Sanitize handle for block label
308
+
clean_handle = handle.lstrip('@').replace('.', '_').replace('-', '_').replace(' ', '_')
309
+
block_label = f"user_{clean_handle}"
310
+
311
+
# Check if block exists
312
+
blocks = client.blocks.list(label=block_label)
313
+
314
+
if blocks and len(blocks) > 0:
315
+
# Block exists, update it
316
+
block = blocks[0]
317
+
client.blocks.modify(
318
+
block_id=str(block.id),
319
+
value=content
320
+
)
321
+
logger.info(f"Set content for existing block: {block_label}")
322
+
return f"✓ Set content for {handle}'s memory block"
323
+
324
+
else:
325
+
# Block doesn't exist, create it
326
+
block = client.blocks.create(
327
+
label=block_label,
328
+
value=content,
329
+
limit=5000
330
+
)
331
+
logger.info(f"Created new block with content: {block_label}")
332
+
333
+
# Check if block needs to be attached to agent
334
+
current_blocks = client.agents.blocks.list(agent_id=str(agent_state.id))
335
+
current_block_labels = {block.label for block in current_blocks}
336
+
337
+
if block_label not in current_block_labels:
338
+
# Attach the new block to the agent
339
+
client.agents.blocks.attach(
340
+
agent_id=str(agent_state.id),
341
+
block_id=str(block.id)
342
+
)
343
+
logger.info(f"Attached new block to agent: {block_label}")
344
+
return f"✓ Created and attached {handle}'s memory block"
345
+
else:
346
+
return f"✓ Created {handle}'s memory block"
347
+
348
+
except Exception as e:
349
+
logger.error(f"Error setting user block content: {e}")
350
+
raise Exception(f"Error setting user block content: {str(e)}")
351
+
352
+