This project is under development phase, so you can change anything; architecture, design, API, etc. You don't need to worry about backward compatibility or breaking changes.
CURRENT Phase:
- branch main: prototyping (completed)
- branch scrap-and-build: the refactor/redesign rebuild of the runtime and compiler (completed, merged into main)
- ★ branch main: preparing the v0.1.0 release — working through the publish-audit follow-ups across language, stdlib, runtime, tooling, and docs (see
docs/2026-07-25-v0.1.0-milestones.md)
- Katari is Language to write orchestration logic for AI agents
- User writes a Katari program, which is then compiled to a IR and executed by the Katari runtime
- Katari runtime is a continuasly running server that can upload, execute and manage Katari programs
- Katari runtime persists the state of the program execution, allowing for long-running programs and recovery from failures
- In katari, parallel execution and concurrency are first-class citizens, allowing for efficient orchestration of multiple agents and tasks
- Agent: In katari, an agent is like "function" in traditional programming languages. It is a unit of execution that can perform tasks.
- Schema: Each agent has a Json schema that defines the structure of the input and output of the agent. AI agents can use this schema to understand how to interact with the agent. (as tool)
- Request: A request is "effect definition" in traditional programming languages. It defines an effect that an agent can perform.
- Effect: Each agent can perform requests. An effect is an set of requests that an agent can perform.
- Handler: A handler is a implementation of a request. It defines how to perform a request.
- IR: Intermediate Representation, which is the output of the Katari compiler and the input of the Katari runtime. It is a mid-level representation of the Katari program that can be executed by the runtime.
- Block: A block is a component of the IR that represents a definition of thread.
- Thread: A thread is a running instance of a block. Each thread has its own state.
- Delegation: In katari runtime, calling another agent is called "delegation".
- Escalation: In katari runtime, performing a request is called "escalation".
- Project: Katari users can manage their Katari programs and dependencies using a project configuration file.
- Snapshot: When uploading a Katari IR, the runtime will create a snapshot of the IR, which is an immutable version of the IR that can be executed. This allows for efficient execution and easy rollback to previous versions of the IR.
haskell: Dependency: compiler <- project <- lsp, clicompiler: Katari compiler, which compiles Katari source code to IRlsp: Language Server Protocol implementation for Katari, providing editor features like autcli: Command Line Interface for Katari, allowing users to interact with the Katari runtime and manage their programsproject: Project management library for Katari, handling project configuration and dependencies
typescriptcli: Wrapper for katari cli (haskell)runtime: Katari runtime, which executes the compiled IR and manages program stateport: Katari user can use this library in FFI to interact with the Katari runtime.bundle: Bundler for bundle FFI code (haskell cli uses this to bundle the FFI code)vscode: VSCode extension for Katariadmin-web: Web interface for managing Katari runtimetypes: Shared types
docs: Documentation for Katari, including design documents, user guides and API references
- Stack: Haskell build tool
- Pnpm: JavaScript package manager
- Ormolu: Haskell code formatter
- Hlint: Haskell linter
- Biome: JavaScript linter and formatter
- Tsc: TypeScript type checker
- Lefthook: Git hooks manager
pnpm run build: Build both haskell and typescript codepnpm run build:haskell: Build haskell codepnpm run build:typescript: Build typescript codepnpm run test: Run tests for both haskell and typescript codepnpm run test:haskell: Run tests for haskell codepnpm run test:typescript: Run tests for typescript codepnpm run test:e2e: Run the smoke e2e (e2e/): compiles examples/playground with the stack-built katari CLI and drives a real runtime server (needs docker +stack build; not part ofpnpm run test)pnpm run format: Format both haskell and typescript codepnpm run format:haskell: Format haskell code using ormolupnpm run format:typescript: Format typescript code using biomepnpm run typecheck: Typecheck both haskell and typescript codepnpm run typecheck:haskell: Typecheck haskell code using stackpnpm run typecheck:typescript: Typecheck typescript code using tscpnpm run lint: Lint both haskell and typescript codepnpm run lint:haskell: Lint haskell code using hlintpnpm run lint:typescript: Lint typescript code using biome check
Github CI will run pnpm run typecheck and pnpm run lint on every push and pull request to ensure code quality and catch errors early.
-
Do not use abbreviations in variable and function names. Exception:
idonly -
Comments should be complete sentences and explain the "why" behind the code, not the "what".
-
Comments should be concise but sufficiently explanatory.
-
Haskell
- Do not use partial functions (e.g. head, tail, fromJust, etc.)
- Use
Recordsyntax for data types with multiple fields- name duplication is allowed in difference data types (Language Extension: DuplicateRecordFields, NoFieldSelectors, OverloadedRecordDot,...) so you can simply name the fields as
inputandoutput, without prefixing them with the data type name.
- name duplication is allowed in difference data types (Language Extension: DuplicateRecordFields, NoFieldSelectors, OverloadedRecordDot,...) so you can simply name the fields as
- Use
Listfor list data types, not[T] - Use
Textfor string data types, notString - Use
casefor pattern matching, not function definitions with multiple equations-
ex)
-- bad myFunction (MyTypeA n) = ... myFunction (MyTypeB s) = ... myFunction x = case x of MyTypeA n -> ... MyTypeB s -> ...
-
-
TypeScript
- Do not use
any - Do not use
as(as possible)
- Do not use