Skip to main content

Contributing to Cortex

Thank you for your interest in contributing to Cortex! This document provides guidelines and instructions for contributing to the project.

๐ŸŒŸ Ways to Contributeโ€‹

  • Bug Reports: Found a bug? Open an issue with detailed reproduction steps
  • Feature Requests: Have an idea? Share it in GitHub Discussions first
  • Code Contributions: Submit pull requests for bug fixes or new features
  • Documentation: Improve docs, add examples, fix typos
  • Community Support: Help others in Discussions and Discord
  • Testing: Test pre-releases and provide feedback

๐Ÿš€ Getting Startedโ€‹

Prerequisitesโ€‹

  • Node.js 18+ and npm 9+
  • TypeScript 5.0+
  • A Convex account (free tier works great)
  • Git
  • Familiarity with AI/LLM concepts

Development Setupโ€‹

  1. Fork and Clone

    git clone https://github.com/SaintNick1214/cortex.git
    cd cortex
  2. Install Dependencies

    npm install
  3. Set Up Convex

    npx convex dev

    This creates a local dev deployment. Follow the prompts to authenticate.

  4. Configure Environment

    cp .env.example .env.local
    # Edit .env.local with your Convex URL
  5. Run Tests

    npm test
  6. Build

    npm run build

Project Structureโ€‹

cortex/
โ”œโ”€โ”€ src/ # Source code
โ”‚ โ”œโ”€โ”€ memory/ # Memory operations
โ”‚ โ”œโ”€โ”€ agents/ # Agent management
โ”‚ โ”œโ”€โ”€ contexts/ # Context chains
โ”‚ โ”œโ”€โ”€ users/ # User profiles
โ”‚ โ”œโ”€โ”€ analytics/ # Access analytics
โ”‚ โ””โ”€โ”€ types/ # TypeScript types
โ”œโ”€โ”€ convex/ # Convex backend functions
โ”‚ โ”œโ”€โ”€ memories.ts # Memory CRUD operations
โ”‚ โ”œโ”€โ”€ search.ts # Vector search logic
โ”‚ โ”œโ”€โ”€ contexts.ts # Context chain operations
โ”‚ โ””โ”€โ”€ schema.ts # Convex schema definitions
โ”œโ”€โ”€ tests/ # Test files
โ”‚ โ”œโ”€โ”€ unit/ # Unit tests
โ”‚ โ”œโ”€โ”€ integration/ # Integration tests
โ”‚ โ””โ”€โ”€ e2e/ # End-to-end tests
โ”œโ”€โ”€ docs/ # Documentation
โ”œโ”€โ”€ examples/ # Example applications
โ””โ”€โ”€ scripts/ # Build and utility scripts

๐Ÿ“ Code Standardsโ€‹

TypeScript Guidelinesโ€‹

  • Strict Mode: All code must pass strict: true type checking
  • Explicit Types: Use explicit return types for public functions
  • No any: Avoid any type; use unknown if needed
  • Interfaces over Types: Prefer interfaces for object shapes
  • ESM: Use ES modules (import/export)
// Good
export interface MemoryEntry {
id: string;
memorySpaceId: string;
content: string;
embedding: number[];
metadata: MemoryMetadata;
createdAt: Date;
}

export async function storeMemory(
memorySpaceId: string,
entry: Omit<MemoryEntry, "id" | "createdAt">,
): Promise<MemoryEntry> {
// Implementation
}

// Bad
export function storeMemory(memorySpaceId: any, entry: any): any {
// Implementation
}

Code Styleโ€‹

  • Formatting: Use Prettier (run npm run format)
  • Linting: Use ESLint (run npm run lint)
  • Naming:
    • camelCase for variables and functions
    • PascalCase for classes and interfaces
    • UPPER_SNAKE_CASE for constants
    • Descriptive names over abbreviations

Error Handlingโ€‹

// Use custom error classes
export class CortexError extends Error {
constructor(
message: string,
public code: string,
public context?: Record<string, unknown>,
) {
super(message);
this.name = "CortexError";
}
}

// Always provide context
throw new CortexError("Failed to store memory", "MEMORY_STORE_FAILED", {
agentId,
memoryId,
});

Testingโ€‹

  • Coverage: Aim for 80%+ code coverage
  • Unit Tests: Test individual functions in isolation
  • Integration Tests: Test Convex function calls
  • E2E Tests: Test complete user workflows
  • Test Files: Co-locate with source (*.test.ts)
// Example test
describe("memory.remember", () => {
it("should store a conversation with ACID + Vector", async () => {
const cortex = new Cortex({ convexUrl: testConvexUrl });

const result = await cortex.memory.remember({
memorySpaceId: "agent-1",
conversationId: "test-conv-1",
userMessage: "Test message",
agentResponse: "Test response",
userId: "test-user",
userName: "Tester",
importance: 50,
});

expect(result.conversation.messageIds).toHaveLength(2);
expect(result.memories).toHaveLength(2);
expect(result.memories[0].conversationRef).toBeDefined();
});

it("should store system memory in Vector layer", async () => {
const memory = await cortex.vector.store("agent-1", {
content: "Test system memory",
contentType: "raw",
source: { type: "system", timestamp: new Date() },
metadata: { importance: 50 },
});

expect(memory.id).toBeDefined();
expect(memory.agentId).toBe("agent-1");
expect(memory.source.type).toBe("system");
});
});

๐Ÿ”„ Development Workflowโ€‹

1. Create a Branchโ€‹

git checkout -b feature/your-feature-name
# or
git checkout -b fix/your-bug-fix

Branch naming:

  • feature/ - New features
  • fix/ - Bug fixes
  • docs/ - Documentation changes
  • refactor/ - Code refactoring
  • test/ - Test improvements

2. Make Changesโ€‹

  • Write clear, focused commits
  • Follow code standards
  • Add tests for new functionality
  • Update documentation if needed

3. Test Locallyโ€‹

# Run all tests
npm test

# Run specific test file
npm test -- memory.test.ts

# Run with coverage
npm run test:coverage

# Type check
npm run type-check

# Lint
npm run lint

# Format
npm run format

4. Commitโ€‹

Write clear commit messages following Conventional Commits:

<type>(<scope>): <description>

[optional body]

[optional footer]

Types:

  • feat: New feature
  • fix: Bug fix
  • docs: Documentation changes
  • style: Code style changes (formatting, etc.)
  • refactor: Code refactoring
  • test: Test changes
  • chore: Build process or tooling changes

Examples:

feat(memory): add support for custom vector dimensions

fix(search): resolve multi-strategy fallback issue

docs(readme): update quick start example

test(contexts): add tests for context chain traversal

5. Push and Create PRโ€‹

git push origin feature/your-feature-name

Then create a Pull Request on GitHub with:

  • Clear title and description
  • Reference related issues (Fixes #123)
  • Screenshots/videos if UI changes
  • Test results
  • Breaking changes noted

๐Ÿ“‹ Pull Request Checklistโ€‹

Before submitting, ensure:

  • Code follows TypeScript and style guidelines
  • Tests added/updated and passing
  • Documentation updated if needed
  • No linter errors or warnings
  • Commit messages follow Conventional Commits
  • PR description clearly explains changes
  • Related issues referenced
  • Breaking changes documented
  • Examples updated if API changed

๐Ÿงช Testing Guidelinesโ€‹

Unit Testsโ€‹

Test individual functions in isolation:

describe("extractTags", () => {
it("should extract finance tags", () => {
const tags = extractTags("Budget review meeting");
expect(tags).toContain("finance");
});
});

Integration Testsโ€‹

Test Convex function interactions:

describe('memory integration', () => {
it('should store and retrieve memory', async () => {
const stored = await storeMemory(ctx, { ... });
const retrieved = await getMemory(ctx, stored._id);
expect(retrieved).toMatchObject(stored);
});
});

E2E Testsโ€‹

Test complete workflows:

describe("chatbot memory workflow", () => {
it("should remember user preferences across sessions", async () => {
// Store preference (Layer 3 - ACID + Vector)
await cortex.memory.remember({
memorySpaceId: "agent-1",
conversationId: "conv-1",
userMessage: "I prefer email notifications",
agentResponse: "I'll remember that",
userId: "user-1",
userName: "User",
});

// New session - search (Layer 3 - searches Vector)
const memories = await cortex.memory.search("agent-1", "preference");

// Verify retrieval
expect(memories[0].content).toContain("email notifications");
expect(memories[0].conversationRef).toBeDefined(); // Has ACID link
});
});

๐Ÿ“š Documentation Guidelinesโ€‹

Code Documentationโ€‹

  • Use JSDoc for public APIs
  • Include examples in comments
  • Explain "why" not "what"
/**
* Stores a conversation with automatic ACID + Vector storage.
*
* This is the recommended way to store conversation memories. It handles:
* - ACID storage (Layer 1) for immutable conversation history
* - Vector indexing (Layer 2) for searchable knowledge
* - Automatic linking via conversationRef
*
* @param params - Conversation details
* @returns Result with ACID message IDs and Vector memory entries
*
* @example
* ```typescript
* const result = await cortex.memory.remember({
* memorySpaceId: 'agent-1',
* conversationId: 'conv-123',
* userMessage: 'I prefer dark mode',
* agentResponse: "I'll remember that!",
* userId: 'user-1',
* userName: 'Alex',
* generateEmbedding: async (content) => await embed(content),
* importance: 70,
* tags: ['preferences']
* });
* // Stores in ACID + creates Vector memories with conversationRef
* ```
*/
export async function remember(
params: RememberParams,
): Promise<RememberResult> {
// Implementation
}

Markdown Documentationโ€‹

  • Use clear, descriptive headings
  • Include code examples
  • Add table of contents for long docs
  • Link related documentation
  • Include "Last Updated" date

๐Ÿ› Bug Reportsโ€‹

Good bug reports include:

  1. Clear Title: Summarize the issue
  2. Description: What happened vs. what should happen
  3. Reproduction Steps: Minimal steps to reproduce
  4. Environment: OS, Node version, Cortex version
  5. Code Sample: Minimal reproducible example
  6. Error Messages: Full error output
  7. Screenshots: If applicable

Template:

### Description

Brief description of the bug

### Steps to Reproduce

1. Initialize Cortex with...
2. Call memory.store with...
3. See error

### Expected Behavior

What should happen

### Actual Behavior

What actually happens

### Environment

- OS: macOS 14.0
- Node: v20.10.0
- Cortex: v0.1.0
- Convex: v1.8.0

### Code Sample

\`\`\`typescript
// Minimal reproduction
\`\`\`

### Error Output

\`\`\`
Full error stack trace
\`\`\`

๐ŸŽฏ Feature Requestsโ€‹

For feature requests:

  1. Start a Discussion: Post in GitHub Discussions first
  2. Describe Use Case: Why is this needed?
  3. Propose API: What would the API look like?
  4. Consider Alternatives: What other approaches exist?
  5. Gauge Interest: See if others want it too

๐Ÿ“œ Code of Conductโ€‹

Our Pledgeโ€‹

We are committed to providing a welcoming and inclusive environment for all contributors, regardless of:

  • Experience level
  • Gender identity and expression
  • Sexual orientation
  • Disability
  • Personal appearance
  • Body size
  • Race
  • Ethnicity
  • Age
  • Religion
  • Nationality

Expected Behaviorโ€‹

  • Be respectful and considerate
  • Welcome newcomers
  • Focus on constructive feedback
  • Accept responsibility for mistakes
  • Prioritize community well-being

Unacceptable Behaviorโ€‹

  • Harassment or discrimination
  • Trolling or insulting comments
  • Personal or political attacks
  • Publishing private information
  • Spam or self-promotion

๐Ÿ† Recognitionโ€‹

Contributors are recognized in:

  • What's New for each release
  • GitHub contributors page
  • Annual contributor spotlight posts

๐Ÿ“ž Questions?โ€‹

๐Ÿ“„ Licenseโ€‹

By contributing, you agree that your contributions will be licensed under the Functional Source License (FSL-1.1-Apache-2.0).

This includes:

  • Copyright License: You grant the project a license to use your code
  • Patent License: You grant a license to any patents covering your contribution
  • Patent Retaliation: If you sue over patents, your license terminates
  • Future Apache 2.0: Each version becomes Apache 2.0 licensed two years after release

This protects both contributors and users. See LICENSE.md for full details.


Thank you for helping make Cortex better! ๐ŸŽ‰