Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
196 changes: 196 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
# Contributing to 12-Factor Agents

First off, thank you for considering contributing to 12-Factor Agents! This project aims to help developers build reliable, production-grade LLM applications, and your contributions help make that possible.

## 📋 Table of Contents

- [Code of Conduct](#code-of-conduct)
- [How Can I Contribute?](#how-can-i-contribute)
- [Reporting Issues](#reporting-issues)
- [Suggesting Enhancements](#suggesting-enhancements)
- [Documentation Improvements](#documentation-improvements)
- [Code Contributions](#code-contributions)
- [Development Setup](#development-setup)
- [Pull Request Process](#pull-request-process)
- [Style Guidelines](#style-guidelines)
- [License](#license)

## Code of Conduct

By participating in this project, you agree to maintain a welcoming and inclusive environment. Please be respectful and constructive in all interactions.

## How Can I Contribute?

### Reporting Issues

If you find a bug or have a question:

1. **Search existing issues** to avoid duplicates
2. **Create a new issue** with a clear title and description
3. **Include relevant details** like error messages, screenshots, or steps to reproduce

### Suggesting Enhancements

Have an idea for a new factor or improvement?

1. **Check the discussions** at [GitHub Discussions](https://github.com/humanlayer/12-factor-agents/discussions)
2. **Open a new discussion** to gather feedback before implementing
3. **Reference related factors** if your suggestion builds on existing content

### Documentation Improvements

Documentation contributions are highly valued! This includes:

- Fixing typos and grammatical errors
- Improving clarity of existing content
- Adding examples or use cases
- Translating content

### Code Contributions

For code contributions to the template or tools:

1. **Fork the repository**
2. **Create a feature branch** from `main`
3. **Make your changes** following our style guidelines
4. **Test your changes** thoroughly
5. **Submit a pull request**

## Development Setup

### Prerequisites

- Node.js 20+ (recommended)
- npm, yarn, or bun

### Getting Started

```bash
# Clone your fork
git clone https://github.com/YOUR_USERNAME/12-factor-agents.git
cd 12-factor-agents

# Install dependencies
make setup
# or manually: npm install

# For the template package
cd packages/create-12-factor-agent/template
npm install
```

### Running the Template Agent

```bash
cd packages/create-12-factor-agent/template

# Set up environment variables
export OPENAI_API_KEY=your_key_here
# or use BASETEN_API_KEY depending on your configuration

# Generate BAML client
npx baml-cli generate

# Run the agent
npx tsx src/index.ts "hello"
```

### Running Tests (walkthroughgen)

```bash
cd packages/walkthroughgen
npm install
npm test
```

## Pull Request Process

### Branch Naming

Use descriptive branch names:

- `docs/fix-readme-typos` - Documentation fixes
- `feat/add-new-factor` - New features
- `fix/template-bug` - Bug fixes

### Commit Messages

Follow [Conventional Commits](https://www.conventionalcommits.org/):

```
type(scope): short description

- Detailed change 1
- Detailed change 2
```

**Types:**
- `docs` - Documentation changes
- `feat` - New features
- `fix` - Bug fixes
- `chore` - Maintenance tasks
- `style` - Code style changes (formatting, etc.)
- `test` - Adding or updating tests
- `refactor` - Code refactoring

**Examples:**
```
docs(content): Fix typos in factor-03-own-your-context-window.md

- Fix spelling error 'libriaries' to 'libraries'
- Correct grammar in example code comments
```

```
feat(template): Add support for Claude as LLM provider

- Add Claude client configuration in clients.baml
- Update README with Claude setup instructions
```

### PR Checklist

Before submitting your PR:

- [ ] Code follows the project's style guidelines
- [ ] Documentation is updated if needed
- [ ] Commit messages follow conventional format
- [ ] All existing tests pass
- [ ] New functionality includes tests (if applicable)

## Style Guidelines

### Markdown

- Use ATX-style headers (`#`, `##`, etc.)
- Use fenced code blocks with language specifiers
- Keep lines under 120 characters when possible
- Use relative links for internal references

### TypeScript

- Use TypeScript for all new code
- Follow existing patterns in the codebase
- Include type annotations for function parameters and return types

### BAML

- Follow the patterns in existing `.baml` files
- Include descriptive comments for complex prompts
- Add tests for new functions

## License

By contributing to 12-Factor Agents, you agree that your contributions will be licensed under:

- **Code**: [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0)
- **Content & Images**: [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/)

## Questions?

- Join the [Discord community](https://humanlayer.dev/discord)
- Open a [GitHub Discussion](https://github.com/humanlayer/12-factor-agents/discussions)
- Check the [README](./README.md) for more resources

Thank you for contributing! 🎉

4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ We're gonna talk a lot about Directed Graphs (DGs) and their Acyclic friends, DA

### From code to DAGs

Around 20 years ago, we started to see DAG orchestrators become popular. We're talking classics like [Airflow](https://airflow.apache.org/), [Prefect](https://www.prefect.io/), some predecessors, and some newer ones like ([dagster](https://dagster.io/), [inggest](https://www.inngest.com/), [windmill](https://www.windmill.dev/)). These followed the same graph pattern, with the added benefit of observability, modularity, retries, administration, etc.
Around 20 years ago, we started to see DAG orchestrators become popular. We're talking classics like [Airflow](https://airflow.apache.org/), [Prefect](https://www.prefect.io/), some predecessors, and some newer ones like ([dagster](https://dagster.io/), [inngest](https://www.inngest.com/), [windmill](https://www.windmill.dev/)). These followed the same graph pattern, with the added benefit of observability, modularity, retries, administration, etc.

![015-dag-orchestrators](https://github.com/humanlayer/12-factor-agents/blob/main/img/015-dag-orchestrators.png)

Expand Down Expand Up @@ -180,7 +180,7 @@ Anyways back to the thing...

### Design Patterns for great LLM applications

After digging through hundreds of AI libriaries and working with dozens of founders, my instinct is this:
After digging through hundreds of AI libraries and working with dozens of founders, my instinct is this:

1. There are some core things that make agents great
2. Going all in on a framework and building what is essentially a greenfield rewrite may be counter-productive
Expand Down
2 changes: 1 addition & 1 deletion content/brief-history-of-software.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ We're gonna talk a lot about Directed Graphs (DGs) and their Acyclic friends, DA

### 20 years ago

Around 20 years ago, we started to see DAG orchestrators become popular. We're talking classics like [Airflow](https://airflow.apache.org/), [Prefect](https://www.prefect.io/), some predecessors, and some newer ones like ([dagster](https://dagster.io/), [inggest](https://www.inngest.com/), [windmill](https://www.windmill.dev/)). These followed the same graph pattern, with the added benefit of observability, modularity, retries, administration, etc.
Around 20 years ago, we started to see DAG orchestrators become popular. We're talking classics like [Airflow](https://airflow.apache.org/), [Prefect](https://www.prefect.io/), some predecessors, and some newer ones like ([dagster](https://dagster.io/), [inngest](https://www.inngest.com/), [windmill](https://www.windmill.dev/)). These followed the same graph pattern, with the added benefit of observability, modularity, retries, administration, etc.

![015-dag-orchestrators](https://github.com/humanlayer/12-factor-agents/blob/main/img/015-dag-orchestrators.png)

Expand Down
8 changes: 4 additions & 4 deletions packages/create-12-factor-agent/template/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Let's start with a basic TypeScript setup and a hello world program.

This guide is written in TypeScript (yes, a python version is coming soon)

There are many checkpoints between the every file edit in theworkshop steps,
There are many checkpoints between every file edit in the workshop steps,
so even if you aren't super familiar with typescript,
you should be able to keep up and run each example.

Expand Down Expand Up @@ -94,7 +94,7 @@ Add the agent implementation

cp ./walkthrough/01-agent.ts src/agent.ts

The the BAML code is configured to use BASETEN_API_KEY by default
The BAML code is configured to use BASETEN_API_KEY by default

To get a Baseten API key and URL, create an account at [baseten.co](https://baseten.co),
and then deploy [Qwen3 32B from the model library](https://www.baseten.co/library/qwen-3-32b/).
Expand Down Expand Up @@ -142,7 +142,7 @@ Let's add some calculator tools to our agent.

Let's start by adding a tool definition for the calculator

These are simpile structured outputs that we'll ask the model to
These are simple structured outputs that we'll ask the model to
return as a "next step" in the agentic loop.


Expand Down Expand Up @@ -709,7 +709,7 @@ workflow agent that uses webhooks for human approval



# Chapter XX - HumanLayer Webhook Integration
# Chapter 12 - HumanLayer Webhook Integration

the previous sections used the humanlayer SDK in "synchronous mode" - that
means every time we wait for human approval, we sit in a loop
Expand Down
2 changes: 1 addition & 1 deletion workshops/2025-05-17/sections/00-hello-world/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Let's start with a basic TypeScript setup and a hello world program.

This guide is written in TypeScript (yes, a python version is coming soon)

There are many checkpoints between the every file edit in theworkshop steps,
There are many checkpoints between every file edit in the workshop steps,
so even if you aren't super familiar with typescript,
you should be able to keep up and run each example.

Expand Down
2 changes: 1 addition & 1 deletion workshops/2025-05-17/sections/01-cli-and-agent/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ export async function agentLoop(thread: Thread): Promise<AgentResponse> {

</details>

The the BAML code is configured to use BASETEN_API_KEY by default
The BAML code is configured to use BASETEN_API_KEY by default

To get a Baseten API key and URL, create an account at [baseten.co](https://baseten.co),
and then deploy [Qwen3 32B from the model library](https://www.baseten.co/library/qwen-3-32b/).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Let's add some calculator tools to our agent.

Let's start by adding a tool definition for the calculator

These are simpile structured outputs that we'll ask the model to
These are simple structured outputs that we'll ask the model to
return as a "next step" in the agentic loop.


Expand Down
8 changes: 4 additions & 4 deletions workshops/2025-05-17/walkthrough.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Let's start with a basic TypeScript setup and a hello world program.

This guide is written in TypeScript (yes, a python version is coming soon)

There are many checkpoints between the every file edit in theworkshop steps,
There are many checkpoints between every file edit in the workshop steps,
so even if you aren't super familiar with typescript,
you should be able to keep up and run each example.

Expand Down Expand Up @@ -341,7 +341,7 @@ export async function agentLoop(thread: Thread): Promise<AgentResponse> {

</details>

The the BAML code is configured to use BASETEN_API_KEY by default
The BAML code is configured to use BASETEN_API_KEY by default

To get a Baseten API key and URL, create an account at [baseten.co](https://baseten.co),
and then deploy [Qwen3 32B from the model library](https://www.baseten.co/library/qwen-3-32b/).
Expand Down Expand Up @@ -388,7 +388,7 @@ Let's add some calculator tools to our agent.

Let's start by adding a tool definition for the calculator

These are simpile structured outputs that we'll ask the model to
These are simple structured outputs that we'll ask the model to
return as a "next step" in the agentic loop.


Expand Down Expand Up @@ -2095,7 +2095,7 @@ thats it - in the next chapter, we'll build a fully email-driven
workflow agent that uses webhooks for human approval


## Chapter XX - HumanLayer Webhook Integration
## Chapter 12 - HumanLayer Webhook Integration

the previous sections used the humanlayer SDK in "synchronous mode" - that
means every time we wait for human approval, we sit in a loop
Expand Down
8 changes: 4 additions & 4 deletions workshops/2025-05-17/walkthrough.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ sections:
- text: |
This guide is written in TypeScript (yes, a python version is coming soon)

There are many checkpoints between the every file edit in theworkshop steps,
There are many checkpoints between every file edit in the workshop steps,
so even if you aren't super familiar with typescript,
you should be able to keep up and run each example.

Expand Down Expand Up @@ -103,7 +103,7 @@ sections:
- text: "Add the agent implementation"
file: {src: ./walkthrough/01-agent.ts, dest: src/agent.ts}
- text: |
The the BAML code is configured to use BASETEN_API_KEY by default
The BAML code is configured to use BASETEN_API_KEY by default

To get a Baseten API key and URL, create an account at [baseten.co](https://baseten.co),
and then deploy [Qwen3 32B from the model library](https://www.baseten.co/library/qwen-3-32b/).
Expand Down Expand Up @@ -149,7 +149,7 @@ sections:
- text: |
Let's start by adding a tool definition for the calculator

These are simpile structured outputs that we'll ask the model to
These are simple structured outputs that we'll ask the model to
return as a "next step" in the agentic loop.

file: {src: ./walkthrough/02-tool_calculator.baml, dest: baml_src/tool_calculator.baml}
Expand Down Expand Up @@ -643,7 +643,7 @@ sections:
workflow agent that uses webhooks for human approval

- name: humanlayer-webhook
title: "Chapter XX - HumanLayer Webhook Integration"
title: "Chapter 12 - HumanLayer Webhook Integration"
text: |
the previous sections used the humanlayer SDK in "synchronous mode" - that
means every time we wait for human approval, we sit in a loop
Expand Down
2 changes: 1 addition & 1 deletion workshops/2025-05/sections/00-hello-world/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Let's start with a basic TypeScript setup and a hello world program.

This guide is written in TypeScript (yes, a python version is coming soon)

There are many checkpoints between the every file edit in theworkshop steps,
There are many checkpoints between every file edit in the workshop steps,
so even if you aren't super familiar with typescript,
you should be able to keep up and run each example.

Expand Down
2 changes: 1 addition & 1 deletion workshops/2025-05/sections/01-cli-and-agent/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ export async function agentLoop(thread: Thread): Promise<AgentResponse> {

</details>

The the BAML code is configured to use OPENAI_API_KEY by default
The BAML code is configured to use OPENAI_API_KEY by default

As you're testing, you can change the model / provider to something else
as you please
Expand Down
2 changes: 1 addition & 1 deletion workshops/2025-05/sections/02-calculator-tools/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Let's add some calculator tools to our agent.

Let's start by adding a tool definition for the calculator

These are simpile structured outputs that we'll ask the model to
These are simple structured outputs that we'll ask the model to
return as a "next step" in the agentic loop.


Expand Down
2 changes: 1 addition & 1 deletion workshops/2025-05/sections/12-humanlayer-webhook/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Chapter XX - HumanLayer Webhook Integration
# Chapter 12 - HumanLayer Webhook Integration

the previous sections used the humanlayer SDK in "synchronous mode" - that
means every time we wait for human approval, we sit in a loop
Expand Down
Loading