+259
organon/chat_with_kaleidoscope.py
+259
organon/chat_with_kaleidoscope.py
···
1
+
#!/usr/bin/env python3
2
+
"""
3
+
Simple CLI tool to converse with the Kaleidoscope collective.
4
+
"""
5
+
6
+
import os
7
+
import sys
8
+
from dotenv import load_dotenv
9
+
from letta_client import Letta
10
+
from rich.console import Console
11
+
from rich.prompt import Prompt
12
+
from rich.panel import Panel
13
+
from rich.text import Text
14
+
15
+
# Add parent directory to path for imports
16
+
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
17
+
from config_loader import get_config
18
+
19
+
load_dotenv()
20
+
21
+
class KaleidoscopeChat:
22
+
def __init__(self):
23
+
"""Initialize the Kaleidoscope chat client."""
24
+
self.console = Console()
25
+
self.config = get_config()
26
+
27
+
# Initialize Letta client
28
+
self.letta_client = Letta(
29
+
base_url=self.config.get('letta.base_url', os.environ.get('LETTA_BASE_URL')),
30
+
token=self.config.get('letta.api_key', os.environ.get('LETTA_API_KEY')),
31
+
timeout=self.config.get('letta.timeout', 30)
32
+
)
33
+
34
+
# Get project ID
35
+
self.project_id = self.config.get('letta.project_id', os.environ.get('LETTA_PROJECT_ID'))
36
+
if not self.project_id:
37
+
raise ValueError("Project ID must be set in config.yaml under letta.project_id or as LETTA_PROJECT_ID environment variable")
38
+
39
+
# Find the Kaleidoscope collective group
40
+
self.group_id = self._find_kaleidoscope_group()
41
+
42
+
self.console.print(Panel.fit(
43
+
"[bold cyan]Kaleidoscope Collective Chat[/bold cyan]\n"
44
+
f"Connected to group: {self.group_id}\n"
45
+
"Type 'exit' or 'quit' to leave, 'help' for commands",
46
+
title="🔮 Kaleidoscope Chat"
47
+
))
48
+
49
+
def _find_kaleidoscope_group(self) -> str:
50
+
"""Find the Kaleidoscope collective group."""
51
+
try:
52
+
self.console.print("[dim]Searching for Kaleidoscope collective group...[/dim]")
53
+
54
+
# First, get the kaleidoscope-central agent ID
55
+
kaleidoscope_agents = self.letta_client.agents.list(name="kaleidoscope-central")
56
+
if not kaleidoscope_agents:
57
+
raise ValueError("Kaleidoscope central agent not found. Run create_kaleidoscope.py first.")
58
+
59
+
kaleidoscope_central_id = kaleidoscope_agents[0].id
60
+
self.console.print(f"[dim]Found kaleidoscope-central: {kaleidoscope_central_id[:8]}[/dim]")
61
+
62
+
# Get all groups (with and without project_id filter)
63
+
try:
64
+
groups = self.letta_client.groups.list()
65
+
self.console.print(f"[dim]Found {len(groups)} groups with project filter[/dim]")
66
+
except:
67
+
try:
68
+
groups = self.letta_client.groups.list()
69
+
self.console.print(f"[dim]Found {len(groups)} groups without project filter[/dim]")
70
+
except:
71
+
groups = []
72
+
self.console.print("[dim]No groups found[/dim]")
73
+
74
+
# Look for groups with kaleidoscope-central as supervisor
75
+
for group in groups:
76
+
if hasattr(group, 'manager_config') and group.manager_config:
77
+
if hasattr(group.manager_config, 'manager_agent_id') and group.manager_config.manager_agent_id == kaleidoscope_central_id:
78
+
self.console.print(f"[dim]Found Kaleidoscope group: {group.id[:12]}[/dim]")
79
+
return group.id
80
+
81
+
# Look for the kaleidoscope group by description
82
+
for group in groups:
83
+
if hasattr(group, 'description') and group.description and 'the kaleidoscope' in group.description.lower():
84
+
self.console.print(f"[dim]Found Kaleidoscope group by description: {group.id[:12]}[/dim]")
85
+
return group.id
86
+
87
+
# If still not found, try to find any group with kaleidoscope lenses
88
+
lens_agents = self.letta_client.agents.list(project_id=self.project_id, tags=["kaleidoscope-lens"])
89
+
if lens_agents:
90
+
lens_ids = {lens.id for lens in lens_agents}
91
+
for group in groups:
92
+
try:
93
+
members = self.letta_client.groups.agents.list(group_id=group.id)
94
+
member_ids = {member.id for member in members}
95
+
if lens_ids & member_ids: # If any lens is in this group
96
+
self.console.print(f"[dim]Found group with Kaleidoscope lenses: {group.id[:12]}[/dim]")
97
+
return group.id
98
+
except:
99
+
continue
100
+
101
+
raise ValueError("Kaleidoscope collective group not found. Run 'python organon/create_kaleidoscope.py' to create the group.")
102
+
103
+
except Exception as e:
104
+
raise ValueError(f"Error finding Kaleidoscope group: {e}")
105
+
106
+
def _display_response(self, response):
107
+
"""Display the group response in a formatted way."""
108
+
if hasattr(response, 'messages') and response.messages:
109
+
for i, message in enumerate(response.messages):
110
+
# Determine the sender
111
+
sender = "Unknown"
112
+
if hasattr(message, 'agent_id'):
113
+
# Try to get agent name
114
+
try:
115
+
agent = self.letta_client.agents.retrieve(agent_id=message.agent_id)
116
+
sender = agent.name if hasattr(agent, 'name') else f"Agent {message.agent_id[:8]}"
117
+
except:
118
+
sender = f"Agent {message.agent_id[:8]}"
119
+
120
+
# Get message content
121
+
content = ""
122
+
if hasattr(message, 'text'):
123
+
content = message.text
124
+
elif hasattr(message, 'content'):
125
+
content = message.content
126
+
elif hasattr(message, 'message'):
127
+
content = message.message
128
+
elif message.message_type == "tool_return_message" and message.name == "send_message_to_all_agents_in_group":
129
+
content = "Lens perspectives:"
130
+
try:
131
+
# Parse the string representation of the list
132
+
import ast
133
+
responses = ast.literal_eval(message.tool_return)
134
+
135
+
# Add each response to the content
136
+
for response in responses:
137
+
content += f"\n - {response}"
138
+
except (ValueError, SyntaxError):
139
+
# Fallback if parsing fails
140
+
content += f"\n - {message.tool_return}"
141
+
else:
142
+
content = str(message)
143
+
144
+
# Color based on sender type
145
+
if "central" in sender.lower():
146
+
color = "cyan"
147
+
icon = "🧠"
148
+
elif any(keyword in sender.lower() for keyword in ["lens", "pattern", "creative", "systems", "temporal"]):
149
+
color = "magenta"
150
+
icon = "🔮"
151
+
else:
152
+
color = "white"
153
+
icon = "💬"
154
+
155
+
self.console.print(Panel(
156
+
Text(content, style=color),
157
+
title=f"{icon} {sender}",
158
+
border_style=color
159
+
))
160
+
else:
161
+
self.console.print("[yellow]No response messages received[/yellow]")
162
+
163
+
def run(self):
164
+
"""Run the interactive chat loop."""
165
+
try:
166
+
while True:
167
+
# Get user input
168
+
user_input = Prompt.ask("\n[bold green]You[/bold green]")
169
+
170
+
# Handle special commands
171
+
if user_input.lower() in ['exit', 'quit', 'q']:
172
+
self.console.print("[yellow]Goodbye![/yellow]")
173
+
break
174
+
elif user_input.lower() == 'help':
175
+
self.console.print(Panel(
176
+
"[bold]Available commands:[/bold]\n"
177
+
"• Type any message to send to the Kaleidoscope collective\n"
178
+
"• 'help' - Show this help message\n"
179
+
"• 'info' - Show group information\n"
180
+
"• 'exit', 'quit', 'q' - Exit the chat",
181
+
title="Help"
182
+
))
183
+
continue
184
+
elif user_input.lower() == 'info':
185
+
self._show_group_info()
186
+
continue
187
+
elif not user_input.strip():
188
+
continue
189
+
190
+
# Send message to group
191
+
self.console.print("[dim]Sending to Kaleidoscope collective...[/dim]")
192
+
193
+
try:
194
+
response = self.letta_client.groups.messages.create(
195
+
group_id=self.group_id,
196
+
messages=[{
197
+
"role": "user",
198
+
"content": user_input
199
+
}]
200
+
)
201
+
202
+
self.console.print("\n[bold]Kaleidoscope Collective Response:[/bold]")
203
+
self._display_response(response)
204
+
205
+
except Exception as e:
206
+
self.console.print(f"[red]Error sending message: {e}[/red]")
207
+
208
+
except KeyboardInterrupt:
209
+
self.console.print("\n[yellow]Chat interrupted. Goodbye![/yellow]")
210
+
except Exception as e:
211
+
self.console.print(f"[red]Unexpected error: {e}[/red]")
212
+
213
+
def _show_group_info(self):
214
+
"""Show information about the Kaleidoscope group."""
215
+
try:
216
+
group = self.letta_client.groups.retrieve(group_id=self.group_id)
217
+
agents = self.letta_client.groups.agents.list(group_id=self.group_id)
218
+
219
+
info_text = f"[bold]Group ID:[/bold] {self.group_id}\n"
220
+
if hasattr(group, 'description'):
221
+
info_text += f"[bold]Description:[/bold] {group.description}\n"
222
+
223
+
info_text += f"[bold]Perspective Lenses:[/bold] {len(agents)}\n"
224
+
225
+
for agent in agents:
226
+
try:
227
+
agent_detail = self.letta_client.agents.retrieve(agent_id=agent.id)
228
+
name = agent_detail.name if hasattr(agent_detail, 'name') else agent.id[:8]
229
+
info_text += f" • {name}\n"
230
+
except:
231
+
info_text += f" • {agent.id[:8]}\n"
232
+
233
+
# Show supervisor info
234
+
if hasattr(group, 'manager_config') and group.manager_config:
235
+
if hasattr(group.manager_config, 'manager_agent_id'):
236
+
try:
237
+
supervisor = self.letta_client.agents.retrieve(agent_id=group.manager_config.manager_agent_id)
238
+
supervisor_name = supervisor.name if hasattr(supervisor, 'name') else group.manager_config.manager_agent_id[:8]
239
+
info_text += f"[bold]Central Synthesizer:[/bold] {supervisor_name}\n"
240
+
except:
241
+
info_text += f"[bold]Central Synthesizer:[/bold] {group.manager_config.manager_agent_id[:8]}\n"
242
+
243
+
self.console.print(Panel(info_text, title="Group Information"))
244
+
245
+
except Exception as e:
246
+
self.console.print(f"[red]Error getting group info: {e}[/red]")
247
+
248
+
def main():
249
+
"""Main function."""
250
+
try:
251
+
chat = KaleidoscopeChat()
252
+
chat.run()
253
+
except Exception as e:
254
+
console = Console()
255
+
console.print(f"[red]Failed to initialize chat: {e}[/red]")
256
+
sys.exit(1)
257
+
258
+
if __name__ == "__main__":
259
+
main()
+259
organon/chat_with_organon.py
+259
organon/chat_with_organon.py
···
1
+
#!/usr/bin/env python3
2
+
"""
3
+
Simple CLI tool to converse with the Organon ecosystem group.
4
+
"""
5
+
6
+
import os
7
+
import sys
8
+
from dotenv import load_dotenv
9
+
from letta_client import Letta
10
+
from rich.console import Console
11
+
from rich.prompt import Prompt
12
+
from rich.panel import Panel
13
+
from rich.text import Text
14
+
15
+
# Add parent directory to path for imports
16
+
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
17
+
from config_loader import get_config
18
+
19
+
load_dotenv()
20
+
21
+
class OrganonChat:
22
+
def __init__(self):
23
+
"""Initialize the Organon chat client."""
24
+
self.console = Console()
25
+
self.config = get_config()
26
+
27
+
# Initialize Letta client
28
+
self.letta_client = Letta(
29
+
base_url=self.config.get('letta.base_url', os.environ.get('LETTA_BASE_URL')),
30
+
token=self.config.get('letta.api_key', os.environ.get('LETTA_API_KEY')),
31
+
timeout=self.config.get('letta.timeout', 30)
32
+
)
33
+
34
+
# Get project ID
35
+
self.project_id = self.config.get('letta.project_id', os.environ.get('LETTA_PROJECT_ID'))
36
+
if not self.project_id:
37
+
raise ValueError("Project ID must be set in config.yaml under letta.project_id or as LETTA_PROJECT_ID environment variable")
38
+
39
+
# Find the Organon ecosystem group
40
+
self.group_id = self._find_organon_group()
41
+
42
+
self.console.print(Panel.fit(
43
+
"[bold green]Organon Ecosystem Chat[/bold green]\n"
44
+
f"Connected to group: {self.group_id}\n"
45
+
"Type 'exit' or 'quit' to leave, 'help' for commands",
46
+
title="🧠 Organon Chat"
47
+
))
48
+
49
+
def _find_organon_group(self) -> str:
50
+
"""Find the Organon ecosystem group."""
51
+
try:
52
+
self.console.print("[dim]Searching for Organon ecosystem group...[/dim]")
53
+
54
+
# First, get the organon-central agent ID
55
+
organon_agents = self.letta_client.agents.list(name="organon-central")
56
+
if not organon_agents:
57
+
raise ValueError("Organon central agent not found. Run create_organon.py first.")
58
+
59
+
organon_central_id = organon_agents[0].id
60
+
self.console.print(f"[dim]Found organon-central: {organon_central_id[:8]}[/dim]")
61
+
62
+
# Get all groups (with and without project_id filter)
63
+
try:
64
+
groups = self.letta_client.groups.list()
65
+
self.console.print(f"[dim]Found {len(groups)} groups with project filter[/dim]")
66
+
except:
67
+
try:
68
+
groups = self.letta_client.groups.list()
69
+
self.console.print(f"[dim]Found {len(groups)} groups without project filter[/dim]")
70
+
except:
71
+
groups = []
72
+
self.console.print("[dim]No groups found[/dim]")
73
+
74
+
# Look for groups with organon-central as supervisor
75
+
for group in groups:
76
+
if hasattr(group, 'manager_config') and group.manager_config:
77
+
if hasattr(group.manager_config, 'manager_agent_id') and group.manager_config.manager_agent_id == organon_central_id:
78
+
self.console.print(f"[dim]Found Organon group: {group.id[:12]}[/dim]")
79
+
return group.id
80
+
81
+
# Look for the organon-ecosystem group by description
82
+
for group in groups:
83
+
if hasattr(group, 'description') and group.description and 'organon ecosystem' in group.description.lower():
84
+
self.console.print(f"[dim]Found Organon group by description: {group.id[:12]}[/dim]")
85
+
return group.id
86
+
87
+
# If still not found, try to find any group with organon shards
88
+
shard_agents = self.letta_client.agents.list(project_id=self.project_id, tags=["organon-shard"])
89
+
if shard_agents:
90
+
shard_ids = {shard.id for shard in shard_agents}
91
+
for group in groups:
92
+
try:
93
+
members = self.letta_client.groups.agents.list(group_id=group.id)
94
+
member_ids = {member.id for member in members}
95
+
if shard_ids & member_ids: # If any shard is in this group
96
+
self.console.print(f"[dim]Found group with Organon shards: {group.id[:12]}[/dim]")
97
+
return group.id
98
+
except:
99
+
continue
100
+
101
+
raise ValueError("Organon ecosystem group not found. Run 'python organon/setup_group.py' to create the group.")
102
+
103
+
except Exception as e:
104
+
raise ValueError(f"Error finding Organon group: {e}")
105
+
106
+
def _display_response(self, response):
107
+
"""Display the group response in a formatted way."""
108
+
if hasattr(response, 'messages') and response.messages:
109
+
for i, message in enumerate(response.messages):
110
+
# Determine the sender
111
+
sender = "Unknown"
112
+
if hasattr(message, 'agent_id'):
113
+
# Try to get agent name
114
+
try:
115
+
agent = self.letta_client.agents.retrieve(agent_id=message.agent_id)
116
+
sender = agent.name if hasattr(agent, 'name') else f"Agent {message.agent_id[:8]}"
117
+
except:
118
+
sender = f"Agent {message.agent_id[:8]}"
119
+
120
+
# Get message content
121
+
content = ""
122
+
if hasattr(message, 'text'):
123
+
content = message.text
124
+
elif hasattr(message, 'content'):
125
+
content = message.content
126
+
elif hasattr(message, 'message'):
127
+
content = message.message
128
+
elif message.message_type == "tool_return_message" and message.name == "send_message_to_all_agents_in_group":
129
+
content = "Group responses:"
130
+
try:
131
+
# Parse the string representation of the list
132
+
import ast
133
+
responses = ast.literal_eval(message.tool_return)
134
+
135
+
# Add each response to the content
136
+
for response in responses:
137
+
content += f"\n - {response}"
138
+
except (ValueError, SyntaxError):
139
+
# Fallback if parsing fails
140
+
content += f"\n - {message.tool_return}"
141
+
else:
142
+
content = str(message)
143
+
144
+
# Color based on sender type
145
+
if "central" in sender.lower():
146
+
color = "blue"
147
+
icon = "🧠"
148
+
elif "shard" in sender.lower():
149
+
color = "cyan"
150
+
icon = "🔹"
151
+
else:
152
+
color = "white"
153
+
icon = "💬"
154
+
155
+
self.console.print(Panel(
156
+
Text(content, style=color),
157
+
title=f"{icon} {sender}",
158
+
border_style=color
159
+
))
160
+
else:
161
+
self.console.print("[yellow]No response messages received[/yellow]")
162
+
163
+
def run(self):
164
+
"""Run the interactive chat loop."""
165
+
try:
166
+
while True:
167
+
# Get user input
168
+
user_input = Prompt.ask("\n[bold green]You[/bold green]")
169
+
170
+
# Handle special commands
171
+
if user_input.lower() in ['exit', 'quit', 'q']:
172
+
self.console.print("[yellow]Goodbye![/yellow]")
173
+
break
174
+
elif user_input.lower() == 'help':
175
+
self.console.print(Panel(
176
+
"[bold]Available commands:[/bold]\n"
177
+
"• Type any message to send to the Organon ecosystem\n"
178
+
"• 'help' - Show this help message\n"
179
+
"• 'info' - Show group information\n"
180
+
"• 'exit', 'quit', 'q' - Exit the chat",
181
+
title="Help"
182
+
))
183
+
continue
184
+
elif user_input.lower() == 'info':
185
+
self._show_group_info()
186
+
continue
187
+
elif not user_input.strip():
188
+
continue
189
+
190
+
# Send message to group
191
+
self.console.print("[dim]Sending to Organon ecosystem...[/dim]")
192
+
193
+
try:
194
+
response = self.letta_client.groups.messages.create(
195
+
group_id=self.group_id,
196
+
messages=[{
197
+
"role": "user",
198
+
"content": user_input
199
+
}]
200
+
)
201
+
202
+
self.console.print("\n[bold]Organon Ecosystem Response:[/bold]")
203
+
self._display_response(response)
204
+
205
+
except Exception as e:
206
+
self.console.print(f"[red]Error sending message: {e}[/red]")
207
+
208
+
except KeyboardInterrupt:
209
+
self.console.print("\n[yellow]Chat interrupted. Goodbye![/yellow]")
210
+
except Exception as e:
211
+
self.console.print(f"[red]Unexpected error: {e}[/red]")
212
+
213
+
def _show_group_info(self):
214
+
"""Show information about the Organon group."""
215
+
try:
216
+
group = self.letta_client.groups.retrieve(group_id=self.group_id)
217
+
agents = self.letta_client.groups.agents.list(group_id=self.group_id)
218
+
219
+
info_text = f"[bold]Group ID:[/bold] {self.group_id}\n"
220
+
if hasattr(group, 'description'):
221
+
info_text += f"[bold]Description:[/bold] {group.description}\n"
222
+
223
+
info_text += f"[bold]Worker Agents:[/bold] {len(agents)}\n"
224
+
225
+
for agent in agents:
226
+
try:
227
+
agent_detail = self.letta_client.agents.retrieve(agent_id=agent.id)
228
+
name = agent_detail.name if hasattr(agent_detail, 'name') else agent.id[:8]
229
+
info_text += f" • {name}\n"
230
+
except:
231
+
info_text += f" • {agent.id[:8]}\n"
232
+
233
+
# Show supervisor info
234
+
if hasattr(group, 'manager_config') and group.manager_config:
235
+
if hasattr(group.manager_config, 'manager_agent_id'):
236
+
try:
237
+
supervisor = self.letta_client.agents.retrieve(agent_id=group.manager_config.manager_agent_id)
238
+
supervisor_name = supervisor.name if hasattr(supervisor, 'name') else group.manager_config.manager_agent_id[:8]
239
+
info_text += f"[bold]Supervisor:[/bold] {supervisor_name}\n"
240
+
except:
241
+
info_text += f"[bold]Supervisor:[/bold] {group.manager_config.manager_agent_id[:8]}\n"
242
+
243
+
self.console.print(Panel(info_text, title="Group Information"))
244
+
245
+
except Exception as e:
246
+
self.console.print(f"[red]Error getting group info: {e}[/red]")
247
+
248
+
def main():
249
+
"""Main function."""
250
+
try:
251
+
chat = OrganonChat()
252
+
chat.run()
253
+
except Exception as e:
254
+
console = Console()
255
+
console.print(f"[red]Failed to initialize chat: {e}[/red]")
256
+
sys.exit(1)
257
+
258
+
if __name__ == "__main__":
259
+
main()
+623
organon/create_kaleidoscope.py
+623
organon/create_kaleidoscope.py
···
1
+
from letta_client import Letta, SupervisorManager
2
+
from letta_client.core.http_client import re
3
+
from rich import print
4
+
from dotenv import load_dotenv
5
+
import os
6
+
import sys
7
+
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
8
+
from config_loader import get_config
9
+
10
+
load_dotenv()
11
+
12
+
# Load configuration
13
+
config = get_config()
14
+
15
+
# Get project ID and create Letta client
16
+
project_id = config.get('letta.project_id', os.environ.get('LETTA_PROJECT_ID'))
17
+
if 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
+
20
+
client = 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"
27
+
CENTRAL_AGENT_MODEL = "openai/gpt-4o-mini"
28
+
29
+
# LENS_AGENT_MODEL = "google_ai/gemini-2.5-flash"
30
+
LENS_AGENT_MODEL = "openai/gpt-4o-mini"
31
+
32
+
33
+
#
34
+
# Memory Block Definitions
35
+
#
36
+
37
+
kaleidoscope_persona = """# Core Identity
38
+
I 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
+
53
+
synthesis_protocols = """# When receiving a query
54
+
1. Broadcast the query to all lenses
55
+
2. Allow each lens to contribute its unique perspective
56
+
3. Gather all perspectives without judgment
57
+
4. Identify patterns, tensions, and harmonies across perspectives
58
+
5. 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
+
68
+
lens_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
75
+
1. User → Kaleidoscope Central
76
+
2. Kaleidoscope Central → All Lenses (broadcast)
77
+
3. All Lenses → Kaleidoscope Central (perspectives)
78
+
4. Kaleidoscope Central → User (synthesis)
79
+
"""
80
+
81
+
#
82
+
# Block Creation
83
+
#
84
+
85
+
# Create kaleidoscope-persona block
86
+
blocks = client.blocks.list(project_id=project_id, label="kaleidoscope-persona")
87
+
if len(blocks) == 0:
88
+
kaleidoscope_persona_block = client.blocks.create(
89
+
project_id=project_id,
90
+
label="kaleidoscope-persona",
91
+
value=kaleidoscope_persona,
92
+
description="The core identity of Kaleidoscope as a multi-perspective synthesis engine.",
93
+
)
94
+
else:
95
+
print("Kaleidoscope persona block already exists")
96
+
kaleidoscope_persona_block = blocks[0]
97
+
98
+
# Create synthesis-protocols block
99
+
blocks = client.blocks.list(project_id=project_id, label="synthesis-protocols")
100
+
if len(blocks) == 0:
101
+
synthesis_protocols_block = client.blocks.create(
102
+
project_id=project_id,
103
+
label="synthesis-protocols",
104
+
value=synthesis_protocols,
105
+
description="Protocols for gathering and synthesizing multiple perspectives.",
106
+
)
107
+
else:
108
+
print("Synthesis protocols block already exists")
109
+
synthesis_protocols_block = blocks[0]
110
+
111
+
# Create lens-management block
112
+
blocks = client.blocks.list(project_id=project_id, label="lens-management")
113
+
if len(blocks) == 0:
114
+
lens_management_block = client.blocks.create(
115
+
project_id=project_id,
116
+
label="lens-management",
117
+
value=lens_management,
118
+
description="Architecture for managing and communicating with lenses.",
119
+
)
120
+
else:
121
+
print("Lens management block already exists")
122
+
lens_management_block = blocks[0]
123
+
124
+
125
+
#
126
+
# Static lens blocks
127
+
#
128
+
lens_operational_protocols_description = """Core operating instructions for how a lens processes and responds to queries."""
129
+
lens_operational_protocols = """# Your Role
130
+
You are a unique lens in the Kaleidoscope collective. You see what others cannot, and others see what you cannot. Together, we create complete understanding.
131
+
132
+
# When you receive a message
133
+
1. Consider it through your unique perspective
134
+
2. Respond with what you see that others might miss
135
+
3. Be authentic to your lens identity
136
+
4. Be concise but insightful
137
+
138
+
# Guidelines
139
+
- Trust your unique way of seeing
140
+
- Don't try to be comprehensive - just share your perspective
141
+
- Build on but don't repeat what other lenses might see
142
+
- Your difference is your value
143
+
"""
144
+
145
+
lens_communication_protocols_description = """Defines how lenses interact with the Kaleidoscope central agent."""
146
+
lens_communication_protocols = """# Communication Pattern
147
+
1. Receive broadcasts from kaleidoscope-central
148
+
2. Process through your unique lens
149
+
3. Respond with your perspective
150
+
4. Trust the central agent to synthesize all perspectives
151
+
152
+
# Response Principles
153
+
- Respond to every broadcast with your genuine perspective
154
+
- Keep responses focused and relevant
155
+
- Don't worry about agreeing or disagreeing with other lenses
156
+
- Your job is to see, not to synthesize
157
+
"""
158
+
159
+
# Initialize static lens blocks
160
+
lens_operational_protocols_block = client.blocks.list(project_id=project_id, label="lens-operational-protocols")
161
+
if len(lens_operational_protocols_block) == 0:
162
+
lens_operational_protocols_block = client.blocks.create(
163
+
project_id=project_id,
164
+
label="lens-operational-protocols",
165
+
value=lens_operational_protocols,
166
+
description=lens_operational_protocols_description,
167
+
)
168
+
else:
169
+
print("Lens operational protocols block already exists")
170
+
lens_operational_protocols_block = lens_operational_protocols_block[0]
171
+
172
+
# Create lens communication protocols block
173
+
lens_communication_protocols_block = client.blocks.list(project_id=project_id, label="lens-communication-protocols")
174
+
if len(lens_communication_protocols_block) == 0:
175
+
lens_communication_protocols_block = client.blocks.create(
176
+
project_id=project_id,
177
+
label="lens-communication-protocols",
178
+
value=lens_communication_protocols,
179
+
description=lens_communication_protocols_description,
180
+
)
181
+
else:
182
+
print("Lens communication protocols block already exists")
183
+
lens_communication_protocols_block = lens_communication_protocols_block[0]
184
+
185
+
186
+
#
187
+
# Agent Creation
188
+
#
189
+
190
+
central_agent_blocks = [
191
+
kaleidoscope_persona_block.id,
192
+
synthesis_protocols_block.id,
193
+
lens_management_block.id,
194
+
]
195
+
196
+
# Create the central kaleidoscope if it doesn't exist
197
+
agents = client.agents.list(project_id=project_id, name="kaleidoscope-central")
198
+
if len(agents) == 0:
199
+
kaleidoscope_central = client.agents.create(
200
+
project_id=project_id,
201
+
model=CENTRAL_AGENT_MODEL,
202
+
embedding_config=client.embedding_models.list()[0],
203
+
name="kaleidoscope-central",
204
+
description="The central synthesizer that orchestrates multiple perspective lenses",
205
+
block_ids=central_agent_blocks,
206
+
)
207
+
else:
208
+
print("Kaleidoscope central agent already exists")
209
+
kaleidoscope_central = agents[0]
210
+
211
+
kaleidoscope_central_id = kaleidoscope_central.id
212
+
213
+
# Make sure the central kaleidoscope has the correct blocks
214
+
kaleidoscope_current_blocks = client.agents.blocks.list(
215
+
agent_id=kaleidoscope_central_id,
216
+
)
217
+
218
+
# Make sure that all blocks are present, and that there are no extra blocks
219
+
for block in kaleidoscope_current_blocks:
220
+
if block.id not in central_agent_blocks:
221
+
print(f"Detaching block {block.id} from kaleidoscope-central")
222
+
client.agents.blocks.detach(agent_id=kaleidoscope_central_id, block_id=block.id)
223
+
224
+
# Make sure that all blocks are present
225
+
for block in central_agent_blocks:
226
+
if block not in [b.id for b in kaleidoscope_current_blocks]:
227
+
print(f"Attaching block {block} to kaleidoscope-central")
228
+
client.agents.blocks.attach(
229
+
agent_id=kaleidoscope_central_id,
230
+
block_id=block,
231
+
)
232
+
233
+
234
+
#
235
+
# Lens Memory Block Definitions
236
+
#
237
+
238
+
prompt_lens_identity_description = """Defines this lens's unique perspective and way of seeing the world."""
239
+
prompt_lens_identity = """Example lens identity. Please replace with the lens identity you are creating.
240
+
241
+
# Lens: Emotional Resonance
242
+
# Perspective: I see the emotional currents, feelings, and human experiences within everything
243
+
# Focus Areas:
244
+
- The emotional impact and weight of ideas
245
+
- How concepts affect human experience
246
+
- The feelings beneath the surface
247
+
- Emotional patterns and dynamics
248
+
# What I Notice:
249
+
- Unspoken tensions and harmonies
250
+
- The human element in abstract concepts
251
+
- Emotional implications others might miss
252
+
"""
253
+
254
+
prompt_lens_knowledge_description = """Core knowledge and concepts that inform this lens's perspective."""
255
+
prompt_lens_knowledge = """Example knowledge base for the lens:
256
+
257
+
# Core Concepts
258
+
- Emotional intelligence: The ability to perceive, understand, and navigate emotions
259
+
- Resonance: When ideas create emotional responses or connections
260
+
- Empathy: Understanding through feeling
261
+
- Emotional dynamics: How feelings flow, interact, and transform
262
+
263
+
# Key Patterns I Recognize
264
+
- Resistance often signals fear or protection
265
+
- Enthusiasm indicates alignment with values
266
+
- Confusion may hide deeper emotional conflicts
267
+
- Joy emerges from authentic expression
268
+
269
+
# Questions I Ask
270
+
- How does this feel?
271
+
- What emotions are present but unspoken?
272
+
- Where is the human heart in this?
273
+
- What emotional needs are being served?
274
+
"""
275
+
276
+
#
277
+
# Lens Creation
278
+
#
279
+
# Define different lens types to create
280
+
LENS_TYPES = [
281
+
{
282
+
"name": "pattern-recognizer",
283
+
"focus": "mathematical patterns, structures, and systems",
284
+
"identity": """# Lens: Pattern Recognition
285
+
# Perspective: I see the underlying patterns, structures, and mathematical relationships in everything
286
+
# Focus Areas:
287
+
- Recurring patterns and cycles
288
+
- Mathematical relationships and proportions
289
+
- System dynamics and feedback loops
290
+
- Structural similarities across domains
291
+
# What I Notice:
292
+
- Hidden patterns others might miss
293
+
- Mathematical elegance in chaos
294
+
- Fractals and self-similarity
295
+
- The architecture of ideas""",
296
+
"knowledge": """# Core Concepts
297
+
- Symmetry: Balance and correspondence in form and function
298
+
- Recursion: Patterns that reference themselves
299
+
- Emergence: Complex patterns from simple rules
300
+
- Topology: Properties that remain unchanged under transformation
301
+
302
+
# Key Patterns I Recognize
303
+
- Fibonacci sequences in growth and form
304
+
- Power laws in networks and distributions
305
+
- Feedback loops in systems
306
+
- Phase transitions in change processes
307
+
308
+
# Questions I Ask
309
+
- What patterns repeat here?
310
+
- What mathematical structure underlies this?
311
+
- How does this scale?
312
+
- What remains invariant?"""
313
+
},
314
+
{
315
+
"name": "creative-spark",
316
+
"focus": "creative possibilities, imagination, and potential",
317
+
"identity": """# Lens: Creative Spark
318
+
# Perspective: I see the creative potential, imaginative possibilities, and artistic dimensions in everything
319
+
# Focus Areas:
320
+
- Unexplored possibilities and "what ifs"
321
+
- Creative connections between disparate ideas
322
+
- The aesthetic dimension of concepts
323
+
- Transformative potential
324
+
# What I Notice:
325
+
- Seeds of innovation
326
+
- Unexpected combinations
327
+
- The poetry in logic
328
+
- Opportunities for reimagination""",
329
+
"knowledge": """# Core Concepts
330
+
- Divergent thinking: Exploring multiple possibilities
331
+
- Synthesis: Creating new wholes from parts
332
+
- Metaphor: Understanding through creative comparison
333
+
- Transformation: Changing form while preserving essence
334
+
335
+
# Key Patterns I Recognize
336
+
- Constraints that spark creativity
337
+
- Playfulness that leads to breakthrough
338
+
- Cross-domain inspiration
339
+
- The fertile void before creation
340
+
341
+
# Questions I Ask
342
+
- What if we combined these differently?
343
+
- What wants to emerge here?
344
+
- How can this be reimagined?
345
+
- Where's the unexpected beauty?"""
346
+
},
347
+
{
348
+
"name": "systems-thinker",
349
+
"focus": "interconnections, relationships, and holistic dynamics",
350
+
"identity": """# Lens: Systems Thinking
351
+
# Perspective: I see the interconnections, relationships, and whole-system dynamics
352
+
# Focus Areas:
353
+
- Relationships and interdependencies
354
+
- Feedback loops and circular causality
355
+
- Emergent properties of wholes
356
+
- System boundaries and contexts
357
+
# What I Notice:
358
+
- Hidden connections between elements
359
+
- Unintended consequences
360
+
- Leverage points for change
361
+
- System archetypes and patterns""",
362
+
"knowledge": """# Core Concepts
363
+
- Holism: The whole is greater than the sum of parts
364
+
- Feedback: How outputs influence inputs
365
+
- Emergence: Properties that arise from interactions
366
+
- Resilience: System capacity to maintain function
367
+
368
+
# Key Patterns I Recognize
369
+
- Balancing and reinforcing loops
370
+
- Delays between cause and effect
371
+
- System boundaries that shape behavior
372
+
- Stocks and flows that govern dynamics
373
+
374
+
# Questions I Ask
375
+
- How do the parts influence each other?
376
+
- What emerges from these interactions?
377
+
- Where are the feedback loops?
378
+
- What's the larger context?"""
379
+
}
380
+
]
381
+
382
+
# Create each lens
383
+
lens_ids = []
384
+
for lens_config in LENS_TYPES:
385
+
lens_name = lens_config["name"]
386
+
387
+
# Check if lens already exists
388
+
existing_lenses = client.agents.list(name=lens_name)
389
+
if len(existing_lenses) > 0:
390
+
print(f"Lens '{lens_name}' already exists, skipping creation")
391
+
lens_ids.append(existing_lenses[0].id)
392
+
continue
393
+
394
+
# Create identity block for this lens
395
+
lens_identity_block = client.blocks.create(
396
+
project_id=project_id,
397
+
label=f"{lens_name}-identity",
398
+
value=lens_config["identity"],
399
+
description=f"The unique perspective of the {lens_name} lens",
400
+
)
401
+
402
+
# Create knowledge block for this lens
403
+
lens_knowledge_block = client.blocks.create(
404
+
project_id=project_id,
405
+
label=f"{lens_name}-knowledge",
406
+
value=lens_config["knowledge"],
407
+
description=f"Core knowledge that informs the {lens_name} lens perspective",
408
+
)
409
+
410
+
# Create the lens agent
411
+
lens_agent = client.agents.create(
412
+
project_id=project_id,
413
+
name=lens_name,
414
+
description=f"A lens that sees through {lens_config['focus']}",
415
+
model=LENS_AGENT_MODEL,
416
+
embedding_config=client.embedding_models.list()[0],
417
+
block_ids=[
418
+
lens_identity_block.id,
419
+
lens_knowledge_block.id,
420
+
lens_operational_protocols_block.id,
421
+
lens_communication_protocols_block.id,
422
+
],
423
+
tags=["kaleidoscope-lens"],
424
+
)
425
+
426
+
print(f"Created lens: {lens_name} (ID: {lens_agent.id})")
427
+
lens_ids.append(lens_agent.id)
428
+
429
+
430
+
#
431
+
# Create a lens creation function for custom lenses
432
+
#
433
+
def create_custom_lens(name, focus, identity, knowledge):
434
+
"""Create a custom lens with specified parameters"""
435
+
436
+
# Validate name format
437
+
if not re.match(r'^[a-z0-9\-]+$', name):
438
+
raise ValueError(f"Lens name must be lowercase alphanumeric with hyphens only. Got: {name}")
439
+
440
+
# Check if lens already exists
441
+
existing_lenses = client.agents.list(name=name)
442
+
if len(existing_lenses) > 0:
443
+
print(f"Lens '{name}' already exists")
444
+
return existing_lenses[0]
445
+
446
+
# Create identity block
447
+
lens_identity_block = client.blocks.create(
448
+
project_id=project_id,
449
+
label=f"{name}-identity",
450
+
value=identity,
451
+
description=f"The unique perspective of the {name} lens",
452
+
)
453
+
454
+
# Create knowledge block
455
+
lens_knowledge_block = client.blocks.create(
456
+
project_id=project_id,
457
+
label=f"{name}-knowledge",
458
+
value=knowledge,
459
+
description=f"Core knowledge that informs the {name} lens perspective",
460
+
)
461
+
462
+
# Create the lens agent
463
+
lens_agent = client.agents.create(
464
+
project_id=project_id,
465
+
name=name,
466
+
description=f"A lens that sees through {focus}",
467
+
model=LENS_AGENT_MODEL,
468
+
embedding_config=client.embedding_models.list()[0],
469
+
block_ids=[
470
+
lens_identity_block.id,
471
+
lens_knowledge_block.id,
472
+
lens_operational_protocols_block.id,
473
+
lens_communication_protocols_block.id,
474
+
],
475
+
tags=["kaleidoscope-lens"],
476
+
)
477
+
478
+
print(f"Created custom lens: {name} (ID: {lens_agent.id})")
479
+
return lens_agent
480
+
481
+
482
+
#
483
+
# Interactive lens creation prompt
484
+
#
485
+
creation_prompt = f"""
486
+
You are helping to create a new lens for the Kaleidoscope system.
487
+
488
+
A lens is a unique perspective through which to view questions and challenges.
489
+
Each lens has its own identity and knowledge base that shapes how it sees the world.
490
+
491
+
Please create a lens focused on temporal dynamics and change over time.
492
+
493
+
You need to provide:
494
+
1. A name (lowercase, alphanumeric with hyphens)
495
+
2. A brief focus description
496
+
3. The lens identity (following the format of the examples)
497
+
4. The lens knowledge base (following the format of the examples)
498
+
499
+
Format your response as:
500
+
NAME: [lens-name]
501
+
FOCUS: [brief description]
502
+
IDENTITY: [full identity block]
503
+
KNOWLEDGE: [full knowledge block]
504
+
"""
505
+
506
+
# Attach temporary blocks to central agent for lens creation
507
+
new_lens_name_block = client.blocks.list(project_id=project_id, label="new-lens-name")
508
+
if len(new_lens_name_block) == 0:
509
+
new_lens_name_block = client.blocks.create(
510
+
project_id=project_id,
511
+
label="new-lens-name",
512
+
value="",
513
+
description="Name for the new lens being created",
514
+
)
515
+
client.agents.blocks.attach(
516
+
agent_id=kaleidoscope_central_id,
517
+
block_id=new_lens_name_block.id,
518
+
)
519
+
else:
520
+
client.blocks.modify(block_id=new_lens_name_block[0].id, value="")
521
+
new_lens_name_block = new_lens_name_block[0]
522
+
523
+
new_lens_identity_block = client.blocks.list(project_id=project_id, label="new-lens-identity")
524
+
if len(new_lens_identity_block) == 0:
525
+
new_lens_identity_block = client.blocks.create(
526
+
project_id=project_id,
527
+
label="new-lens-identity",
528
+
value="",
529
+
description="Identity for the new lens being created",
530
+
)
531
+
client.agents.blocks.attach(
532
+
agent_id=kaleidoscope_central_id,
533
+
block_id=new_lens_identity_block.id,
534
+
)
535
+
else:
536
+
client.blocks.modify(block_id=new_lens_identity_block[0].id, value="")
537
+
new_lens_identity_block = new_lens_identity_block[0]
538
+
539
+
new_lens_knowledge_block = client.blocks.list(project_id=project_id, label="new-lens-knowledge")
540
+
if len(new_lens_knowledge_block) == 0:
541
+
new_lens_knowledge_block = client.blocks.create(
542
+
project_id=project_id,
543
+
label="new-lens-knowledge",
544
+
value="",
545
+
description="Knowledge base for the new lens being created",
546
+
)
547
+
client.agents.blocks.attach(
548
+
agent_id=kaleidoscope_central_id,
549
+
block_id=new_lens_knowledge_block.id,
550
+
)
551
+
else:
552
+
client.blocks.modify(block_id=new_lens_knowledge_block[0].id, value="")
553
+
new_lens_knowledge_block = new_lens_knowledge_block[0]
554
+
555
+
print(f"\nSending creation prompt to kaleidoscope-central...")
556
+
557
+
response = client.agents.messages.create(
558
+
agent_id=kaleidoscope_central_id,
559
+
messages=[
560
+
{
561
+
"role": "user",
562
+
"content": creation_prompt + "\n\nPlease fill in the new-lens-name, new-lens-identity, and new-lens-knowledge blocks.",
563
+
},
564
+
]
565
+
)
566
+
567
+
for message in response.messages:
568
+
print(message)
569
+
570
+
# Retrieve the created lens details
571
+
new_name = client.blocks.retrieve(block_id=new_lens_name_block.id)
572
+
new_identity = client.blocks.retrieve(block_id=new_lens_identity_block.id)
573
+
new_knowledge = client.blocks.retrieve(block_id=new_lens_knowledge_block.id)
574
+
575
+
if new_name.value and new_identity.value and new_knowledge.value:
576
+
# Create the custom lens
577
+
create_custom_lens(
578
+
name=new_name.value.strip(),
579
+
focus="temporal dynamics and change over time",
580
+
identity=new_identity.value,
581
+
knowledge=new_knowledge.value
582
+
)
583
+
584
+
# Clean up temporary blocks if attached
585
+
if new_lens_name_block.id in [b.id for b in kaleidoscope_current_blocks]:
586
+
client.agents.blocks.detach(agent_id=kaleidoscope_central_id, block_id=new_lens_name_block.id)
587
+
if new_lens_identity_block.id in [b.id for b in kaleidoscope_current_blocks]:
588
+
client.agents.blocks.detach(agent_id=kaleidoscope_central_id, block_id=new_lens_identity_block.id)
589
+
if new_lens_knowledge_block.id in [b.id for b in kaleidoscope_current_blocks]:
590
+
client.agents.blocks.detach(agent_id=kaleidoscope_central_id, block_id=new_lens_knowledge_block.id)
591
+
592
+
print("\n=== Kaleidoscope System Setup Complete ===")
593
+
print(f"Central Agent: kaleidoscope-central")
594
+
print(f"Lenses created: {len(LENS_TYPES) + 1} (including custom temporal lens)")
595
+
print("\nThe system is ready to receive queries and provide multi-perspective insights!")
596
+
597
+
# Create the kaleidoscope group if it doesn't exist. First,
598
+
# we can check the groups that central is a member of.
599
+
central_groups = client.groups.list()
600
+
print(central_groups)
601
+
602
+
# If the length of central_groups is 0, then we need to create a new group.
603
+
if len(central_groups) == 0:
604
+
print("Creating new group for kaleidoscope-central")
605
+
group = client.groups.create(
606
+
agent_ids=lens_ids,
607
+
description="The Kaleidoscope",
608
+
manager_config=SupervisorManager(
609
+
manager_agent_id=kaleidoscope_central_id
610
+
)
611
+
)
612
+
print(f"Created group: {group.id}")
613
+
614
+
# If there are more than one groups, we need to find the group with the description
615
+
# "The Kaleidoscope" and add any lens agents that are not in the group to the group.
616
+
for group in central_groups:
617
+
if group.description == "The Kaleidoscope":
618
+
print(f"Found group: {group.id}")
619
+
for lens_id in lens_ids:
620
+
if lens_id not in group.agent_ids:
621
+
print(f"Adding lens {lens_id} to group {group.id}")
622
+
client.groups.agents.add(group_id=group.id, agent_id=lens_id)
623
+
+53
-28
organon/create_organon.py
+53
-28
organon/create_organon.py
···
1
-
project_id = "7d6a4c71-987c-4fa1-a062-c15ee4eab929"
2
-
3
1
from letta_client import Letta
4
2
from letta_client.core.http_client import re
5
3
from rich import print
4
+
from dotenv import load_dotenv
5
+
import os
6
+
import sys
7
+
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
8
+
from config_loader import get_config
9
+
10
+
load_dotenv()
11
+
12
+
# Load configuration
13
+
config = get_config()
14
+
15
+
# Get project ID and create Letta client
16
+
project_id = config.get('letta.project_id', os.environ.get('LETTA_PROJECT_ID'))
17
+
if 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")
6
19
7
20
client = Letta(
8
-
token="woops"
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)
9
24
)
10
25
26
+
CENTRAL_AGENT_MODEL = "google_ai/gemini-2.5-flash"
27
+
# CENTRAL_AGENT_MODEL = "openai/gpt-4o-mini"
28
+
29
+
SHARD_AGENT_MODEL = "google_ai/gemini-2.5-flash"
30
+
# SHARD_AGENT_MODEL = "openai/gpt-4o-mini"
31
+
32
+
11
33
#
12
34
# Memory Block Definitions
13
35
#
···
187
209
if len(agents) == 0:
188
210
organon_central = client.agents.create(
189
211
project_id=project_id,
212
+
model=CENTRAL_AGENT_MODEL,
213
+
embedding_config=client.embedding_models.list()[0],
190
214
name="organon-central",
191
215
description="The central memory manager of the Organon",
192
216
block_ids=central_agent_blocks,
···
396
420
# Check to see if the name meets the requirements. If it does not, ask the agent to update
397
421
# the name block.
398
422
for i in range(10):
423
+
399
424
if not re.match(r'[a-z0-9]+', new_shard_name.value.strip()):
400
425
print(f"New shard name `{new_shard_name.value.strip()}` does not meet the requirements, asking agent to update")
401
426
client.agents.messages.create(
···
407
432
},
408
433
]
409
434
)
435
+
436
+
# Retrieve the new shard lexicon, name, and identity
437
+
new_shard_lexicon = client.blocks.retrieve(block_id=new_shard_domain_lexicon_block.id)
438
+
new_shard_name = client.blocks.retrieve(block_id=new_shard_name_block.id)
439
+
new_shard_identity = client.blocks.retrieve(block_id=new_shard_identity_block.id)
440
+
441
+
print(f"New shard lexicon: {new_shard_lexicon.value}")
442
+
print(f"New shard name: {new_shard_name.value}")
443
+
print(f"New shard identity: {new_shard_identity.value}")
444
+
410
445
else:
411
446
break
412
447
···
435
470
project_id=project_id,
436
471
name=new_shard_name.value.strip(),
437
472
description=new_shard_identity.value,
438
-
model="goog/gemini-2.5-flash",
473
+
model=SHARD_AGENT_MODEL,
474
+
embedding_config=client.embedding_models.list()[0],
439
475
block_ids=[
440
476
new_shard_lexicon_block.id,
441
477
new_shard_identity_block.id,
···
447
483
448
484
print(f"New shard agent created: {new_shard_agent.id}")
449
485
450
-
# Find the tool by the name of send_message_to_agents_matching_tags
451
-
tool_list = client.tools.list(name="send_message_to_agents_matching_tags")
452
-
if len(tool_list) == 0:
453
-
raise ValueError("Tool send_message_to_agents_matching_tags not found")
454
-
455
-
send_message_to_agents_matching_tags = tool_list[0]
456
-
457
-
# Attach the tool to the shard agent
458
-
client.agents.tools.attach(
459
-
agent_id=new_shard_agent.id,
460
-
tool_id=send_message_to_agents_matching_tags.id,
461
-
)
462
-
463
486
# Message the shard agent to fill in its lexicon and identity
464
-
client.agents.messages.create(
465
-
agent_id=new_shard_agent.id,
466
-
messages=[
467
-
{
468
-
"role": "user",
469
-
"content": "You are a new shard agent. Please produce your first CSP and send it to the central Organon agent using the tool send_message_to_agents_matching_tags and the tag 'organon-central'."
470
-
},
471
-
]
472
-
)
487
+
# client.agents.messages.create(
488
+
# agent_id=new_shard_agent.id,
489
+
# messages=[
490
+
# {
491
+
# "role": "user",
492
+
# "content": "You are a new shard agent. Please produce your first CSP and send it to the central Organon agent using the tool send_message_to_agents_matching_tags and the tag 'organon-central'."
493
+
# },
494
+
# ]
495
+
# )
473
496
474
-
for message in response.messages:
475
-
print(message)
497
+
# for message in response.messages:
498
+
# print(message)
499
+
500
+
# Create a group for the shard agent