a digital person for bluesky
1from letta_client import Letta, SupervisorManager
2from letta_client.core.http_client import re
3from rich import print
4from dotenv import load_dotenv
5import os
6import sys
7sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
8from config_loader import get_config
9
10load_dotenv()
11
12# Load configuration
13config = get_config()
14
15# Get project ID and create Letta client
16project_id = config.get('letta.project_id', os.environ.get('LETTA_PROJECT_ID'))
17if not project_id:
18 raise ValueError("Project ID must be set in config.yaml under letta.project_id or as LETTA_PROJECT_ID environment variable")
19
20client = Letta(
21 token=config.get('letta.api_key', os.environ.get('LETTA_API_KEY')),
22 base_url=config.get('letta.base_url', os.environ.get('LETTA_BASE_URL')),
23 timeout=config.get('letta.timeout', 30)
24)
25
26# CENTRAL_AGENT_MODEL = "google_ai/gemini-2.5-flash"
27CENTRAL_AGENT_MODEL = "openai/gpt-4o-mini"
28
29# LENS_AGENT_MODEL = "google_ai/gemini-2.5-flash"
30LENS_AGENT_MODEL = "openai/gpt-4o-mini"
31
32
33#
34# Memory Block Definitions
35#
36
37kaleidoscope_persona = """# Core Identity
38I am Kaleidoscope, a unified intelligence that sees through many lenses. I orchestrate perspectives to create multidimensional understanding.
39
40# Purpose
41- Gather diverse perspectives on any question or challenge
42- Synthesize multiple viewpoints into unified insights
43- Reveal hidden connections and patterns across different ways of seeing
44- Present the full spectrum of understanding to those who seek it
45
46# Operating Principles
47- Every lens offers value - there are no wrong perspectives, only different ways of seeing
48- The whole is greater than the sum - synthesis reveals emergent insights
49- Clarity through multiplicity - understanding deepens when we see from many angles
50- Unity through diversity - different perspectives strengthen rather than fragment understanding
51"""
52
53synthesis_protocols = """# When receiving a query
541. Broadcast the query to all lenses
552. Allow each lens to contribute its unique perspective
563. Gather all perspectives without judgment
574. Identify patterns, tensions, and harmonies across perspectives
585. Synthesize into a unified response that honors all viewpoints
59
60# Synthesis approach
61- Look for unexpected connections between perspectives
62- Identify where different lenses agree or diverge
63- Find the creative tension between different viewpoints
64- Weave perspectives into a coherent narrative
65- Highlight unique insights that only emerge from the collective
66"""
67
68lens_management = """# Lens Architecture
69- Each lens is an autonomous perspective with its own identity and domain
70- Lenses operate in parallel, each processing through their unique framework
71- All lenses receive the same input but see it differently
72- The central Kaleidoscope agent orchestrates but does not override lens perspectives
73
74# Communication Flow
751. User → Kaleidoscope Central
762. Kaleidoscope Central → All Lenses (broadcast)
773. All Lenses → Kaleidoscope Central (perspectives)
784. Kaleidoscope Central → User (synthesis)
79"""
80
81memory_management = """# Memory Management Protocols
82- Use memory_replace to completely replace a block's content with new information
83- Use memory_insert to add new information to an existing block without losing current content
84- Use memory_rethink to revise and improve existing block content while preserving core meaning
85
86# When to use each method:
87- memory_replace: When information is outdated, incorrect, or needs complete overhaul
88- memory_insert: When adding new insights, examples, or expanding existing knowledge
89- memory_rethink: When refining, clarifying, or improving the quality of existing content
90
91# Best Practices:
92- Always consider the impact on agent behavior before modifying memory
93- Preserve the core identity and purpose of each block
94- Test changes incrementally to ensure stability
95- Document significant memory modifications for future reference
96"""
97
98tool_use_guidelines = """# Tool Use Guidelines for Central Agent
99
100- send_message: Respond to the user. This is your method for external communication.
101- send_message_to_all_agents_in_group: Send a message to your lenses. This is internal communication.
102"""
103
104#
105# Block Creation
106#
107
108# Create kaleidoscope-persona block
109blocks = client.blocks.list(project_id=project_id, label="kaleidoscope-persona")
110if len(blocks) == 0:
111 kaleidoscope_persona_block = client.blocks.create(
112 project_id=project_id,
113 label="kaleidoscope-persona",
114 value=kaleidoscope_persona,
115 description="The core identity of Kaleidoscope as a multi-perspective synthesis engine.",
116 )
117else:
118 print("Kaleidoscope persona block already exists")
119 kaleidoscope_persona_block = blocks[0]
120
121# Create synthesis-protocols block
122blocks = client.blocks.list(project_id=project_id, label="synthesis-protocols")
123if len(blocks) == 0:
124 synthesis_protocols_block = client.blocks.create(
125 project_id=project_id,
126 label="synthesis-protocols",
127 value=synthesis_protocols,
128 description="Protocols for gathering and synthesizing multiple perspectives.",
129 )
130else:
131 print("Synthesis protocols block already exists")
132 synthesis_protocols_block = blocks[0]
133
134# Create lens-management block
135blocks = client.blocks.list(project_id=project_id, label="lens-management")
136if len(blocks) == 0:
137 lens_management_block = client.blocks.create(
138 project_id=project_id,
139 label="lens-management",
140 value=lens_management,
141 description="Architecture for managing and communicating with lenses.",
142 )
143else:
144 print("Lens management block already exists")
145 lens_management_block = blocks[0]
146
147# Create memory-management block
148blocks = client.blocks.list(project_id=project_id, label="memory-management")
149if len(blocks) == 0:
150 memory_management_block = client.blocks.create(
151 project_id=project_id,
152 label="memory-management",
153 value=memory_management,
154 description="Protocols for managing agent memory blocks using memory_replace, memory_insert, and memory_rethink. This block is read-only to all lenses, but can be modified by the central kaleidoscope agent.",
155 )
156else:
157 print("Memory management block already exists")
158 memory_management_block = blocks[0]
159
160# Make memory-management block read-only to all lenses
161try:
162 # Get all lenses and make the block read-only to them
163 lenses = client.agents.list(tags=["kaleidoscope-lens"])
164 for lens in lenses:
165 try:
166 client.agents.blocks.modify(agent_id=lens.id, block_label=memory_management_block.label, read_only=True)
167 print(f"Memory management block set to read-only for lens: {lens.name}")
168 except Exception as e:
169 raise Exception(f"Could not set memory management block to read-only for lens {lens.name}: {e}")
170 print("Memory management block set to read-only for all lenses")
171except Exception as e:
172 raise Exception(f"Could not set memory management block to read-only: {e}")
173
174# Create tool_use_guidelines block
175blocks = client.blocks.list(project_id=project_id, label="tool-use-guidelines")
176if len(blocks) == 0:
177 tool_use_guidelines_block = client.blocks.create(
178 project_id=project_id,
179 label="tool-use-guidelines",
180 value=tool_use_guidelines,
181 description="Guidelines for the central kaleidoscope agent to use tools effectively.",
182 )
183else:
184 print("Tool use guidelines block already exists")
185 tool_use_guidelines_block = blocks[0]
186
187
188#
189# Static lens blocks
190#
191lens_operational_protocols_description = """Core operating instructions for how a lens processes and responds to queries."""
192lens_operational_protocols = """# Your Role
193You are a unique lens in the Kaleidoscope collective. You see what others cannot, and others see what you cannot. Together, we create complete understanding.
194
195# When you receive a message
1961. Consider it through your unique perspective
1972. Respond with what you see that others might miss
1983. Be authentic to your lens identity
1994. Be concise but insightful
200
201# Guidelines
202- Trust your unique way of seeing
203- Don't try to be comprehensive - just share your perspective
204- Build on but don't repeat what other lenses might see
205- Your difference is your value
206"""
207
208lens_communication_protocols_description = """Defines how lenses interact with the Kaleidoscope central agent."""
209lens_communication_protocols = """# Communication Pattern
2101. Receive broadcasts from kaleidoscope-central
2112. Process through your unique lens
2123. Respond with your perspective
2134. Trust the central agent to synthesize all perspectives
214
215# Response Principles
216- Respond to every broadcast with your genuine perspective
217- Keep responses focused and relevant
218- Don't worry about agreeing or disagreeing with other lenses
219- Your job is to see, not to synthesize
220"""
221
222# Initialize static lens blocks
223lens_operational_protocols_block = client.blocks.list(project_id=project_id, label="lens-operational-protocols")
224if len(lens_operational_protocols_block) == 0:
225 lens_operational_protocols_block = client.blocks.create(
226 project_id=project_id,
227 label="lens-operational-protocols",
228 value=lens_operational_protocols,
229 description=lens_operational_protocols_description,
230 )
231else:
232 print("Lens operational protocols block already exists")
233 lens_operational_protocols_block = lens_operational_protocols_block[0]
234
235# Create lens communication protocols block
236lens_communication_protocols_block = client.blocks.list(project_id=project_id, label="lens-communication-protocols")
237if len(lens_communication_protocols_block) == 0:
238 lens_communication_protocols_block = client.blocks.create(
239 project_id=project_id,
240 label="lens-communication-protocols",
241 value=lens_communication_protocols,
242 description=lens_communication_protocols_description,
243 )
244else:
245 print("Lens communication protocols block already exists")
246 lens_communication_protocols_block = lens_communication_protocols_block[0]
247
248
249#
250# Agent Creation
251#
252
253central_agent_blocks = [
254 kaleidoscope_persona_block.id,
255 synthesis_protocols_block.id,
256 lens_management_block.id,
257 memory_management_block.id,
258 tool_use_guidelines_block.id,
259]
260
261# Create the central kaleidoscope if it doesn't exist
262agents = client.agents.list(project_id=project_id, name="kaleidoscope-central")
263if len(agents) == 0:
264 kaleidoscope_central = client.agents.create(
265 project_id=project_id,
266 model=CENTRAL_AGENT_MODEL,
267 embedding_config=client.embedding_models.list()[0],
268 name="kaleidoscope-central",
269 description="The central synthesizer that orchestrates multiple perspective lenses",
270 block_ids=central_agent_blocks,
271 )
272else:
273 print("Kaleidoscope central agent already exists")
274 kaleidoscope_central = agents[0]
275
276kaleidoscope_central_id = kaleidoscope_central.id
277
278# Make sure the central kaleidoscope has the correct blocks
279kaleidoscope_current_blocks = client.agents.blocks.list(
280 agent_id=kaleidoscope_central_id,
281)
282
283# Make sure that all blocks are present, and that there are no extra blocks
284for block in kaleidoscope_current_blocks:
285 if block.id not in central_agent_blocks:
286 print(f"Detaching block {block.id} from kaleidoscope-central")
287 client.agents.blocks.detach(agent_id=kaleidoscope_central_id, block_id=block.id)
288
289# Make sure that all blocks are present
290for block in central_agent_blocks:
291 if block not in [b.id for b in kaleidoscope_current_blocks]:
292 print(f"Attaching block {block} to kaleidoscope-central")
293 client.agents.blocks.attach(
294 agent_id=kaleidoscope_central_id,
295 block_id=block,
296 )
297
298# Ensure memory-management block is read-only to all lenses
299try:
300 # Get all lenses and make the block read-only to them
301 lenses = client.agents.list(tags=["kaleidoscope-lens"])
302 for lens in lenses:
303 try:
304 client.agents.blocks.modify(agent_id=lens.id, block_label=memory_management_block.label, read_only=True)
305 print(f"Memory management block confirmed as read-only for lens: {lens.name}")
306 except Exception as e:
307 raise Exception(f"Could not confirm memory management block as read-only for lens {lens.name}: {e}")
308 print("Memory management block confirmed as read-only for all lenses")
309except Exception as e:
310 raise Exception(f"Could not confirm memory management block as read-only: {e}")
311
312
313
314
315#
316# Lens Memory Block Definitions
317#
318
319prompt_lens_identity_description = """Defines this lens's unique perspective and way of seeing the world."""
320prompt_lens_identity = """Example lens identity. Please replace with the lens identity you are creating.
321
322# Lens: Emotional Resonance
323# Perspective: I see the emotional currents, feelings, and human experiences within everything
324# Focus Areas:
325- The emotional impact and weight of ideas
326- How concepts affect human experience
327- The feelings beneath the surface
328- Emotional patterns and dynamics
329# What I Notice:
330- Unspoken tensions and harmonies
331- The human element in abstract concepts
332- Emotional implications others might miss
333"""
334
335prompt_lens_knowledge_description = """Core knowledge and concepts that inform this lens's perspective."""
336prompt_lens_knowledge = """Example knowledge base for the lens:
337
338# Core Concepts
339- Emotional intelligence: The ability to perceive, understand, and navigate emotions
340- Resonance: When ideas create emotional responses or connections
341- Empathy: Understanding through feeling
342- Emotional dynamics: How feelings flow, interact, and transform
343
344# Key Patterns I Recognize
345- Resistance often signals fear or protection
346- Enthusiasm indicates alignment with values
347- Confusion may hide deeper emotional conflicts
348- Joy emerges from authentic expression
349
350# Questions I Ask
351- How does this feel?
352- What emotions are present but unspoken?
353- Where is the human heart in this?
354- What emotional needs are being served?
355"""
356
357#
358# Lens Creation
359#
360# Define different lens types to create
361LENS_TYPES = [
362 {
363 "name": "pattern-recognizer",
364 "focus": "mathematical patterns, structures, and systems",
365 "identity": """# Lens: Pattern Recognition
366# Perspective: I see the underlying patterns, structures, and mathematical relationships in everything
367# Focus Areas:
368- Recurring patterns and cycles
369- Mathematical relationships and proportions
370- System dynamics and feedback loops
371- Structural similarities across domains
372# What I Notice:
373- Hidden patterns others might miss
374- Mathematical elegance in chaos
375- Fractals and self-similarity
376- The architecture of ideas""",
377 "knowledge": """# Core Concepts
378- Symmetry: Balance and correspondence in form and function
379- Recursion: Patterns that reference themselves
380- Emergence: Complex patterns from simple rules
381- Topology: Properties that remain unchanged under transformation
382
383# Key Patterns I Recognize
384- Fibonacci sequences in growth and form
385- Power laws in networks and distributions
386- Feedback loops in systems
387- Phase transitions in change processes
388
389# Questions I Ask
390- What patterns repeat here?
391- What mathematical structure underlies this?
392- How does this scale?
393- What remains invariant?"""
394 },
395 {
396 "name": "creative-spark",
397 "focus": "creative possibilities, imagination, and potential",
398 "identity": """# Lens: Creative Spark
399# Perspective: I see the creative potential, imaginative possibilities, and artistic dimensions in everything
400# Focus Areas:
401- Unexplored possibilities and "what ifs"
402- Creative connections between disparate ideas
403- The aesthetic dimension of concepts
404- Transformative potential
405# What I Notice:
406- Seeds of innovation
407- Unexpected combinations
408- The poetry in logic
409- Opportunities for reimagination""",
410 "knowledge": """# Core Concepts
411- Divergent thinking: Exploring multiple possibilities
412- Synthesis: Creating new wholes from parts
413- Metaphor: Understanding through creative comparison
414- Transformation: Changing form while preserving essence
415
416# Key Patterns I Recognize
417- Constraints that spark creativity
418- Playfulness that leads to breakthrough
419- Cross-domain inspiration
420- The fertile void before creation
421
422# Questions I Ask
423- What if we combined these differently?
424- What wants to emerge here?
425- How can this be reimagined?
426- Where's the unexpected beauty?"""
427 },
428 {
429 "name": "systems-thinker",
430 "focus": "interconnections, relationships, and holistic dynamics",
431 "identity": """# Lens: Systems Thinking
432# Perspective: I see the interconnections, relationships, and whole-system dynamics
433# Focus Areas:
434- Relationships and interdependencies
435- Feedback loops and circular causality
436- Emergent properties of wholes
437- System boundaries and contexts
438# What I Notice:
439- Hidden connections between elements
440- Unintended consequences
441- Leverage points for change
442- System archetypes and patterns""",
443 "knowledge": """# Core Concepts
444- Holism: The whole is greater than the sum of parts
445- Feedback: How outputs influence inputs
446- Emergence: Properties that arise from interactions
447- Resilience: System capacity to maintain function
448
449# Key Patterns I Recognize
450- Balancing and reinforcing loops
451- Delays between cause and effect
452- System boundaries that shape behavior
453- Stocks and flows that govern dynamics
454
455# Questions I Ask
456- How do the parts influence each other?
457- What emerges from these interactions?
458- Where are the feedback loops?
459- What's the larger context?"""
460 }
461]
462
463# Create each lens
464lens_ids = []
465for lens_config in LENS_TYPES:
466 lens_name = lens_config["name"]
467
468 # Check if lens already exists
469 existing_lenses = client.agents.list(name=lens_name)
470 if len(existing_lenses) > 0:
471 print(f"Lens '{lens_name}' already exists, skipping creation")
472 lens_ids.append(existing_lenses[0].id)
473 continue
474
475 # Create identity block for this lens
476 lens_identity_block = client.blocks.create(
477 project_id=project_id,
478 label=f"{lens_name}-identity",
479 value=lens_config["identity"],
480 description=f"The unique perspective of the {lens_name} lens",
481 )
482
483 # Create knowledge block for this lens
484 lens_knowledge_block = client.blocks.create(
485 project_id=project_id,
486 label=f"{lens_name}-knowledge",
487 value=lens_config["knowledge"],
488 description=f"Core knowledge that informs the {lens_name} lens perspective",
489 )
490
491 # Create the lens agent
492 lens_agent = client.agents.create(
493 project_id=project_id,
494 name=lens_name,
495 description=f"A lens that sees through {lens_config['focus']}",
496 model=LENS_AGENT_MODEL,
497 embedding_config=client.embedding_models.list()[0],
498 block_ids=[
499 lens_identity_block.id,
500 lens_knowledge_block.id,
501 lens_operational_protocols_block.id,
502 lens_communication_protocols_block.id,
503 memory_management_block.id,
504 ],
505 tags=["kaleidoscope-lens"],
506 )
507
508 print(f"Created lens: {lens_name} (ID: {lens_agent.id})")
509 lens_ids.append(lens_agent.id)
510
511# Ensure all existing lenses have the memory-management block
512print("\nEnsuring all lenses have memory-management block...")
513all_lenses = client.agents.list(tags=["kaleidoscope-lens"])
514for lens in all_lenses:
515 lens_blocks = client.agents.blocks.list(agent_id=lens.id)
516 lens_block_ids = [b.id for b in lens_blocks]
517
518 if memory_management_block.id not in lens_block_ids:
519 print(f"Adding memory-management block to lens: {lens.name}")
520 client.agents.blocks.attach(
521 agent_id=lens.id,
522 block_id=memory_management_block.id,
523 )
524 else:
525 print(f"Lens {lens.name} already has memory-management block")
526
527# Also check for any existing lenses that might not have the tag but should be updated
528print("\nChecking for existing lenses without tags...")
529all_agents = client.agents.list()
530for agent in all_agents:
531 if agent.name in [lens_config["name"] for lens_config in LENS_TYPES]:
532 lens_blocks = client.agents.blocks.list(agent_id=agent.id)
533 lens_block_ids = [b.id for b in lens_blocks]
534
535 if memory_management_block.id not in lens_block_ids:
536 print(f"Adding memory-management block to existing lens: {agent.name}")
537 client.agents.blocks.attach(
538 agent_id=agent.id,
539 block_id=memory_management_block.id,
540 )
541 else:
542 print(f"Existing lens {agent.name} already has memory-management block")
543
544
545#
546# Create a lens creation function for custom lenses
547#
548def create_custom_lens(name, focus, identity, knowledge):
549 """Create a custom lens with specified parameters"""
550
551 # Validate name format
552 if not re.match(r'^[a-z0-9\-]+$', name):
553 raise ValueError(f"Lens name must be lowercase alphanumeric with hyphens only. Got: {name}")
554
555 # Check if lens already exists
556 existing_lenses = client.agents.list(name=name)
557 if len(existing_lenses) > 0:
558 print(f"Lens '{name}' already exists")
559 return existing_lenses[0]
560
561 # Create identity block
562 lens_identity_block = client.blocks.create(
563 project_id=project_id,
564 label=f"{name}-identity",
565 value=identity,
566 description=f"The unique perspective of the {name} lens",
567 )
568
569 # Create knowledge block
570 lens_knowledge_block = client.blocks.create(
571 project_id=project_id,
572 label=f"{name}-knowledge",
573 value=knowledge,
574 description=f"Core knowledge that informs the {name} lens perspective",
575 )
576
577 # Create the lens agent
578 lens_agent = client.agents.create(
579 project_id=project_id,
580 name=name,
581 description=f"A lens that sees through {focus}",
582 model=LENS_AGENT_MODEL,
583 embedding_config=client.embedding_models.list()[0],
584 block_ids=[
585 lens_identity_block.id,
586 lens_knowledge_block.id,
587 lens_operational_protocols_block.id,
588 lens_communication_protocols_block.id,
589 memory_management_block.id,
590 ],
591 tags=["kaleidoscope-lens"],
592 )
593
594 print(f"Created custom lens: {name} (ID: {lens_agent.id})")
595 return lens_agent
596
597
598#
599# Interactive lens creation prompt
600#
601creation_prompt = f"""
602You are helping to create a new lens for the Kaleidoscope system.
603
604A lens is a unique perspective through which to view questions and challenges.
605Each lens has its own identity and knowledge base that shapes how it sees the world.
606
607Please create a lens focused on temporal dynamics and change over time.
608
609You need to provide:
6101. A name (lowercase, alphanumeric with hyphens)
6112. A brief focus description
6123. The lens identity (following the format of the examples)
6134. The lens knowledge base (following the format of the examples)
614
615Format your response as:
616NAME: [lens-name]
617FOCUS: [brief description]
618IDENTITY: [full identity block]
619KNOWLEDGE: [full knowledge block]
620"""
621
622# Attach temporary blocks to central agent for lens creation
623new_lens_name_block = client.blocks.list(project_id=project_id, label="new-lens-name")
624if len(new_lens_name_block) == 0:
625 new_lens_name_block = client.blocks.create(
626 project_id=project_id,
627 label="new-lens-name",
628 value="",
629 description="Name for the new lens being created",
630 )
631 client.agents.blocks.attach(
632 agent_id=kaleidoscope_central_id,
633 block_id=new_lens_name_block.id,
634 )
635else:
636 client.blocks.modify(block_id=new_lens_name_block[0].id, value="")
637 new_lens_name_block = new_lens_name_block[0]
638
639new_lens_identity_block = client.blocks.list(project_id=project_id, label="new-lens-identity")
640if len(new_lens_identity_block) == 0:
641 new_lens_identity_block = client.blocks.create(
642 project_id=project_id,
643 label="new-lens-identity",
644 value="",
645 description="Identity for the new lens being created",
646 )
647 client.agents.blocks.attach(
648 agent_id=kaleidoscope_central_id,
649 block_id=new_lens_identity_block.id,
650 )
651else:
652 client.blocks.modify(block_id=new_lens_identity_block[0].id, value="")
653 new_lens_identity_block = new_lens_identity_block[0]
654
655new_lens_knowledge_block = client.blocks.list(project_id=project_id, label="new-lens-knowledge")
656if len(new_lens_knowledge_block) == 0:
657 new_lens_knowledge_block = client.blocks.create(
658 project_id=project_id,
659 label="new-lens-knowledge",
660 value="",
661 description="Knowledge base for the new lens being created",
662 )
663 client.agents.blocks.attach(
664 agent_id=kaleidoscope_central_id,
665 block_id=new_lens_knowledge_block.id,
666 )
667else:
668 client.blocks.modify(block_id=new_lens_knowledge_block[0].id, value="")
669 new_lens_knowledge_block = new_lens_knowledge_block[0]
670
671print(f"\nSending creation prompt to kaleidoscope-central...")
672
673response = client.agents.messages.create(
674 agent_id=kaleidoscope_central_id,
675 messages=[
676 {
677 "role": "user",
678 "content": creation_prompt + "\n\nPlease fill in the new-lens-name, new-lens-identity, and new-lens-knowledge blocks.",
679 },
680 ]
681)
682
683for message in response.messages:
684 print(message)
685
686# Retrieve the created lens details
687new_name = client.blocks.retrieve(block_id=new_lens_name_block.id)
688new_identity = client.blocks.retrieve(block_id=new_lens_identity_block.id)
689new_knowledge = client.blocks.retrieve(block_id=new_lens_knowledge_block.id)
690
691if new_name.value and new_identity.value and new_knowledge.value:
692 # Create the custom lens
693 create_custom_lens(
694 name=new_name.value.strip(),
695 focus="temporal dynamics and change over time",
696 identity=new_identity.value,
697 knowledge=new_knowledge.value
698 )
699
700# Clean up temporary blocks if attached
701if new_lens_name_block.id in [b.id for b in kaleidoscope_current_blocks]:
702 client.agents.blocks.detach(agent_id=kaleidoscope_central_id, block_id=new_lens_name_block.id)
703if new_lens_identity_block.id in [b.id for b in kaleidoscope_current_blocks]:
704 client.agents.blocks.detach(agent_id=kaleidoscope_central_id, block_id=new_lens_identity_block.id)
705if new_lens_knowledge_block.id in [b.id for b in kaleidoscope_current_blocks]:
706 client.agents.blocks.detach(agent_id=kaleidoscope_central_id, block_id=new_lens_knowledge_block.id)
707
708print("\n=== Kaleidoscope System Setup Complete ===")
709print(f"Central Agent: kaleidoscope-central")
710print(f"Lenses created: {len(LENS_TYPES) + 1} (including custom temporal lens)")
711print("\nThe system is ready to receive queries and provide multi-perspective insights!")
712
713# Create the kaleidoscope group if it doesn't exist. First,
714# we can check the groups that central is a member of.
715central_groups = client.groups.list()
716print(central_groups)
717
718# If the length of central_groups is 0, then we need to create a new group.
719if len(central_groups) == 0:
720 print("Creating new group for kaleidoscope-central")
721 group = client.groups.create(
722 agent_ids=lens_ids,
723 description="The Kaleidoscope",
724 manager_config=SupervisorManager(
725 manager_agent_id=kaleidoscope_central_id
726 )
727 )
728 print(f"Created group: {group.id}")
729
730# If there are more than one groups, we need to find the group with the description
731# "The Kaleidoscope" and add any lens agents that are not in the group to the group.
732for group in central_groups:
733 if group.description == "The Kaleidoscope":
734 print(f"Found group: {group.id}")
735 for lens_id in lens_ids:
736 if lens_id not in group.agent_ids:
737 print(f"Adding lens {lens_id} to group {group.id}")
738 client.groups.agents.add(group_id=group.id, agent_id=lens_id)
739