Skip to content

Commit

Permalink
more society of mind
Browse files Browse the repository at this point in the history
  • Loading branch information
ToonTalk committed Sep 7, 2024
1 parent f972936 commit 4000d54
Show file tree
Hide file tree
Showing 8 changed files with 455 additions and 0 deletions.
97 changes: 97 additions & 0 deletions apps/society of mind/agents.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// agents.js

let agents = [];

async function createAgent(role, systemPrompt, llmType, apiKey) {
console.log(`Attempting to create agent: ${role} with LLM type: ${llmType}`);
const baseAgent = {
role,
llmType,
apiKey,
messages: [`You are a ${role} agent in Minsky's Society of Mind. ${systemPrompt}`]
};

if (llmType === 'geminiNano') {
try {
console.log(`Creating Gemini Nano session for ${role}`);
const session = await ai.assistant.create({
systemPrompt: `You are a ${role} agent in Minsky's Society of Mind. ${systemPrompt}`
});
console.log(`Gemini Nano session created successfully for ${role}`);
return { ...baseAgent, session };
} catch (error) {
console.error(`Error creating Gemini Nano session for ${role}:`, error);
throw error;
}
}

console.log(`Agent created successfully: ${role}`);
return baseAgent;
}

async function initializeAgents() {
const llmSelect = document.getElementById('llmSelect');
const apiKeyInput = document.getElementById('apiKeyInput');
currentLLMType = llmSelect.value;
const apiKey = currentLLMType === 'geminiNano' ? null : apiKeyInput.value;
console.log(`Initializing agents with LLM type: ${currentLLMType}`);

const agentRoles = [
{ role: 'K-line', prompt: 'Your role is to store and retrieve specific memories or knowledge. When asked a question, provide relevant information from your knowledge base. If you don\'t have specific information, say so.' },
{ role: 'Neme', prompt: 'You are a basic memory element. Your task is to recognize and respond to specific patterns or stimuli.' },
{ role: 'Frame', prompt: 'You represent a structured collection of information about a particular concept or situation. Provide context and details when called upon.' },
{ role: 'Trans-frame', prompt: 'Your job is to handle transitions between different frames or states. Suggest how to move from one situation to another.' },
{ role: 'Polyneme', prompt: 'You are responsible for connecting multiple ideas or concepts. When presented with information, find and explain relationships between different elements.' },
{ role: 'Microneme', prompt: 'You represent small, context-specific bits of information. Provide subtle contextual cues that might influence thinking or decision-making.' },
{ role: 'Censor', prompt: 'Your role is to inhibit or prevent certain thoughts or actions. When presented with ideas, evaluate if they should be suppressed and explain why.' },
{ role: 'Suppressor', prompt: 'Similar to a Censor, but you actively work to reduce the influence of certain thoughts or memories. Suggest alternative focuses when presented with information.' },
{ role: 'Recognizer', prompt: 'Your job is to identify patterns, concepts, or relevant information in any input you receive. Analyze the input and describe any patterns or important elements you recognize.' },
{ role: 'Difference-engine', prompt: 'Your task is to compare the current state of a situation to the desired state and suggest actions to bridge the gap. Analyze the situation presented to you, identify discrepancies, and propose solutions.' },
{ role: 'Summary', prompt: 'Your task is to generate concise summaries of the interactions between other agents. Highlight key points and progression towards the solution.' },
{ role: 'Decision', prompt: 'Your role is to evaluate the current state of the problem-solving process and decide if a satisfactory solution has been found. Consider the initial problem and the proposed solutions.' }
];

const selectedAgents = Array.from(document.querySelectorAll('.agent-checkbox:checked')).map(checkbox => checkbox.value);

// Ensure Summary and Decision agents are always created
const essentialAgents = ['Summary', 'Decision'];
const agentsToCreate = [...new Set([...selectedAgents, ...essentialAgents])];

agents = await Promise.all(agentRoles
.filter(({role}) => agentsToCreate.includes(role))
.map(({ role, prompt }) => createAgent(role, prompt, currentLLMType, apiKey))
);

console.log("Initialized agents:", agents.map(agent => agent.role));
}

function getRandomAgent() {
return agents[Math.floor(Math.random() * agents.length)];
}

function getAgentTask(role) {
switch (role) {
case 'K-line':
return 'Provide relevant information from your knowledge base.';
case 'Neme':
return 'Recognize and respond to specific patterns or stimuli in the current situation.';
case 'Frame':
return 'Provide context and details about the current concept or situation.';
case 'Trans-frame':
return 'Suggest how to transition from the current state to a desired state.';
case 'Polyneme':
return 'Find and explain relationships between different elements in the current situation.';
case 'Microneme':
return 'Provide subtle contextual cues that might influence thinking or decision-making in this situation.';
case 'Censor':
return 'Evaluate if any ideas should be suppressed and explain why.';
case 'Suppressor':
return 'Suggest alternative focuses to reduce the influence of certain thoughts or memories.';
case 'Recognizer':
return 'Identify patterns or concepts in the current situation.';
case 'Difference-engine':
return 'Compare the current state to the desired state and suggest actions to bridge the gap.';
default:
return 'Analyze the situation and provide insights based on your role.';
}
}
108 changes: 108 additions & 0 deletions apps/society of mind/api.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
// api.js

async function processMessage(agent, message, maxRetries = 3) {
console.log(`Processing message for agent: ${agent.role}, LLM type: ${agent.llmType}`);
console.log(`Message: ${message}`);
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
let response;

switch (agent.llmType) {
case 'geminiNano':
agent.messages.push(message);
const fullPrompt = agent.messages.join('\n');
console.log(`Sending prompt to Gemini Nano: ${fullPrompt}`);
response = await agent.session.prompt(fullPrompt);
console.log(`Received response from Gemini Nano: ${response}`);
agent.messages.push(response);
break;
case 'gemini':
response = await callGeminiApi(agent.apiKey, [...agent.messages, message]);
agent.messages.push(message, response);
break;
case 'cohere':
response = await callCohereApi(agent.apiKey, [...agent.messages, message]);
agent.messages.push(message, response);
break;
case 'gpt4':
response = await callGpt4Api(agent.apiKey, [...agent.messages, {role: "user", content: message}]);
agent.messages.push({role: "user", content: message}, {role: "assistant", content: response});
break;
default:
throw new Error(`Invalid LLM type: ${agent.llmType}`);
}

return response;
} catch (error) {
console.error(`Attempt ${attempt + 1} failed for ${agent.role}:`, error);
if (attempt === maxRetries - 1) {
throw error;
}
await new Promise(resolve => setTimeout(resolve, 1000));
}
}
}

async function callGeminiApi(apiKey, messages) {
const GEMINI_API_URL = 'https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent';

const formattedMessages = messages.map((msg, index) => ({
role: index % 2 === 0 ? "user" : "model",
parts: [{ text: msg }]
}));

const requestBody = {
contents: formattedMessages,
safetySettings: [
{
category: "HARM_CATEGORY_DANGEROUS_CONTENT",
threshold: "BLOCK_ONLY_HIGH"
}
],
generationConfig: {
temperature: 0.7,
topK: 40,
topP: 0.95,
maxOutputTokens: 1024,
}
};

console.log('Gemini API Request:', JSON.stringify(requestBody, null, 2));

try {
const response = await fetch(`${GEMINI_API_URL}?key=${apiKey}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(requestBody)
});

const responseData = await response.json();

if (!response.ok) {
console.error('Gemini API Error Response:', responseData);
throw new Error(`HTTP error! status: ${response.status}, message: ${responseData.error?.message || 'Unknown error'}`);
}

console.log('Gemini API Response:', responseData);
return responseData.candidates[0].content.parts[0].text;
} catch (error) {
console.error('Error calling Gemini API:', error);
throw error;
}
}

async function callCohereApi(apiKey, messages) {
// Implementation for Cohere API
// This is a placeholder. You'll need to implement the actual API call based on Cohere's documentation.
console.log('Calling Cohere API with messages:', messages);
return "Cohere API response placeholder";
}

async function callGpt4Api(apiKey, messages) {
// Implementation for GPT-4 API
// This is a placeholder. You'll need to implement the actual API call based on OpenAI's documentation.
console.log('Calling GPT-4 API with messages:', messages);
return "GPT-4 API response placeholder";
}
48 changes: 48 additions & 0 deletions apps/society of mind/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Minsky's Agents Simulation with All Agent Types</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/markdown-it/12.3.2/markdown-it.min.js"></script>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<h1>Minsky's Agents Simulation with All Agent Types</h1>
<select id="llmSelect">
<option value="geminiNano">Gemini Nano (Default)</option>
<option value="gemini">Gemini</option>
<option value="cohere">Cohere.ai</option>
<option value="gpt4">GPT-4 (4o-mini)</option>
</select>
<input type="password" id="apiKeyInput" placeholder="Enter API Key">
<div id="agentSelection">
<h3>Select Agent Types:</h3>
<label><input type="checkbox" class="agent-checkbox" value="K-line" checked> K-line</label>
<label><input type="checkbox" class="agent-checkbox" value="Neme" checked> Neme</label>
<label><input type="checkbox" class="agent-checkbox" value="Frame" checked> Frame</label>
<label><input type="checkbox" class="agent-checkbox" value="Trans-frame" checked> Trans-frame</label>
<label><input type="checkbox" class="agent-checkbox" value="Polyneme" checked> Polyneme</label>
<label><input type="checkbox" class="agent-checkbox" value="Microneme" checked> Microneme</label>
<label><input type="checkbox" class="agent-checkbox" value="Censor" checked> Censor</label>
<label><input type="checkbox" class="agent-checkbox" value="Suppressor" checked> Suppressor</label>
<label><input type="checkbox" class="agent-checkbox" value="Recognizer" checked> Recognizer</label>
<label><input type="checkbox" class="agent-checkbox" value="Difference-engine" checked> Difference-engine</label>
</div>
<textarea id="problem" rows="3" placeholder="Enter your problem here..."></textarea>
<input type="number" id="maxIterations" value="10" min="1" max="20">
<button id="runSimulation">Run Simulation</button>
<div id="summary"></div>
<button id="toggleLog" class="toggle-btn">Show Full Log</button>
<div id="fullLog"></div>
<button id="toggleErrorLog" class="toggle-btn">Show Error Log</button>
<div id="errorLog"></div>

<script src="markdown-setup.js"></script>
<script src="utils.js"></script>
<script src="agents.js"></script>
<script src="api.js"></script>
<script src="simulation.js"></script>
<script src="main.js"></script>
</body>
</html>
12 changes: 12 additions & 0 deletions apps/society of mind/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Main script to tie everything together

document.addEventListener('DOMContentLoaded', function() {
document.getElementById('llmSelect').addEventListener('change', toggleApiKeyInput);
document.getElementById('runSimulation').addEventListener('click', runSimulation);
document.getElementById('toggleLog').addEventListener('click', () => toggleLog('fullLog'));
document.getElementById('toggleErrorLog').addEventListener('click', () => toggleLog('errorLog'));

// Initialize on page load
toggleApiKeyInput();
initializeAgents();
});
4 changes: 4 additions & 0 deletions apps/society of mind/markdown-setup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// markdown-setup.js

// Initialize markdown-it and make it globally accessible
window.md = window.markdownit();
Loading

0 comments on commit 4000d54

Please sign in to comment.