Skip to main content

pidgin_lang/
lib.rs

1//! # Pidgin — A Compact Agent Handoff Protocol & Runtime
2//!
3//! Pidgin is a small, fast, local-first **protocol and runtime** for compact, structured
4//! handoffs between AI agents, between an agent and a human operator, and between an
5//! orchestrator and the tools/executors it drives.
6//!
7//! ```text
8//! Take a compact Pidgin packet (9 lines of key=value text)
9//! → parse it
10//! → validate it against a schema and registries
11//! → run it through a safety gate
12//! → resolve short references into real paths/IDs
13//! → expand it into a fully-specified, executable packet
14//! → estimate token cost
15//! → recommend a route
16//! → log every step
17//! ```
18//!
19//! Pidgin is **not** a model, not an agent framework, not a replacement for
20//! MCP/A2A/ACP. It is a narrow waist — a deliberately minimal layer that sits
21//! between whatever produces a task and whatever executes it.
22//!
23//! # Background
24//!
25//! Every serious 2025–2026 study of multi-agent token cost reaches the same
26//! conclusion: the dominant cost and failure surface in multi-agent LLM systems
27//! is the communication layer itself, not the reasoning layer.  Replace verbose
28//! natural-language handoffs with a small, typed, validated wire format, and
29//! you cut both token use and error rate without touching the models.
30//!
31//! Pidgin formalizes that conclusion into a runtime instead of a one-off convention.
32//!
33//! # Quick Start
34//!
35//! ```bash
36//! cargo install pidgin-lang
37//!
38//! # Scaffold a host configuration
39//! pgn init
40//!
41//! # Parse a packet
42//! pgn parse examples/basic/generic_task.pgn
43//!
44//! # Full pipeline
45//! pgn run examples/basic/generic_task.pgn
46//!
47//! # Check (validate + safety + resolve)
48//! pgn check examples/basic/generic_task.pgn
49//!
50//! # Token-cost estimation
51//! pgn measure examples/basic/generic_task.pgn
52//!
53//! # Validate host configuration
54//! pgn doctor
55//! ```
56//!
57//! # Architecture
58//!
59//! The runtime is a linear pipeline — each stage is a pure function that
60//! transforms or inspects the packet:
61//!
62//! ```text
63//! Pidgin packet (.pgn text)
64//!    │
65//!    ▼
66//! ┌─────────────┐
67//! │   Lexer     │  winnow tokenizer
68//! └─────────────┘
69//!    │
70//!    ▼
71//! ┌─────────────┐
72//! │   Parser    │  builds typed AST (PgnPacket)
73//! └─────────────┘
74//!    │
75//!    ▼
76//! ┌──────────────────┐
77//! │ Syntax Validator  │  required fields present? types correct?
78//! └──────────────────┘
79//!    │
80//!    ▼
81//! ┌──────────────────┐
82//! │ Schema Validator  │  workflow/mode/risk values legal against registries
83//! └──────────────────┘
84//!    │
85//!    ▼
86//! ┌──────────────────┐
87//! │   Safety Gate     │  contradiction check, deny precedence, human-required
88//! └──────────────────┘
89//!    │
90//!    ▼
91//! ┌──────────────────┐
92//! │ Reference Resolver │ short refs → real paths/IDs with confidence scores
93//! └──────────────────┘
94//!    │
95//!    ▼
96//! ┌──────────────────┐
97//! │  Packet Expander   │  builds fully-specified executable packet (YAML)
98//! └──────────────────┘
99//!    │
100//!    ▼
101//! ┌──────────────────┐
102//! │  Context Planner   │  decides what to retrieve and how
103//! └──────────────────┘
104//!    │
105//!    ▼
106//! ┌──────────────────┐
107//! │  Token Estimator    │  estimates packet + context token cost
108//! └──────────────────┘
109//!    │
110//!    ▼
111//! ┌──────────────────┐
112//! │  Router Planner     │  recommends an executor
113//! └──────────────────┘
114//!    │
115//!    ▼
116//! ┌──────────────────┐
117//! │  Logger / Metrics    │  every step writes a structured log row
118//! └──────────────────┘
119//!    │
120//!    ▼
121//! Expanded packet, ready for: dry-run report | execution handoff | human approval queue
122//! ```
123//!
124//! # Packet Grammar
125//!
126//! A Pidgin packet is plain text — a header line followed by `key=value` fields:
127//!
128//! ```text
129//! @run task.example
130//! wf=generic_review
131//! mode=draft
132//! in=[primary_subject,source_refs]
133//! out=[review_notes]
134//! do=[draft,review]
135//! deny=[publish,send,delete,secrets]
136//! risk=med
137//! human=yes
138//! ```
139//!
140//! **Directives:** `@run`, `@result`, `@approval`, `@context`
141//!
142//! **Reference syntax** (inside lists and the `route` field):
143//! - Namespace ref: `namespace:id` — e.g. `file:src/main.rs`, `ep:UNIT012`
144//! - Bare alias: resolved through `REFERENCE_ALIASES.yaml`
145//!
146//! # Safety Gate
147//!
148//! The safety gate enforces 9 numbered rules (SG-1 through SG-9):
149//!
150//! | Rule | Description |
151//! |------|-------------|
152//! | SG-1 | Action in both `do` and `deny` → blocked |
153//! | SG-2 | Human-gated action without `human=yes` → blocked |
154//! | SG-3 | High/critical risk forces `human=yes`, cannot override |
155//! | SG-4 | References resolving to private paths → blocked |
156//! | SG-5 | Unknown workflow → blocked |
157//! | SG-6 | Invalid mode → blocked |
158//! | SG-7 | Free-text `note` field is never parsed for instructions |
159//! | SG-8 | Unresolved required inputs → expansion blocked |
160//! | SG-9 | Critical risk requires an `@approval` packet |
161//!
162//! **Safety-first principle:** If the runtime is ever uncertain, it fails closed
163//! (blocks, asks for human approval, or refuses to expand) rather than fail open.
164//!
165//! # Multi-Agent Integration
166//!
167//! Pidgin is the handoff *format* between agents, not an orchestrator itself.
168//! The integration pattern is:
169//!
170//! ```text
171//! Agent A (orchestrator) ──produces .pgn──→ Pidgin (validate→safety→resolve→expand)
172//!                                                                                │
173//!                                                                           result .pgn
174//!                                                                                │
175//!                                                                           Pidgin (validate→log)
176//!                                                                                │
177//! Agent A ◀──────────────────────── reads result ────────────────────────────────┘
178//! ```
179//!
180//! ## Integration with Orchestrator Frameworks
181//!
182//! - **LangGraph**: A Pidgin node parses/validates the packet before routing to
183//!   the next agent. Expanded packets become structured messages in the graph state.
184//!
185//! - **CrewAI**: Each agent's task output is a `.pgn` packet; Pidgin validates
186//!   inter-agent handoffs.
187//!
188//! - **A2A (Agent2Agent)**: Pidgin's expanded Run Packet is the payload inside
189//!   an A2A Task when crossing trust boundaries.
190//!
191//! - **MCP (Model Context Protocol)**: Pidgin runs as an MCP server, exposing
192//!   `parse`, `validate`, `expand` as MCP tools.
193//!
194//! ## Python SDK
195//!
196//! A Python SDK (scaffolded in `python/`) wraps the `pgn` binary as a subprocess
197//! or via PyO3 bindings, providing typed Pydantic models so orchestrators get
198//! Python objects instead of raw CLI output.
199//!
200//! ## Hooking into the Pipeline
201//!
202//! Each stage in the pipeline is a public function you can call from your own
203//! code:
204//!
205//! ```rust
206//! use pidgin_lang::parser::parse_packet;
207//! use pidgin_lang::safety::check_safety;
208//! use pidgin_lang::expander::expand_to_run_packet;
209//!
210//! let packet = parse_packet("@run my.task\nwf=generic_review\nmode=draft")
211//!     .expect("valid packet");
212//! ```
213//!
214//! You can hook into any individual stage, skip stages, or compose them in
215//! custom orders depending on your use case.
216//!
217//! # Host Configuration
218//!
219//! Pidgin reads its configuration from `.pidgin/` in the host directory.
220//! Use `pgn init` to scaffold the default config:
221//!
222//! ```bash
223//! pgn init
224//! ```
225//!
226//! | File | Purpose |
227//! |------|---------|
228//! | `WORKFLOW_REGISTRY.yaml` | Workflow definitions with modes, inputs, executors |
229//! | `ACTION_REGISTRY.yaml` | Action tiers: `safe`, `controlled`, `human_gated` |
230//! | `SAFETY_RULES.yaml` | Default denies, private paths, human approval rules |
231//! | `REFERENCE_ALIASES.yaml` | Short-name aliases for frequently-used references |
232//! | `PIDGIN_RUNTIME_CONFIG.yaml` | Runtime settings (paths, modes, defaults) |
233//!
234//! # CLI Reference
235//!
236//! | Command | Description |
237//! |---------|-------------|
238//! | `pgn init [--host .] [--force]` | Scaffold default `.pidgin/` config |
239//! | `pgn parse <file>` | Parse a packet and print the AST |
240//! | `pgn validate <files> --host .` | Validate syntax + schema against registries |
241//! | `pgn check <file> --host .` | Parse → validate → safety → resolve (end-to-end) |
242//! | `pgn resolve <file> --host .` | Resolve all short references |
243//! | `pgn expand <file> --host . [--out file]` | Expand into executable YAML |
244//! | `pgn context-plan <file> --host .` | Build a context retrieval plan |
245//! | `pgn measure <file>` | Estimate token cost |
246//! | `pgn compare --pgn <file> --verbose <file>` | Compare Pidgin vs verbose token cost |
247//! | `pgn run <file> --host . [--out file]` | Full pipeline end-to-end |
248//! | `pgn doctor --host .` | Check host configuration |
249//!
250//! # Modules
251//!
252//! The library is organized into the following modules, each corresponding to a
253//! pipeline stage or supporting infrastructure:
254
255/// Typed AST types — `PgnPacket`, `FieldValue`, `PacketDirective`, and related
256/// data structures that represent a parsed Pidgin packet in memory.
257pub mod ast;
258
259/// Context planner — decides what information to retrieve given a packet's
260/// workflow and resolved references, producing a structured retrieval plan.
261pub mod context;
262
263/// Error types — `ParseError`, `ValidationError`, `SafetyError`, and other
264/// error enums with typed variants and formatted messages.
265pub mod errors;
266
267/// Packet expander — takes a parsed, validated, safety-checked, and resolved
268/// packet and produces a fully-specified executable YAML packet (RunPacket,
269/// ResultPacket, ApprovalPacket, etc.).
270pub mod expander;
271
272/// Lexer/tokenizer — winnow-based tokenizer that converts raw `.pgn` text
273/// into tokens (headers, fields, scalars, lists, comments).
274pub mod lexer;
275
276/// Structured logging — append-only CSV logging for every pipeline stage
277/// (parse, validate, safety, resolve, expand, run) with sanitization.
278pub mod logging;
279
280/// Token estimation and cost metrics — estimates token cost of raw text and
281/// structured packets, and compares Pidgin format against verbose alternatives.
282pub mod metrics;
283
284/// Packet parser — winnow-based grammar parser that converts tokenized input
285/// into a typed `PgnPacket` AST, with size limits and input validation.
286pub mod parser;
287
288/// Registry loader — deserializes YAML configuration files (WorkflowRegistry,
289/// ActionRegistry, SafetyRules) from the host's `.pidgin/` directory.
290pub mod registry;
291
292/// Reference resolver — resolves short references (`namespace:id`, bare
293/// aliases) into real filesystem paths or IDs, with containment checks
294/// and symlink traversal protection.
295pub mod resolver;
296
297/// Route planner — recommends an executor for a packet based on the
298/// workflow's recommended and fallback executors and the safety result.
299pub mod router;
300
301/// Safety gate — enforces 9 safety rules (SG-1 through SG-9) including
302/// contradiction detection, human-gated actions, private path protection,
303/// and post-resolution safety checks.
304pub mod safety;
305
306/// Validator — syntax validation (structural completeness) and schema
307/// validation (registry-checked legality of values) for parsed packets.
308pub mod validator;
309
310#[cfg(test)]
311mod tests;