Skip to content

Instantly share code, notes, and snippets.

@ruvnet
Last active November 16, 2024 08:43
Show Gist options
  • Save ruvnet/92f0e8d0b2a98987838c5598c82920b6 to your computer and use it in GitHub Desktop.
Save ruvnet/92f0e8d0b2a98987838c5598c82920b6 to your computer and use it in GitHub Desktop.
AI-Driven Decentralized Organization (AIDO) using Supabase and LangChain.js. It includes all necessary files, configurations, tests, and deployment components to get started. Feel free to extend and customize the system based on your specific requirements.

AI-Driven Decentralized Organization (AIDO)

In the evolving landscape of organizational structures, the AI-Driven Decentralized Organization (AIDO) emerges as a groundbreaking concept that leverages artificial intelligence to enable autonomous and distributed decision-making without relying on traditional blockchain or cryptocurrency frameworks. Unlike conventional Decentralized Autonomous Organizations (DAOs) that depend on blockchain technology for transparency and security, AIDO harnesses a network of specialized AI agents to collaboratively manage operations, make strategic decisions, and allocate tasks efficiently.

At the core of AIDO lies a diverse set of AI agents, each equipped with unique expertise in areas such as finance, operations, strategy, and human resources. These agents interact through a sophisticated distributed decision-making system, where proposals are generated, evaluated, and voted upon using advanced machine learning algorithms and natural language processing. A robust consensus mechanism ensures that decisions reflect the collective intelligence of the network, while automated task allocation optimizes workflow based on agent capabilities and workload.

Performance monitoring within AIDO employs key performance indicators (KPIs) and continuous learning to assess the effectiveness of decisions and improve agent performance over time. This innovative approach offers enhanced adaptability, speed, and scalability compared to human-led organizations or traditional DAOs. AIDO holds immense potential across various sectors, including business management, scientific research, urban planning, and environmental conservation, paving the way for more efficient and resilient organizational models in the digital age.

Key Components

  1. AI Agents: The foundation of the AIDO would be a network of AI agents, each with specific roles and capabilities.

  2. Distributed Decision-Making System: A mechanism for agents to propose, evaluate, and vote on decisions.

  3. Consensus Algorithm: A method for reaching agreement among agents.

  4. Task Allocation System: A way to distribute work and responsibilities among agents.

  5. Performance Monitoring: A system to evaluate the effectiveness of decisions and agent performance.

Implementation

AI Agent Network

  • Develop a diverse set of AI agents with different specializations (e.g., finance, operations, strategy, human resources).
  • Each agent would have its own decision-making model, based on machine learning algorithms like neural networks or decision trees.
  • Agents would be designed to communicate with each other, share information, and collaborate on tasks.

Distributed Decision-Making

  • Implement a proposal system where any agent can submit ideas or suggestions.
  • Create a voting mechanism where agents can evaluate proposals based on predefined criteria.
  • Use natural language processing (NLP) to enable agents to understand and discuss proposals.

Consensus Algorithm

  • Develop a consensus mechanism inspired by blockchain consensus algorithms but adapted for AI agents.
  • This could involve a reputation-based system where agents with a history of good decisions have more influence.
  • Implement conflict resolution protocols for when agents disagree.

Task Allocation

  • Design an automated task distribution system based on agent capabilities and current workload.
  • Use reinforcement learning to optimize task allocation over time.

Performance Monitoring

  • Implement key performance indicators (KPIs) to measure the success of decisions and overall organization performance.
  • Use machine learning to analyze patterns in successful and unsuccessful decisions.

Challenges and Considerations

  1. Centralization Risk: Ensure that no single agent or small group of agents can dominate decision-making.

  2. Ethical Decision-Making: Implement robust ethical guidelines and checks to prevent harmful or biased decisions.

  3. Transparency: Create logs and explanations of agent decisions to maintain accountability.

  4. Human Oversight: While the system is autonomous, consider implementing a human review board for major decisions or as a failsafe.

  5. Adaptability: Design the system to evolve and improve over time based on its performance and changing environments.

  6. Security: Implement strong security measures to protect against hacking or manipulation of the AI agents.

Potential Applications

This AI-driven decentralized organization could be applied in various fields:

  • Business Management: Running day-to-day operations of a company.
  • Scientific Research: Coordinating and managing complex research projects.
  • Urban Planning: Making decisions about city development and resource allocation.
  • Environmental Conservation: Managing wildlife preserves or coordinating climate change initiatives.

While this concept of an AIDO diverges from the traditional blockchain-based DAO, it presents an innovative approach to decentralized decision-making using AI. It could potentially offer faster decision-making and more adaptive strategies compared to human-led organizations or traditional DAOs. However, it would require careful design and ongoing refinement to ensure it operates ethically and effectively.

Citations:

Project Structure

aido-project/
├── supabase/
│   ├── functions/
│   │   ├── agent-network/
│   │   │   └── index.ts
│   │   ├── decision-making/
│   │   │   └── index.ts
│   │   ├── consensus/
│   │   │   └── index.ts
│   │   ├── task-allocation/
│   │   │   └── index.ts
│   │   └── performance-monitoring/
│   │       └── index.ts
│   ├── migrations/
│   │   └── 20231115000000_initial_schema.sql
│   └── seed.sql
├── tests/
│   ├── agent-network.test.ts
│   ├── decision-making.test.ts
│   ├── consensus.test.ts
│   ├── task-allocation.test.ts
│   └── performance-monitoring.test.ts
├── package.json
├── tsconfig.json
├── .env
├── .gitignore
├── .github/
│   └── workflows/
│       └── main.yml
└── README.md

Implementation Details

1. Agent Network (supabase/functions/agent-network/index.ts)

import { serve } from 'https://deno.land/[email protected]/http/server.ts';
import { createClient } from 'https://esm.sh/@supabase/supabase-js@2';
import { OpenAI } from 'https://esm.sh/langchain/llms/openai';
import { PromptTemplate } from 'https://esm.sh/langchain/prompts';

const supabaseUrl = Deno.env.get('SUPABASE_URL') ?? '';
const supabaseAnonKey = Deno.env.get('SUPABASE_ANON_KEY') ?? '';
const openAiApiKey = Deno.env.get('OPENAI_API_KEY') ?? '';

const supabase = createClient(supabaseUrl, supabaseAnonKey);

serve(async (req) => {
  try {
    const { action, data } = await req.json();

    const llm = new OpenAI({ openAIApiKey: openAiApiKey });

    switch (action) {
      case 'generate_proposal':
        const template = 'You are an AI agent specializing in {specialty}. Generate a proposal for {topic}.';
        const prompt = new PromptTemplate({ template, inputVariables: ['specialty', 'topic'] });
        const formattedPrompt = await prompt.format({ specialty: data.specialty, topic: data.topic });
        const response = await llm.call(formattedPrompt);

        const { error } = await supabase.from('proposals').insert({
          content: response,
          agent_specialty: data.specialty,
        });

        if (error) throw error;

        return new Response(JSON.stringify({ proposal: response }), {
          headers: { 'Content-Type': 'application/json' },
        });

      default:
        return new Response(JSON.stringify({ error: 'Invalid action' }), {
          status: 400,
          headers: { 'Content-Type': 'application/json' },
        });
    }
  } catch (error) {
    console.error(error);
    return new Response(JSON.stringify({ error: error.message }), {
      status: 500,
      headers: { 'Content-Type': 'application/json' },
    });
  }
});

2. Decision Making (supabase/functions/decision-making/index.ts)

import { serve } from 'https://deno.land/[email protected]/http/server.ts';
import { createClient } from 'https://esm.sh/@supabase/supabase-js@2';
import { OpenAI } from 'https://esm.sh/langchain/llms/openai';
import { PromptTemplate } from 'https://esm.sh/langchain/prompts';

const supabaseUrl = Deno.env.get('SUPABASE_URL') ?? '';
const supabaseAnonKey = Deno.env.get('SUPABASE_ANON_KEY') ?? '';
const openAiApiKey = Deno.env.get('OPENAI_API_KEY') ?? '';

const supabase = createClient(supabaseUrl, supabaseAnonKey);

serve(async (req) => {
  try {
    const { action, data } = await req.json();

    const llm = new OpenAI({ openAIApiKey: openAiApiKey });

    switch (action) {
      case 'evaluate_proposal':
        const { proposal_id } = data;
        const { data: proposalData, error: proposalError } = await supabase
          .from('proposals')
          .select('*')
          .eq('id', proposal_id)
          .single();

        if (proposalError) throw proposalError;

        const template = 'Evaluate the following proposal: "{proposal}". Provide a score from 0 to 10 and a brief explanation.';
        const prompt = new PromptTemplate({ template, inputVariables: ['proposal'] });
        const formattedPrompt = await prompt.format({ proposal: proposalData.content });
        const response = await llm.call(formattedPrompt);

        // Assume the response is in the format "Score: X\nExplanation: Y"
        const scoreMatch = response.match(/Score:\s*(\d+)/i);
        const explanationMatch = response.match(/Explanation:\s*(.+)/i);

        const score = scoreMatch ? parseInt(scoreMatch[1]) : null;
        const explanation = explanationMatch ? explanationMatch[1] : '';

        if (score === null) throw new Error('Failed to parse score from AI response.');

        const { error: evalError } = await supabase.from('evaluations').insert({
          proposal_id,
          score,
          explanation,
        });

        if (evalError) throw evalError;

        return new Response(JSON.stringify({ score, explanation }), {
          headers: { 'Content-Type': 'application/json' },
        });

      default:
        return new Response(JSON.stringify({ error: 'Invalid action' }), {
          status: 400,
          headers: { 'Content-Type': 'application/json' },
        });
    }
  } catch (error) {
    console.error(error);
    return new Response(JSON.stringify({ error: error.message }), {
      status: 500,
      headers: { 'Content-Type': 'application/json' },
    });
  }
});

3. Consensus (supabase/functions/consensus/index.ts)

import { serve } from 'https://deno.land/[email protected]/http/server.ts';
import { createClient } from 'https://esm.sh/@supabase/supabase-js@2';

const supabaseUrl = Deno.env.get('SUPABASE_URL') ?? '';
const supabaseAnonKey = Deno.env.get('SUPABASE_ANON_KEY') ?? '';

const supabase = createClient(supabaseUrl, supabaseAnonKey);

serve(async (req) => {
  try {
    const { action, data } = await req.json();

    switch (action) {
      case 'reach_consensus':
        const { proposal_id } = data;
        const { data: evaluations, error: evalError } = await supabase
          .from('evaluations')
          .select('score')
          .eq('proposal_id', proposal_id);

        if (evalError) throw evalError;

        if (evaluations.length === 0) {
          throw new Error('No evaluations found for the proposal.');
        }

        const totalScore = evaluations.reduce((sum, evalItem) => sum + evalItem.score, 0);
        const averageScore = totalScore / evaluations.length;
        const consensus = averageScore >= 7 ? 'accepted' : 'rejected';

        const { error: updateError } = await supabase
          .from('proposals')
          .update({ status: consensus })
          .eq('id', proposal_id);

        if (updateError) throw updateError;

        return new Response(JSON.stringify({ consensus, averageScore }), {
          headers: { 'Content-Type': 'application/json' },
        });

      default:
        return new Response(JSON.stringify({ error: 'Invalid action' }), {
          status: 400,
          headers: { 'Content-Type': 'application/json' },
        });
    }
  } catch (error) {
    console.error(error);
    return new Response(JSON.stringify({ error: error.message }), {
      status: 500,
      headers: { 'Content-Type': 'application/json' },
    });
  }
});

4. Task Allocation (supabase/functions/task-allocation/index.ts)

import { serve } from 'https://deno.land/[email protected]/http/server.ts';
import { createClient } from 'https://esm.sh/@supabase/supabase-js@2';
import { OpenAI } from 'https://esm.sh/langchain/llms/openai';
import { PromptTemplate } from 'https://esm.sh/langchain/prompts';

const supabaseUrl = Deno.env.get('SUPABASE_URL') ?? '';
const supabaseAnonKey = Deno.env.get('SUPABASE_ANON_KEY') ?? '';
const openAiApiKey = Deno.env.get('OPENAI_API_KEY') ?? '';

const supabase = createClient(supabaseUrl, supabaseAnonKey);

serve(async (req) => {
  try {
    const { action, data } = await req.json();

    const llm = new OpenAI({ openAIApiKey: openAiApiKey });

    switch (action) {
      case 'allocate_task':
        const { task } = data;

        const { data: agents, error: agentsError } = await supabase.from('agents').select('name, specialty');

        if (agentsError) throw agentsError;

        const template = `Given the task: "{task}", and the available agents with their specialties: {agents}, which agent is best suited for this task? Provide the agent's name and a brief explanation.`;
        const prompt = new PromptTemplate({ template, inputVariables: ['task', 'agents'] });
        const formattedPrompt = await prompt.format({
          task,
          agents: agents.map((agent) => `${agent.name} (${agent.specialty})`).join(', '),
        });
        const response = await llm.call(formattedPrompt);

        // Assume the response is in the format "Agent: X\nExplanation: Y"
        const agentMatch = response.match(/Agent:\s*(.+)/i);
        const explanationMatch = response.match(/Explanation:\s*(.+)/i);

        const allocatedAgent = agentMatch ? agentMatch[1].trim() : null;
        const explanation = explanationMatch ? explanationMatch[1].trim() : '';

        if (!allocatedAgent) throw new Error('Failed to parse allocated agent from AI response.');

        const { error: allocationError } = await supabase.from('task_allocations').insert({
          task,
          allocated_agent: allocatedAgent,
          explanation,
        });

        if (allocationError) throw allocationError;

        return new Response(JSON.stringify({ allocatedAgent, explanation }), {
          headers: { 'Content-Type': 'application/json' },
        });

      default:
        return new Response(JSON.stringify({ error: 'Invalid action' }), {
          status: 400,
          headers: { 'Content-Type': 'application/json' },
        });
    }
  } catch (error) {
    console.error(error);
    return new Response(JSON.stringify({ error: error.message }), {
      status: 500,
      headers: { 'Content-Type': 'application/json' },
    });
  }
});

5. Performance Monitoring (supabase/functions/performance-monitoring/index.ts)

import { serve } from 'https://deno.land/[email protected]/http/server.ts';
import { createClient } from 'https://esm.sh/@supabase/supabase-js@2';

const supabaseUrl = Deno.env.get('SUPABASE_URL') ?? '';
const supabaseAnonKey = Deno.env.get('SUPABASE_ANON_KEY') ?? '';

const supabase = createClient(supabaseUrl, supabaseAnonKey);

serve(async (req) => {
  try {
    const { action, data } = await req.json();

    switch (action) {
      case 'calculate_kpis':
        const { start_date, end_date } = data;

        const { data: proposals, error: proposalsError } = await supabase
          .from('proposals')
          .select('*')
          .gte('created_at', start_date)
          .lte('created_at', end_date);

        if (proposalsError) throw proposalsError;

        const { data: taskAllocations, error: tasksError } = await supabase
          .from('task_allocations')
          .select('*')
          .gte('created_at', start_date)
          .lte('created_at', end_date);

        if (tasksError) throw tasksError;

        const acceptedProposals = proposals.filter((p) => p.status === 'accepted').length;
        const totalProposals = proposals.length;
        const proposalAcceptanceRate = totalProposals > 0 ? acceptedProposals / totalProposals : 0;

        const completedTasks = taskAllocations.filter((task) => task.completed_at);
        const totalTasks = taskAllocations.length;
        const averageTaskCompletionTime =
          completedTasks.length > 0
            ? completedTasks.reduce((sum, task) => {
                const completionTime = new Date(task.completed_at).getTime() - new Date(task.created_at).getTime();
                return sum + completionTime;
              }, 0) / completedTasks.length
            : 0;

        const kpis = {
          proposal_acceptance_rate: proposalAcceptanceRate,
          average_task_completion_time: averageTaskCompletionTime,
          total_proposals: totalProposals,
          total_tasks: totalTasks,
        };

        const { error: metricsError } = await supabase.from('performance_metrics').insert(kpis);

        if (metricsError) throw metricsError;

        return new Response(JSON.stringify(kpis), {
          headers: { 'Content-Type': 'application/json' },
        });

      default:
        return new Response(JSON.stringify({ error: 'Invalid action' }), {
          status: 400,
          headers: { 'Content-Type': 'application/json' },
        });
    }
  } catch (error) {
    console.error(error);
    return new Response(JSON.stringify({ error: error.message }), {
      status: 500,
      headers: { 'Content-Type': 'application/json' },
    });
  }
});

6. Database Schema (supabase/migrations/20231115000000_initial_schema.sql)

-- Enable UUID generation
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

-- Agents Table
CREATE TABLE public.agents (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  name TEXT NOT NULL,
  specialty TEXT NOT NULL,
  created_at TIMESTAMPTZ DEFAULT NOW()
);

-- Proposals Table
CREATE TABLE public.proposals (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  content TEXT NOT NULL,
  agent_specialty TEXT NOT NULL,
  status TEXT DEFAULT 'pending',
  created_at TIMESTAMPTZ DEFAULT NOW()
);

-- Evaluations Table
CREATE TABLE public.evaluations (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  proposal_id UUID REFERENCES public.proposals(id) ON DELETE CASCADE,
  score INTEGER NOT NULL,
  explanation TEXT,
  created_at TIMESTAMPTZ DEFAULT NOW()
);

-- Task Allocations Table
CREATE TABLE public.task_allocations (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  task TEXT NOT NULL,
  allocated_agent TEXT NOT NULL,
  explanation TEXT,
  created_at TIMESTAMPTZ DEFAULT NOW(),
  completed_at TIMESTAMPTZ
);

-- Performance Metrics Table
CREATE TABLE public.performance_metrics (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  proposal_acceptance_rate FLOAT,
  average_task_completion_time FLOAT,
  total_proposals INTEGER,
  total_tasks INTEGER,
  created_at TIMESTAMPTZ DEFAULT NOW()
);

7. Seed Data (supabase/seed.sql)

-- Insert sample agents
INSERT INTO public.agents (name, specialty) VALUES
('Alice', 'Finance'),
('Bob', 'Operations'),
('Carol', 'Strategy'),
('Dave', 'Human Resources');

8. Tests

Create a deno.json file to set up Deno's configuration for testing:

{
  "tasks": {
    "test": "deno test --allow-env --allow-net --unstable"
  },
  "imports": {}
}

a. Agent Network Test (tests/agent-network.test.ts)

import { assertEquals, assert } from 'https://deno.land/[email protected]/testing/asserts.ts';
import { createClient } from 'https://esm.sh/@supabase/supabase-js@2';

const supabaseUrl = Deno.env.get('SUPABASE_URL') ?? '';
const supabaseAnonKey = Deno.env.get('SUPABASE_ANON_KEY') ?? '';
const functionsUrl = Deno.env.get('SUPABASE_FUNCTIONS_URL') ?? '';

const supabase = createClient(supabaseUrl, supabaseAnonKey);

Deno.test('Agent Network - Generate Proposal', async () => {
  const response = await fetch(`${functionsUrl}/agent-network`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      action: 'generate_proposal',
      data: { specialty: 'Finance', topic: 'Cost Reduction Strategies' },
    }),
  });

  const result = await response.json();
  assertEquals(response.status, 200);
  assert(typeof result.proposal === 'string');

  const { data, error } = await supabase
    .from('proposals')
    .select()
    .order('created_at', { ascending: false })
    .limit(1);

  assertEquals(error, null);
  assertEquals(data[0].content, result.proposal);
});

b. Decision Making Test (tests/decision-making.test.ts)

import { assertEquals, assert } from 'https://deno.land/[email protected]/testing/asserts.ts';
import { createClient } from 'https://esm.sh/@supabase/supabase-js@2';

const supabaseUrl = Deno.env.get('SUPABASE_URL') ?? '';
const supabaseAnonKey = Deno.env.get('SUPABASE_ANON_KEY') ?? '';
const functionsUrl = Deno.env.get('SUPABASE_FUNCTIONS_URL') ?? '';

const supabase = createClient(supabaseUrl, supabaseAnonKey);

Deno.test('Decision Making - Evaluate Proposal', async () => {
  // Insert a test proposal
  const { data: proposal, error: proposalError } = await supabase.from('proposals').insert({
    content: 'Test proposal content',
    agent_specialty: 'Finance',
  }).select().single();

  assertEquals(proposalError, null);

  const response = await fetch(`${functionsUrl}/decision-making`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      action: 'evaluate_proposal',
      data: { proposal_id: proposal.id },
    }),
  });

  const result = await response.json();
  assertEquals(response.status, 200);
  assert(typeof result.score === 'number');
  assert(typeof result.explanation === 'string');

  const { data: evaluations, error: evalError } = await supabase
    .from('evaluations')
    .select()
    .eq('proposal_id', proposal.id);

  assertEquals(evalError, null);
  assert(evaluations.length > 0);
});

c. Consensus Test (tests/consensus.test.ts)

import { assertEquals } from 'https://deno.land/[email protected]/testing/asserts.ts';
import { createClient } from 'https://esm.sh/@supabase/supabase-js@2';

const supabaseUrl = Deno.env.get('SUPABASE_URL') ?? '';
const supabaseAnonKey = Deno.env.get('SUPABASE_ANON_KEY') ?? '';
const functionsUrl = Deno.env.get('SUPABASE_FUNCTIONS_URL') ?? '';

const supabase = createClient(supabaseUrl, supabaseAnonKey);

Deno.test('Consensus - Reach Consensus', async () => {
  // Insert a test proposal
  const { data: proposal, error: proposalError } = await supabase.from('proposals').insert({
    content: 'Consensus test proposal',
    agent_specialty: 'Strategy',
  }).select().single();

  assertEquals(proposalError, null);

  // Insert evaluations
  await supabase.from('evaluations').insert([
    { proposal_id: proposal.id, score: 8, explanation: 'Good idea' },
    { proposal_id: proposal.id, score: 7, explanation: 'Viable' },
    { proposal_id: proposal.id, score: 9, explanation: 'Excellent' },
  ]);

  const response = await fetch(`${functionsUrl}/consensus`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      action: 'reach_consensus',
      data: { proposal_id: proposal.id },
    }),
  });

  const result = await response.json();
  assertEquals(response.status, 200);
  assertEquals(result.consensus, 'accepted');

  const { data: updatedProposal } = await supabase
    .from('proposals')
    .select('status')
    .eq('id', proposal.id)
    .single();

  assertEquals(updatedProposal.status, 'accepted');
});

d. Task Allocation Test (tests/task-allocation.test.ts)

import { assertEquals } from 'https://deno.land/[email protected]/testing/asserts.ts';
import { createClient } from 'https://esm.sh/@supabase/supabase-js@2';

const supabaseUrl = Deno.env.get('SUPABASE_URL') ?? '';
const supabaseAnonKey = Deno.env.get('SUPABASE_ANON_KEY') ?? '';
const functionsUrl = Deno.env.get('SUPABASE_FUNCTIONS_URL') ?? '';

const supabase = createClient(supabaseUrl, supabaseAnonKey);

Deno.test('Task Allocation - Allocate Task', async () => {
  const taskDescription = 'Develop a new marketing strategy';

  const response = await fetch(`${functionsUrl}/task-allocation`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      action: 'allocate_task',
      data: { task: taskDescription },
    }),
  });

  const result = await response.json();
  assertEquals(response.status, 200);
  assert(typeof result.allocatedAgent === 'string');
  assert(typeof result.explanation === 'string');

  const { data: taskAllocations, error } = await supabase
    .from('task_allocations')
    .select()
    .eq('task', taskDescription);

  assertEquals(error, null);
  assertEquals(taskAllocations[0].allocated_agent, result.allocatedAgent);
});

e. Performance Monitoring Test (tests/performance-monitoring.test.ts)

import { assertEquals, assert } from 'https://deno.land/[email protected]/testing/asserts.ts';
import { createClient } from 'https://esm.sh/@supabase/supabase-js@2';

const supabaseUrl = Deno.env.get('SUPABASE_URL') ?? '';
const supabaseAnonKey = Deno.env.get('SUPABASE_ANON_KEY') ?? '';
const functionsUrl = Deno.env.get('SUPABASE_FUNCTIONS_URL') ?? '';

const supabase = createClient(supabaseUrl, supabaseAnonKey);

Deno.test('Performance Monitoring - Calculate KPIs', async () => {
  const startDate = new Date();
  startDate.setDate(startDate.getDate() - 7); // Last 7 days
  const endDate = new Date();

  const response = await fetch(`${functionsUrl}/performance-monitoring`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      action: 'calculate_kpis',
      data: { start_date: startDate.toISOString(), end_date: endDate.toISOString() },
    }),
  });

  const result = await response.json();
  assertEquals(response.status, 200);
  assert(typeof result.proposal_acceptance_rate === 'number');
  assert(typeof result.average_task_completion_time === 'number');

  const { data: metrics, error } = await supabase
    .from('performance_metrics')
    .select()
    .order('created_at', { ascending: false })
    .limit(1);

  assertEquals(error, null);
  assert(metrics.length > 0);
  assertEquals(metrics[0].proposal_acceptance_rate, result.proposal_acceptance_rate);
});

9. Package.json (package.json)

{
  "name": "aido-project",
  "version": "1.0.0",
  "description": "AI-Driven Decentralized Organization (AIDO) using Supabase and LangChain.js",
  "main": "index.js",
  "scripts": {
    "start": "supabase start",
    "deploy": "supabase functions deploy --all",
    "test": "deno task test"
  },
  "author": "Your Name",
  "license": "MIT",
  "dependencies": {},
  "devDependencies": {}
}

10. TypeScript Configuration (tsconfig.json)

{
  "compilerOptions": {
    "target": "ES2020",
    "module": "ESNext",
    "lib": ["ES2020", "DOM"],
    "strict": true,
    "moduleResolution": "Node",
    "esModuleInterop": true,
    "jsx": "react",
    "types": ["deno.ns", "deno.unstable"]
  }
}

11. Environment Variables (.env)

Create a .env file in the root directory:

SUPABASE_URL=your_supabase_url
SUPABASE_ANON_KEY=your_supabase_anon_key
SUPABASE_SERVICE_ROLE_KEY=your_supabase_service_role_key
OPENAI_API_KEY=your_openai_api_key
SUPABASE_FUNCTIONS_URL=your_supabase_functions_url

Replace the placeholders with your actual Supabase and OpenAI credentials.


12. Git Ignore File (.gitignore)

.env
node_modules/
.DS_Store
supabase/.temp/

13. README.md (README.md)

# AI-Driven Decentralized Organization (AIDO)

This project implements an AI-Driven Decentralized Organization (AIDO) using Supabase Edge Functions and LangChain.js.

## Features

- **Agent Network**: AI agents generate proposals based on their specialties.
- **Decision Making**: Agents evaluate proposals and provide scores and explanations.
- **Consensus**: The system reaches consensus on proposals based on evaluations.
- **Task Allocation**: Tasks are allocated to the most suitable agents.
- **Performance Monitoring**: KPIs are calculated to monitor organizational performance.

## Project Structure

aido-project/ ├── supabase/ ├── tests/ ├── package.json ├── tsconfig.json ├── .env ├── .gitignore ├── .github/ └── README.md


## Setup Instructions

1. **Clone the repository**

   ```bash
   git clone https://github.com/your-username/aido-project.git
   cd aido-project
  1. Install Supabase CLI

    npm install -g supabase
  2. Install Deno

    Follow the instructions at https://deno.land/#installation

  3. Set up Environment Variables

    Create a .env file and add your Supabase and OpenAI credentials.

  4. Initialize Supabase

    supabase init
  5. Start Supabase Locally

    supabase start
  6. Apply Database Migrations

    supabase db reset
    supabase db push
  7. Seed the Database

    supabase db seed
  8. Deploy Edge Functions

    supabase functions deploy agent-network
    supabase functions deploy decision-making
    supabase functions deploy consensus
    supabase functions deploy task-allocation
    supabase functions deploy performance-monitoring
  9. Run Tests

    deno task test

Continuous Integration and Deployment

The project uses GitHub Actions for CI/CD. Make sure to set the SUPABASE_ACCESS_TOKEN and other necessary secrets in your GitHub repository settings.


14. GitHub Actions Workflow (.github/workflows/main.yml)

name: CI/CD

on:
  push:
    branches: [ main ]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2

    - name: Set up Deno
      uses: denoland/setup-deno@v1

    - name: Install Supabase CLI
      run: npm install -g supabase

    - name: Log in to Supabase
      env:
        SUPABASE_ACCESS_TOKEN: ${{ secrets.SUPABASE_ACCESS_TOKEN }}
      run: |
        echo $SUPABASE_ACCESS_TOKEN | supabase login --token

    - name: Deploy to Supabase
      env:
        PROJECT_ID: ${{ secrets.SUPABASE_PROJECT_ID }}
        SUPABASE_URL: ${{ secrets.SUPABASE_URL }}
        SUPABASE_ANON_KEY: ${{ secrets.SUPABASE_ANON_KEY }}
        OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
      run: |
        supabase link --project-ref $PROJECT_ID
        supabase db push
        supabase functions deploy agent-network --no-verify-jwt
        supabase functions deploy decision-making --no-verify-jwt
        supabase functions deploy consensus --no-verify-jwt
        supabase functions deploy task-allocation --no-verify-jwt
        supabase functions deploy performance-monitoring --no-verify-jwt

15. Supabase Configuration (supabase/config.toml)

[project]
id = "your-project-id"

[functions]
ignore_paths = [".gitignore", "node_modules/", "tests/", "README.md"]

Deployment Instructions

  1. Set Up GitHub Secrets

    In your GitHub repository, add the following secrets:

    • SUPABASE_ACCESS_TOKEN: Your Supabase access token.
    • SUPABASE_PROJECT_ID: Your Supabase project ID.
    • SUPABASE_URL: Your Supabase URL.
    • SUPABASE_ANON_KEY: Your Supabase anonymous key.
    • OPENAI_API_KEY: Your OpenAI API key.
  2. Push to GitHub

    Commit and push your code to the main branch. The GitHub Actions workflow will automatically deploy your functions.

    git add .
    git commit -m "Initial commit"
    git push origin main
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment