Skip to content

Contributing Guide

Thank you for your interest in contributing to Helix Agents! This guide covers development setup, testing, and the contribution process.

Development Setup

Prerequisites

  • Node.js 18+
  • npm 9+
  • Git
  • Docker (for integration tests)

Clone and Install

bash
git clone https://github.com/your-org/helix-agents.git
cd helix-agents
npm install

Build

bash
# Build all packages
npm run build

# Watch mode for development
npm run dev

Project Structure

helix-agents/
├── packages/
│   ├── core/                 # Core types and logic
│   ├── sdk/                  # Umbrella package
│   ├── runtime-js/           # JavaScript runtime
│   ├── runtime-temporal/     # Temporal runtime
│   ├── runtime-cloudflare/   # Cloudflare runtime
│   ├── store-memory/         # In-memory stores
│   ├── store-redis/          # Redis stores
│   ├── store-cloudflare/     # Cloudflare stores
│   ├── llm-vercel/           # Vercel AI SDK adapter
│   ├── ai-sdk/               # Frontend integration
│   └── e2e/                  # End-to-end tests
├── examples/
│   ├── research-assistant/
│   ├── research-assistant-temporal/
│   └── research-assistant-cloudflare/
├── docs/                     # Documentation (VitePress)
└── turbo.json               # Turborepo configuration

Commands

Building

bash
npm run build        # Build all packages
npm run build:core   # Build specific package
npm run dev          # Watch mode

Testing

bash
npm run test                 # Unit tests
npm run test:watch           # Watch mode
npm run test:integration     # Integration tests (requires services)
npm run test:e2e             # End-to-end tests

Code Quality

bash
npm run typecheck    # TypeScript type checking
npm run lint         # ESLint
npm run lint:fix     # Auto-fix lint issues
npm run format       # Prettier formatting

Documentation

bash
npm run docs:dev     # Start dev server
npm run docs:build   # Production build
npm run docs:preview # Preview build

Testing

Unit Tests

Located in src/__tests__/*.test.ts:

typescript
// packages/core/src/__tests__/step-processor.test.ts
import { describe, it, expect } from 'vitest';
import { planStepProcessing } from '../orchestration/step-processor.js';

describe('planStepProcessing', () => {
  it('handles text response', () => {
    const plan = planStepProcessing({
      type: 'text',
      content: 'Hello',
      shouldStop: false,
    });

    expect(plan.isTerminal).toBe(false);
    expect(plan.assistantMessagePlan?.content).toBe('Hello');
  });
});

Run unit tests:

bash
npm run test
npm run test -- --coverage

Integration Tests

Located in src/__tests__/*.integ.test.ts. Require external services:

bash
# Start services
docker-compose up -d

# Run integration tests
npm run test:integration

End-to-End Tests

Located in packages/e2e/:

bash
npm run test:e2e

Adding a New Package

1. Create Directory

bash
mkdir packages/my-package
cd packages/my-package

2. Initialize Package

json
// packages/my-package/package.json
{
  "name": "@helix-agents/my-package",
  "version": "0.0.1",
  "type": "module",
  "exports": {
    ".": {
      "types": "./dist/index.d.ts",
      "default": "./dist/index.js"
    }
  },
  "files": ["dist"],
  "scripts": {
    "build": "tsup",
    "dev": "tsup --watch",
    "test": "vitest run",
    "typecheck": "tsc --noEmit"
  },
  "dependencies": {
    "@helix-agents/core": "workspace:*"
  },
  "devDependencies": {
    "tsup": "^8.0.0",
    "typescript": "^5.3.0",
    "vitest": "^1.0.0"
  },
  "publishConfig": {
    "access": "public"
  }
}

3. Add TypeScript Config

json
// packages/my-package/tsconfig.json
{
  "extends": "../../tsconfig.base.json",
  "compilerOptions": {
    "outDir": "./dist",
    "rootDir": "./src"
  },
  "include": ["src/**/*"]
}

4. Add Build Config

typescript
// packages/my-package/tsup.config.ts
import { defineConfig } from 'tsup';

export default defineConfig({
  entry: ['src/index.ts'],
  format: ['esm'],
  dts: true,
  clean: true,
  sourcemap: true,
});

5. Create Source Files

typescript
// packages/my-package/src/index.ts
export function myFunction() {
  return 'hello';
}

6. Update Turborepo

Add to turbo.json if special build requirements.

Code Style

TypeScript

  • Strict mode enabled
  • Explicit return types on public APIs
  • Use readonly for immutable properties
  • Prefer interface over type for objects
typescript
// Good
interface MyConfig {
  readonly name: string;
  count: number;
}

export function processConfig(config: MyConfig): ProcessResult {
  // ...
}

// Avoid
type MyConfig = {
  name: string;
  count: number;
};

export const processConfig = (config) => {
  // ...
};

Imports

  • Use explicit .js extensions for local imports
  • Group imports: external, then internal, then relative
typescript
// External
import { z } from 'zod';
import type { Draft } from 'immer';

// Internal workspace
import { defineAgent } from '@helix-agents/core';

// Relative
import { helper } from './utils.js';
import type { MyType } from './types.js';

Exports

  • Export types separately with export type
  • Use barrel exports in index.ts
typescript
// types.ts
export interface MyInterface { ... }
export type MyType = { ... };

// index.ts
export type { MyInterface, MyType } from './types.js';
export { myFunction } from './functions.js';

Comments

  • JSDoc for public APIs
  • Inline comments for complex logic
  • No comments for self-explanatory code
typescript
/**
 * Process an agent step and determine next actions.
 *
 * @param stepResult - The result from the LLM adapter
 * @param options - Processing options
 * @returns A plan describing what operations to perform
 */
export function planStepProcessing<TOutput>(
  stepResult: StepResult<TOutput>,
  options?: PlanStepProcessingOptions<TOutput>
): StepProcessingPlan<TOutput> {
  // Check for __finish__ tool call (signals completion)
  const finishCall = findFinishToolCall(stepResult);
  // ...
}

Pull Request Process

1. Create a Branch

bash
git checkout -b feature/my-feature
# or
git checkout -b fix/bug-description

2. Make Changes

  • Write code
  • Add tests
  • Update documentation if needed

3. Run Checks

bash
npm run typecheck
npm run lint
npm run test
npm run build

4. Add Changeset

For changes that affect published packages:

bash
npx changeset

Select affected packages and describe changes.

5. Commit

bash
git add .
git commit -m "feat: add new feature"

Commit message format:

  • feat: New feature
  • fix: Bug fix
  • docs: Documentation
  • refactor: Code refactoring
  • test: Test changes
  • chore: Build/tooling changes

6. Push and Create PR

bash
git push -u origin feature/my-feature

Create PR with:

  • Clear description
  • Link to related issues
  • Test instructions if applicable

Changesets

We use Changesets for versioning.

Adding a Changeset

bash
npx changeset
  1. Select affected packages
  2. Choose bump type (patch/minor/major)
  3. Write description

Changeset File

Creates .changeset/random-name.md:

markdown
---
'@helix-agents/core': minor
'@helix-agents/runtime-js': patch
---

Add new orchestration function for step processing

Release Process

Maintainers handle releases:

bash
# Consume changesets and update versions
npx changeset version

# Review changes
git diff

# Commit and create release PR
git add .
git commit -m "chore: version packages"
git push

# After merge, publish
npm run publish

Getting Help

  • Open an issue for bugs or feature requests
  • Discussions for questions
  • Check existing issues before creating new ones

Code of Conduct

  • Be respectful and inclusive
  • Focus on constructive feedback
  • Help others learn and grow

License

Contributions are licensed under the project's license (see LICENSE file).

See Also

Released under the MIT License.