# lambdagentpaas โ€” Lambda Calculus Agent Platform (monorepo) [![License: BSL 1.1](https://img.shields.io/badge/License-BSL%201.1-blue.svg)](LICENSE) [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/) [![Repo](https://img.shields.io/badge/repo-kenny67nju%2Flambdagentpaas-181717?logo=github)](https://github.com/kenny67nju/lambdagentpaas) **lambdagentpaas** is a full-stack platform for building, deploying, and serving AI agents defined in a Lambda-calculus DSL. The monorepo contains the language, the backend, the web UI, and ~10 example agents shipped to production. > ๐Ÿ“– **New here?** Start with [`docs/INTRODUCTION.md`](docs/INTRODUCTION.md) for a project-level overview, then read this README for the DSL deep-dive. ## v1.0 scope and deliberate non-goals This first release prioritizes **predictable, single-deployment usage over breadth**. The audit ([`docs/AUDIT_2026-06-05.md`](docs/AUDIT_2026-06-05.md)) led to a series of *subtractions* before the first tag: - **Deleted:** the Feishu bot integration (`agentpaas/api/v1/feishu.py` + `agentpaas/services/feishu.py`) โ€” it was an unfinished dev-stage surface that handed `process`-wide bot-rebind capability to anyone reaching port 8000. Will return in v2 with proper signing. - **Deleted:** `agentexample/agent67/tools/shell_executor.py` โ€” LLM-controlled shell with a substring blocklist (RCE-via-prompt-injection). Was never wired into agent67's actual tool registry; the file is gone now too. - **Hardened:** `POST /api/v1/setup/bootstrap` only accepts loopback callers. Production deploys behind a reverse proxy should use the `agentpaas` CLI to create the initial tenant. - **Single-tenant assumption:** while the data model carries `tenant_id` columns and the audit found the scoping mostly correct, v1.0 is **intended for single-tenant deployments**. Multi-tenant requires the full RBAC + integration-test pass deferred to v2. - **Sample agents are samples:** `agentexample/qaagent67lambda` ships with `/home/67/knowledge/finance` paths โ€” treat as a reference implementation requiring path customization, not a turn-key template. Things v1.0 is **good for:** running the lambdagent DSL kernel, executing YAML-defined agents through the PaaS API, building a knowledge base, using the web UI for chat/run/inspection, deploying via Docker Compose or the native scripts. Things v1.0 is **not yet good for:** untrusted multi-tenant SaaS, knowledge-dir-as-attack-surface (no pickle for shared dirs), Feishu integration, or anything that needs the `where = [".."]` empty-wheel pre-fix tooling. ## Repository layout | Directory | What it is | Run / install | |---|---|---| | [`lambdagent/`](lambdagent/) | The core DSL โ€” Lambda-calculus agent language, runtime, MCP/A2A/RAG/sandbox. Published as a standalone package (`pip install lambdagent`). | `pip install -e lambdagent/` | | [`agentpaas/`](agentpaas/) | PaaS layer โ€” REST API, CLI, agent registry, run workspace, knowledge-base management. Wraps `lambdagent` for multi-tenant serving. | `python3 -m agentpaas serve` | | [`webui/`](webui/) | React + Vite frontend โ€” agent editor, chat, run inspector, knowledge-base UI. | `cd webui && npm run dev` | | [`agentexample/`](agentexample/) | Concrete agents in production: `physics67` (research pipeline), `qaagent67*` (RAG QA), `travelagent67`, `pptagent67`, `research67`, `agent67`, etc. | See each subdir's README | | [`lambdagent_guard/`](lambdagent_guard/) | Static-analysis & runtime safety layer for compiled Lambda terms. | imported by `agentpaas` | | [`deploy/`](deploy/) | Native install + start/stop scripts (Bash, PowerShell, batch). | `bash deploy/install-native.sh && bash deploy/start.sh` | | [`docker-compose.yml`](docker-compose.yml) (repo root) | One-click Docker Compose deployment. | `docker compose up -d` | | [`demo/`](demo/) | End-to-end demos (notebooks, scripts) for talks and onboarding. | โ€” | | [`docs/`](docs/) | Design docs, architecture, audits, comparison studies, [INTRODUCTION.md](docs/INTRODUCTION.md). | โ€” | | [`tests/`](tests/) | 189+ pytest suite across DSL, compiler, runtime, cost vectors, algebraic laws, AgentPack e2e. | `pytest tests/` | ## OntoRefactor data-governance platform The monorepo now includes an end-to-end governance plane based on UML/MOF M3โ€”M0 metamodeling. Business, software, and governance are composable M2 Profiles; important graph edges are reified assertions with evidence, confidence, validity, generator, and human-review state. - Semantic source: [`ontology/`](ontology/) - LambdAgent pack: [`agentexample/agentpacks/governance.ontology-steward/`](agentexample/agentpacks/governance.ontology-steward/) - REST API: `/api/v1/governance/*` (15 paths, tenant scoped) - Web UI: open **ๆ•ฐๆฎๆฒป็†** in the sidebar, then load the built-in tenant-isolation sample - Inputs: MySQL DDL, OpenAPI YAML/JSON, or JSON asset inventory - Workflow: deterministic extraction โ†’ parallel LambdAgent analysis โ†’ M0 facts/M1 candidates โ†’ validation โ†’ evidence/review โ†’ impact graph After starting AgentPaaS and the Web UI, the fastest demo is: 1. Open **ๆ•ฐๆฎๆฒป็†** and click **ๅŠ ่ฝฝ็งŸๆˆท้š”็ฆปๆ ทไพ‹**. 2. Inspect the 48-node M3โ€”M0 reference slice and its cross-Profile relations. 3. Paste DDL into **ๆ™บ่ƒฝไฝ“ๅˆ†ๆž** to create evidence-backed facts and candidates. 4. Review inferred assertions, run the governance gates, and inspect impact paths. ## Live deployments | Service | URL | Notes | |---|---|---| | maritime-qa | `http://qa.lambdagent.cn:8080` | ๆตทไบ‹ๆณ•่ง„ RAG | | ๆŠ•ๆ ‡-qa | `http://qa.lambdagent.cn:8084` | ๆŠ•ๆ ‡ๆ–‡ไปถ RAG | | clean-qa | `http://qa.lambdagent.cn:8083` | 49 docs / 1527 chunks, BM25 + Graph + Wiki | --- ## About the DSL (rest of this document) The remainder of this README documents the `lambdagent/` subpackage โ€” the Lambda-calculus DSL itself. For platform usage (REST API, web UI, deploying your own agent), see [`docs/INTRODUCTION.md`](docs/INTRODUCTION.md) and [`AGENT_GUIDE.md`](AGENT_GUIDE.md). A Python DSL that models AI agents as Lambda calculus terms. Every agent is a function, every composition is function composition, every loop is a Y combinator. This is not a metaphor โ€” it is a formal correspondence backed by a Church encoding verification. **Key insight:** An (M, D) pair โ€” a language model M plus a dataset/prompt D โ€” is isomorphic to a Lambda term. `LLM + Dataset = Lambda term`. **Stats:** ~13,500 lines of Python | 197 exported symbols | 4 patents filed ## Highlights - **Unified LLM Provider System** -- 4 providers cover all major backends: Claude Code (via Max Plan), Anthropic API, OpenAI-compatible (DashScope / DeepSeek / Moonshot / Zhipu), and Ollama (local). Switch with one line of YAML. - **Zero-Hallucination Conversations** -- `ConversationLam` maintains full session persistence so the model never loses context mid-conversation, eliminating the hallucination caused by truncated history. - **Claude Code Max Plan -- No API Key** -- Set `provider: claude-code` and use your Claude Code subscription directly. No API key, no billing dashboard, no environment variables. - **YAML-Driven Configuration** -- Define agents, tools, memory, and provider settings in a single YAML file. `from_config()` compiles it into a typed Lambda term tree. ### Quick Start (Simplest Path) ```yaml # agent-config.yml model: provider: claude-code name: sonnet ``` ```bash # Interactive chat python3 -m agentpaas chat lambda # Or run the example agent directly python3 agentexample/agent67/run.py --claude ``` No API key required -- uses your Claude Code Max Plan subscription. ### Provider Comparison | Provider | Config value | API Key needed | Notes | |----------|-------------|----------------|-------| | Claude Code (Max Plan) | `claude-code` | No | Uses local Claude Code subscription | | Anthropic API | `anthropic` | Yes (`ANTHROPIC_API_KEY`) | Direct Claude API access | | OpenAI-compatible | `dashscope` / `openai` / `deepseek` / `zhipu` / `moonshot` | Yes | Any OpenAI-compatible endpoint | | Ollama (local) | `ollama` | No | Runs models locally, requires Ollama installed | ## Features ### Core Constructs (Lambda Calculus) lambdagent maps 11 core agent constructs to Lambda calculus, giving each one a precise denotational semantics: | # | Lambda Calculus | DSL Construct | Description | |----|--------------------------|-------------------------------|---------------------------------| | 1 | Lambda abstraction `ฮปx.body` | `Lam(name, prompt)` | An LLM with a system prompt | | 2 | Application `(f x)` | `agent(input)` | Run agent on input | | 3 | Composition `ฮปx.g(f(x))`| `f >> g` | Pipeline / chain | | 4 | Church conditional `IF` | `If(cond, then_, else_)` | Conditional branching | | 5 | Y combinator | `Loop(body, condition)` | Iterative reasoning (ReAct) | | 6 | Church pair `PAIR` | `Pair(f, g)` | Run two agents, return both | | 7 | Projections `FST / SND` | `Fst() / Snd()` | Extract from pair | | 8 | Primitive / Oracle | `Tool(name, fn)` | External tool call | | 9 | Generalized CASE | `Route(classifier, routes)` | Multi-way dispatch | | 10 | Dependent type `{x:T\|P(x)}` | `Guard(agent, validator)` | Output validation | | 11 | Environment extension | `Memory(agent, store)` | Persistent context | Plus `Par(f, g)` as syntactic sugar for parallel execution (via `|` operator). ### Multi-Agent Constructs (pi-calculus extension) | # | Process Calculus | DSL Construct | Description | |----|---------------------------|-------------------------------|---------------------------------| | 12 | Channel `c!(v)` / `c?(x)` | `Channel` + `Send` + `Receive` | Inter-agent communication | | 13 | Shared environment | `SharedMemory` | Thread-safe shared state | | 14 | Y_n(Loop + Route) | `GroupChat` | Multi-agent group discussion | | 15 | Dynamic CASE | `Handoff` | Runtime dynamic delegation | | 16 | Concurrent beta-reduction | `AsyncPar` | Thread-pool true parallelism | ### Skill System | Construct | Description | |----------------|-------------------------------------------------| | `Skill` | Named, reusable Lambda term with metadata | | `SkillPack` | Collection of related skills (like a package) | | `SkillRegistry`| Global singleton registry with search/discover | | `SkillAgent` | Auto-discovers and executes best skill | | `@skill` | Decorator to create and register skills | ### Protocol Integrations | Module | Protocol | Description | |-----------------|----------------|--------------------------------------------| | `MCPServer/Tool`| MCP 2025-11-25 | Connect to MCP servers (HTTP + stdio) | | `A2AServer/Client` | Google A2A v0.3 | Publish/discover/call remote agents | | `RAGTool` | -- | TF-IDF or ChromaDB retrieval-augmented gen | | `AgenticRAG` | -- | Agent decides when to retrieve | | `Checkpoint` | -- | Serialize/restore execution state to JSON | ### Sandbox (Process Isolation) | Construct | Description | |--------------------|----------------------------------------------------| | `SandboxedTool` | Tool that runs in isolated subprocess with resource limits | | `SandboxPolicy` | Security policy (timeout, memory, network, etc.) | | `SecureExecutor` | Auto-wraps all Tools in a term tree with sandbox | | `ResourceLimiter` | Applies CPU/memory/fd limits via POSIX resource | | `@sandboxed` | One-line decorator for sandboxed tool creation | ## Architecture ``` YAML Config โ”€โ”€โ†’ from_config() โ”€โ”€โ†’ Lambda Term โ”€โ”€โ†’ Runtime โ”€โ”€โ†’ Result (compiler) (Term tree) (beta-reduction) โ”Œโ”€โ”€ Multi-Agent: Channel, GroupChat, Handoff, AsyncPar โ”œโ”€โ”€ Skills: Skill, SkillPack, SkillRegistry, SkillAgent Lambda Term โ”€โ”€โ†’ Runtime โ”€โ”€โ†’ โ”œโ”€โ”€ MCP: MCPServer, MCPTool (HTTP + stdio) โ”œโ”€โ”€ A2A: AgentCard, A2AServer, A2AClient โ”œโ”€โ”€ RAG: RAGTool, AgenticRAG, SimpleVectorStore โ”œโ”€โ”€ Checkpoint: save/load execution state โ””โ”€โ”€ Sandbox: SandboxedTool, SecureExecutor, ResourceLimiter ``` The system has five layers: 1. **Core DSL** (`lambdagent.core`, `lambdagent.primitives`, `lambdagent.extensions`) โ€” the 11 core constructs as Python classes, each a subclass of `Term`. 2. **Multi-Agent** (`lambdagent.multiagent`) โ€” 5 pi-calculus constructs for inter-agent communication, group chat, dynamic delegation, and true parallelism. 3. **Skill + Protocol** (`lambdagent.skills`, `lambdagent.mcp_client`, `lambdagent.a2a`, `lambdagent.rag`, `lambdagent.checkpoint`) โ€” reusable skills, MCP/A2A protocol integration, retrieval-augmented generation, and state persistence. 4. **Compiler** (`lambdagent.fromconfig`) โ€” parses YAML configs into Lambda term trees. Includes schema validation and lint. 5. **Runtime** (`lambdagent.agentruntime`) โ€” executes Lambda terms via beta-reduction, handling LLM calls, MCP tool invocation, memory, and tracing. ๆ”ฏๆŒๅŒๆ‰ง่กŒๅผ•ๆ“Žๅˆ‡ๆข (recursive/cek/adaptive), ้€š่ฟ‡ `runtime.engine` ้…็ฝฎใ€‚CEK ๅผ•ๆ“Žๆไพ›้€ๆญฅๆˆๆœฌ็›‘ๆŽงใ€ๆš‚ๅœ/ๆขๅคๅ’Œๅพช็Žฏๆฃ€ๆต‹่ƒฝๅŠ›ใ€‚ ## Installation ```bash pip install lambdagent ``` For LLM provider support: ```bash pip install lambdagent[anthropic] # Anthropic Claude pip install lambdagent[openai] # OpenAI-compatible (Dashscope, etc.) ``` ## Quick Start ### Python DSL ```python from lambdagent import Lam, Compose, Loop, Tool, Memory # A single agent is a Lambda abstraction writer = Lam("writer", "You are a technical writer. Write clear documentation.") # Composition is function composition reviewer = Lam("reviewer", "Review the text for clarity and correctness.") pipeline = writer >> reviewer # = lambda x. reviewer(writer(x)) # ReAct agent is a Y combinator # `condition` takes (result, step_index) and returns bool; # `max_steps` is the unfolding bound (default 10). searcher = Tool("search", lambda q: web_search(q)) researcher = Loop( body=Lam("think", "Analyze the question. Use search if needed."), condition=lambda result, step: "DONE" in result, max_steps=10, ) # Add memory for persistent context. # `store` is an optional dict of {key: value} pre-loaded into the agent's # environment; further entries are added via `agent.remember(k, v)`. agent = Memory(researcher, store={"recent_topic": "LLM agents"}) # Execute = beta-reduction result = agent("What are the latest advances in LLM agents?") ``` ### YAML Configuration ```yaml agentId: research-assistant name: ResearchAssistant type: react systemPrompt: | You are a research assistant. Search for information, analyze it, and produce a comprehensive report. model: provider: dashscope name: qwen3-max-2026-01-23 temperature: 0.7 maxTokens: 4096 react: maxSteps: 15 runtime: engine: recursive # recursive | cek | adaptive memory: enabled: true strategy: local size: 20 mcp: onlineTool: example-mcp-server: - everything_get_sum localTools: - terminate ``` ```python from lambdagent import from_config agent = from_config("agent-config.yml") result = agent("Summarize recent progress in AI safety research") ``` ### Multi-Agent Group Chat ```python from lambdagent import Lam, GroupChat, SharedMemory researcher = Lam("researcher", "You are a researcher. Find evidence.") critic = Lam("critic", "You are a critic. Challenge weak arguments.") synthesizer = Lam("synthesizer", "You synthesize the discussion into conclusions.") chat = GroupChat( agents=[researcher, critic, synthesizer], max_rounds=6, scheduler="round_robin", ) result = chat("Should we invest in quantum computing?") ``` ### MCP Tool Integration ```python from lambdagent import mcp_tools, mcp_tool # Get all tools from an MCP server tools = mcp_tools("http://localhost:3000/mcp") # Or get a single tool search = mcp_tool("http://localhost:3000/mcp", "search") result = search({"query": "AI agents"}) ``` ### RAG (Retrieval-Augmented Generation) ```python from lambdagent import create_rag, AgenticRAG, Lam rag = create_rag(["Python is a programming language.", "Lambda calculus is..."]) agent = Lam("qa", "Answer questions using the provided context.") agentic = AgenticRAG(agent, rag, decider=lambda x: "?" in x) result = agentic("What is Lambda calculus?") ``` ### Checkpoint (Save/Resume) ```python from lambdagent import Context, save_context, load_context ctx = Context() agent("long running task", ctx) save_context(ctx, "checkpoint.json", last_input="long running task") # Later, resume: ctx = load_context("checkpoint.json") agent("continue from here", ctx) ``` ### Sandbox (Process Isolation) ```python from lambdagent import SandboxedTool, SandboxPolicy, SecureExecutor, sandboxed # One-line decorator @sandboxed(timeout=10, memory_mb=128) def risky_calc(x): return eval(x) # Or explicit construction with policy presets tool = SandboxedTool("calc", lambda x: eval(x), policy=SandboxPolicy.strict()) # Secure an entire term tree โ€” wraps all Tools in sandboxes secure_tree = SecureExecutor(policy=SandboxPolicy.default()).sandbox_all_tools(agent) ``` ### One-Sentence Agent Builder ```bash python experiments/nl2agent.py "Build a research assistant that can search the web and write reports, up to 20 steps, with memory" ``` Or programmatically: ```python from experiments.nl2agent import one_sentence_to_agent one_sentence_to_agent( "Build a code review pipeline: check security, then style, then performance", user_input="Review this Python function: def login(u, p): ...", ) ``` ## CLI Usage ```bash # Compile YAML to Lambda term (no execution) lambdagent compile agent-config.yml # Compile and execute lambdagent run agent-config.yml "Write a quicksort in Python" # Interactive REPL lambdagent repl agent-config.yml # Static analysis (lint) lambdagent lint agent-config.yml # Export pure Lambda expression lambdagent lambda agent-config.yml # Unix pipes work (composition = pipe) echo "Hello world" | lambdagent run agent-config.yml - ``` ## API Reference ### Core Terms (11 constructs) - **`Term`** โ€” Abstract base class. All constructs are Terms. - **`Context`** โ€” Evaluation environment with beta-reduction tracing. - **`Lam(name, prompt)`** โ€” Lambda abstraction. Wraps an LLM call. - **`Compose(f, g)` / `f >> g`** โ€” Function composition. - **`If(cond, then_, else_)`** โ€” Church conditional. - **`Loop(body, condition)`** โ€” Y combinator with termination. - **`Pair(f, g)` / `Par(f, g)`** โ€” Church pair / parallel execution. - **`Fst()` / `Snd()`** โ€” Pair projections. - **`Tool(name, fn)`** โ€” External oracle (MCP tool, shell command, etc.). - **`Route(classifier, routes)`** โ€” Generalized Church boolean (CASE). - **`Guard(agent, validator)`** โ€” Dependent type / output validation. - **`Memory(agent, store)`** โ€” Environment extension with persistent state. ### Multi-Agent (5 constructs) - **`Channel(name, capacity)`** โ€” pi-calculus channel for inter-agent communication. - **`Send(agent, channel)`** โ€” Send agent output to channel. - **`Receive(channel, handler)`** โ€” Receive from channel, optionally process with handler. - **`SharedMemory(store, append_only)`** โ€” Thread-safe shared state across agents. - **`GroupChat(agents, scheduler, max_rounds)`** โ€” Multi-agent group discussion (Y + Route). - **`Handoff(selector, registry, fallback)`** โ€” Runtime dynamic delegation. - **`AsyncPar(*agents)`** โ€” True parallel execution via thread pool. ### Skill System - **`Skill(name, term, description, signature, tags)`** โ€” Named, reusable Lambda term with metadata. - **`SkillPack(name)`** โ€” Collection of related skills. - **`SkillRegistry()`** โ€” Global singleton registry (search, discover, build_route). - **`SkillAgent(classifier, registry)`** โ€” Auto-discovers and executes best skill. - **`@skill(name, description, tags)`** โ€” Decorator to create and auto-register skills. ### MCP Client - **`MCPServer.http(url)` / `MCPServer.stdio(command)`** โ€” Connect to MCP servers. - **`MCPTool(server, tool_name)`** โ€” MCP tool wrapped as lambdagent Term. - **`mcp_tools(url)`** โ€” One-liner to get all tools from a server. - **`mcp_tool(url, name)`** โ€” One-liner to get a single tool. ### A2A Protocol - **`AgentCard`** โ€” A2A Agent capability description (JSON). - **`A2AServer(agent, port)`** โ€” Publish agent as A2A HTTP service. - **`A2AClient(url)`** โ€” Call remote A2A agent as local Term. - **`skill_to_agent_card(skill)`** โ€” Convert Skill to AgentCard. ### RAG - **`RAGTool(store, top_k)`** โ€” Retrieval tool (TF-IDF or ChromaDB). - **`AgenticRAG(agent, rag, decider)`** โ€” Agent decides when to retrieve. - **`SimpleVectorStore()`** โ€” Zero-dependency TF-IDF vector store. - **`create_rag(documents, top_k)`** โ€” One-liner to create RAG tool. ### Checkpoint - **`Checkpoint(context, shared_data)`** โ€” Execution state snapshot. - **`CheckpointManager(directory)`** โ€” Manage multiple checkpoints with auto-cleanup. - **`save_context(ctx, path)` / `load_context(path)`** โ€” Save/restore Context. ### Sandbox - **`SandboxedTool(name, fn, policy)`** โ€” Tool running in isolated subprocess with resource limits. - **`SandboxPolicy(timeout, memory_mb, network, ...)`** โ€” Security policy. Presets: `.strict()`, `.default()`, `.permissive()`. - **`SecureExecutor(policy)`** โ€” Auto-wraps all Tools in a term tree via `sandbox_all_tools()`. - **`ResourceLimiter`** โ€” Applies POSIX `RLIMIT_CPU`, `RLIMIT_AS`, `RLIMIT_NOFILE`, `RLIMIT_NPROC`. - **`@sandboxed(timeout, memory_mb, ...)`** โ€” Decorator for one-line sandboxed tool creation. - **Exceptions:** `SandboxViolation`, `TimeoutViolation`, `MemoryViolation`, `OutputViolation`. ### Compiler - **`from_config(path_or_dict)`** โ€” YAML to Lambda term. - **`lint_config(path_or_dict)`** โ€” Static analysis. - **`to_lambda_expr(path_or_dict)`** โ€” Export formal Lambda expression. - **`describe_config(path_or_dict)`** โ€” Human-readable structure description. ### Runtime - **`Runtime`** โ€” Executes Lambda terms with LLM backends. - **`ReActEngine`** โ€” Implements the Y combinator loop for ReAct agents. - **`MCPClient`** โ€” Model Context Protocol tool invocation. - **`TraceStore`** โ€” Records beta-reduction traces for debugging. ## Theory lambdagent is grounded in a formal correspondence between agent constructs and Lambda calculus: - **Church encoding verification**: All 11 constructs are shown to be encodable as pure Lambda terms. The `If` construct uses Church booleans, `Pair`/`Fst`/`Snd` use Church pairs, and `Route` uses generalized Church numerals. - **S+K completeness**: The DSL is computationally complete โ€” `Lam` and application together can encode `S` and `K` combinators, from which all computable functions follow. - **Y combinator semantics**: `Loop` is not ad-hoc iteration; it is the Y combinator `Y = ฮปf.(ฮปx.f(x x))(ฮปx.f(x x))` with a bounded unfolding (`max_iterations`) to ensure termination. For the full formal treatment, see [`docs/INTRODUCTION.md`](docs/INTRODUCTION.md) and the design docs under [`docs/`](docs/) (Church-encoding proofs, cost-vector semantics, algebraic laws). ## License [Business Source License 1.1](LICENSE) โ€” Copyright (c) 2025 kenny67nju Non-production use (development, testing, personal projects, academic research) is always permitted. Production use is free for organizations with โ‰ค10 individual users or employees. On **2031-04-05** (the Change Date), the license automatically converts to Apache License 2.0. For production use beyond the 10-user limit before the Change Date, contact the licensor for a commercial license. ## Citation If you use lambdagent in academic work, please cite: ```bibtex @software{lambdagentpaas2025, title = {lambdagentpaas: A Lambda Calculus Agent Platform}, author = {kenny67nju}, year = {2025}, url = {https://github.com/kenny67nju/lambdagentpaas}, } ``` To cite the DSL specifically (the `lambdagent/` subpackage, also published standalone on PyPI): ```bibtex @software{lambdagent2025, title = {lambdagent: A Lambda Calculus Agent DSL}, author = {kenny67nju}, year = {2025}, url = {https://github.com/kenny67nju/lambdagent}, } ```