diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..85b1cb9e3 --- /dev/null +++ b/CONTRIBUTING.md @@ -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! 🎉 + diff --git a/README.md b/README.md index bf87693af..cf2ea1fe1 100644 --- a/README.md +++ b/README.md @@ -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) @@ -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 diff --git a/content/brief-history-of-software.md b/content/brief-history-of-software.md index 595973963..64871c045 100644 --- a/content/brief-history-of-software.md +++ b/content/brief-history-of-software.md @@ -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) diff --git a/packages/create-12-factor-agent/template/README.md b/packages/create-12-factor-agent/template/README.md index 6b2a41303..ae1e1873f 100644 --- a/packages/create-12-factor-agent/template/README.md +++ b/packages/create-12-factor-agent/template/README.md @@ -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. @@ -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/). @@ -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. @@ -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 diff --git a/workshops/2025-05-17/sections/00-hello-world/README.md b/workshops/2025-05-17/sections/00-hello-world/README.md index bc004e015..317796e5b 100644 --- a/workshops/2025-05-17/sections/00-hello-world/README.md +++ b/workshops/2025-05-17/sections/00-hello-world/README.md @@ -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. diff --git a/workshops/2025-05-17/sections/01-cli-and-agent/README.md b/workshops/2025-05-17/sections/01-cli-and-agent/README.md index 882448f5c..ad6478211 100644 --- a/workshops/2025-05-17/sections/01-cli-and-agent/README.md +++ b/workshops/2025-05-17/sections/01-cli-and-agent/README.md @@ -188,7 +188,7 @@ export async function agentLoop(thread: Thread): Promise { -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/). diff --git a/workshops/2025-05-17/sections/02-calculator-tools/README.md b/workshops/2025-05-17/sections/02-calculator-tools/README.md index 1cbc621a3..6cce8ca03 100644 --- a/workshops/2025-05-17/sections/02-calculator-tools/README.md +++ b/workshops/2025-05-17/sections/02-calculator-tools/README.md @@ -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. diff --git a/workshops/2025-05-17/walkthrough.md b/workshops/2025-05-17/walkthrough.md index b1701e47d..fb0397cfd 100644 --- a/workshops/2025-05-17/walkthrough.md +++ b/workshops/2025-05-17/walkthrough.md @@ -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. @@ -341,7 +341,7 @@ export async function agentLoop(thread: Thread): Promise { -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/). @@ -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. @@ -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 diff --git a/workshops/2025-05-17/walkthrough.yaml b/workshops/2025-05-17/walkthrough.yaml index 0d3807a5b..bca5074a5 100644 --- a/workshops/2025-05-17/walkthrough.yaml +++ b/workshops/2025-05-17/walkthrough.yaml @@ -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. @@ -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/). @@ -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} @@ -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 diff --git a/workshops/2025-05/sections/00-hello-world/README.md b/workshops/2025-05/sections/00-hello-world/README.md index bc004e015..317796e5b 100644 --- a/workshops/2025-05/sections/00-hello-world/README.md +++ b/workshops/2025-05/sections/00-hello-world/README.md @@ -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. diff --git a/workshops/2025-05/sections/01-cli-and-agent/README.md b/workshops/2025-05/sections/01-cli-and-agent/README.md index fb8265031..6a334605c 100644 --- a/workshops/2025-05/sections/01-cli-and-agent/README.md +++ b/workshops/2025-05/sections/01-cli-and-agent/README.md @@ -177,7 +177,7 @@ export async function agentLoop(thread: Thread): Promise { -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 diff --git a/workshops/2025-05/sections/02-calculator-tools/README.md b/workshops/2025-05/sections/02-calculator-tools/README.md index 6c7e33a39..2e9851117 100644 --- a/workshops/2025-05/sections/02-calculator-tools/README.md +++ b/workshops/2025-05/sections/02-calculator-tools/README.md @@ -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. diff --git a/workshops/2025-05/sections/12-humanlayer-webhook/README.md b/workshops/2025-05/sections/12-humanlayer-webhook/README.md index b44b614e4..8b14231c1 100644 --- a/workshops/2025-05/sections/12-humanlayer-webhook/README.md +++ b/workshops/2025-05/sections/12-humanlayer-webhook/README.md @@ -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 diff --git a/workshops/2025-05/sections/final/README.md b/workshops/2025-05/sections/final/README.md index 0111c848e..7494a6539 100644 --- a/workshops/2025-05/sections/final/README.md +++ b/workshops/2025-05/sections/final/README.md @@ -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. @@ -94,7 +94,7 @@ Add the agent implementation cp ./walkthrough/01-agent.ts src/agent.ts -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 @@ -129,7 +129,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. @@ -690,7 +690,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 diff --git a/workshops/2025-05/walkthrough.md b/workshops/2025-05/walkthrough.md index 8230478e5..012c97e80 100644 --- a/workshops/2025-05/walkthrough.md +++ b/workshops/2025-05/walkthrough.md @@ -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. @@ -329,7 +329,7 @@ export async function agentLoop(thread: Thread): Promise { -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 @@ -363,7 +363,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. @@ -2016,7 +2016,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 diff --git a/workshops/2025-05/walkthrough.yaml b/workshops/2025-05/walkthrough.yaml index 72169674c..f5c38f801 100644 --- a/workshops/2025-05/walkthrough.yaml +++ b/workshops/2025-05/walkthrough.yaml @@ -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. @@ -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 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 @@ -137,7 +137,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} @@ -629,7 +629,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