Open-Agent Documentation

repository·master·Indexed 21 days ago

https://github.com/afk-surf/open-agent

An open-source multi-agent framework and alternative to proprietary agentic AI systems. It enables collaboration between frontier models (OpenAI, Claude, Gemini) through spec and context engineering. The project includes a GraphQL client, a React + Vite frontend, an Electron-based state management system using arktype and RxJS, and a comprehensive extension system for managing store and view providers via BlockSuite.

Tokens
210K
Snippets
773
Records
1.1K
Agent score
75%

What's inside Open-Agent

  1. Understand the React + Vite setup in @afk/app

    master

    The @afk/app package uses a React + Vite template designed for high-performance development with Hot Module Replacement (HMR). It supports two official Vite plugins for Fast Refresh:

    1. @vitejs/plugin-react: Uses Babel for Fast Refresh.
    2. @vitejs/plugin-react-swc: Uses SWC (Speedy Web Compiler) for Fast Refresh, which is typically faster.

    This setup provides a minimal foundation for building the Open-Agent frontend application.

  2. Use the custom @lit/react wrapper

    master
    The project provides a custom wrapper for @lit/react to resolve a known issue with the official createComponent utility. Specifically, the official utility fails when properties are accessed within the Lit connectedCallback lifecycle hook. Use this custom wrapper instead of the standard @lit/react createComponent when your components rely on property access during the connectedCallback phase.
  3. How the State Module works

    master

    The State Module is a JSON-based state management system designed for the Electron main process. It uses a factory pattern to create type-safe, persistent state services.

    Key characteristics include:

    • Type-safety: Uses arktype for schema validation and TypeScript support.
    • Persistence: Automatically saves state to JSON files in the Electron userData directory.
    • Reactivity: Provides RxJS observables for subscribing to state changes.
    • Performance: Implements a debounced saving mechanism (default 1s) to prevent excessive disk I/O, with a flush() method for immediate writes.
    • IPC Integration: Includes built-in IPC handlers so the Renderer process can interact with the state.
  4. Use the effect method for one-time initialization

    master

    The effect() method in a ViewExtensionProvider is used for one-time initialization logic. It is called automatically during setup but is guaranteed to run only once per provider class, even if multiple instances of the provider are created.

    Use effect() for:

    • Initializing global state
    • Registering Lit elements
    • Setting up shared resources or global event listeners
    class MyViewProvider extends ViewExtensionProvider {
      override effect() {
        // This will only run once, even if multiple instances are created
        initializeGlobalState();
        registerLitElements();
        setupGlobalEventListeners();
      }
    }
  5. Prerequisites for Open Agent development

    master

    To develop on Open Agent, ensure your environment meets the following requirements:

    • Node.js: Version 18–22 (Node < 23 is required).
    • Yarn: Version 4 (Berry). The repository specifies packageManager: yarn@4.9.1.
    • Rust: A valid Rust toolchain must be installed for native package compilation.
    • Docker: Docker and Docker Compose (Orbstack is recommended).
  6. Interact with state from the Renderer process via IPC

    master

    The state module provides built-in IPC handlers to allow the Electron Renderer process to interact with the main process state.

    // In renderer process
    import { ipcRenderer } from 'electron';
    
    // Get state
    const state = await ipcRenderer.invoke('getState');
    
    // Update state
    await ipcRenderer.invoke('updateState', {
      userPreferences: {
        recentFiles: ['file1.txt', 'file2.txt'],
      },
    });
    
    // Listen to state changes
    ipcRenderer.on('state', (_, state) => {
      console.log('State updated:', state);
    });
    
    // Force immediate save from renderer
    await ipcRenderer.invoke('flushState');
  7. Use the Open-Agent Monorepo CLI

    master
    The Open-Agent Monorepo CLI (oa) is used to manage tasks across the monorepo, including running builds, development servers, cleaning workspace artifacts, and initializing the repository. You can access the help menu using yarn oa -h.
    yarn oa -h
  8. Run build and dev commands via the CLI

    master

    You can trigger commands defined in a package's package.json using the oa command.

    To run a build command (e.g., for i18n): yarn oa i18n build or yarn build -p i18n.

    To run a development command (e.g., for web): yarn oa web dev or yarn dev -p i18n.

    # Build
    yarn oa i18n build
    
    # Dev
    yarn oa web dev
  9. Implement and Manage Store Extensions

    master

    Store extensions are managed via the StoreExtensionManager.

    1. Create a Provider: Extend StoreExtensionProvider and override name, schema, and setup. In setup, use context.register([...]) to register the extensions you want to include.
    2. Initialize Manager: Instantiate StoreExtensionManager with an array of your providers.
    3. Configure: Use manager.configure(ProviderClass, options) to set the configuration.
    4. Retrieve: Use manager.get('store') to access the registered extensions.
    import { StoreExtensionProvider, StoreExtensionManager } from '@blocksuite/affine-ext-loader';
    import { z } from 'zod';
    
    // Create a store provider with custom options
    class MyStoreProvider extends StoreExtensionProvider<{ cacheSize: number }> {
      override name = 'MyStoreProvider';
    
      override schema = z.object({
        cacheSize: z.number().min(0),
      });
    
      override setup(context: StoreExtensionContext, options?: { cacheSize: number }) {
        super.setup(context, options);
        context.register([Ext1, Ext2, Ext3]);
      }
    }
    
    // Create and use the store extension manager
    const manager = new StoreExtensionManager([MyStoreProvider]);
    manager.configure(MyStoreProvider, { cacheSize: 100 });
    const extensions = manager.get('store');