openagentflow 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 AbdulRahman Elzahaby (egyjs) and OpenAgentFlow Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,262 @@
1
+ <p align="center">
2
+ <img src="docs/assets/oaf-logo.svg" alt="OpenAgentFlow Logo" width="160"/>
3
+ </p>
4
+
5
+ # OpenAgentFlow
6
+
7
+ **An Open, Portable Specification for Executable Multi-Agent Workflows**
8
+
9
+ [![Tests: 163 Passing](https://img.shields.io/badge/tests-163%20passing-brightgreen.svg)](#testing--quality-assurance)
10
+ [![Core Dependencies: 0](https://img.shields.io/badge/core%20dependencies-0-blue.svg)](#project-structure)
11
+ [![Target Runtime: LangGraph](https://img.shields.io/badge/runtime-LangGraph%20Python-orange.svg)](#multi-llm--runtime-integration)
12
+ [![LLM Providers: Gemini | OpenAI | Anthropic](https://img.shields.io/badge/LLMs-Gemini%20%7C%20OpenAI%20%7C%20Anthropic-purple.svg)](#multi-llm--runtime-integration)
13
+ [![VS Code Extension](https://img.shields.io/badge/VS%20Code-Syntax%20Support-007ACC.svg?logo=visualstudiocode)](https://marketplace.visualstudio.com/items?itemName=OpenAgentFlow.openagentflow-support)
14
+ [![Documentation](https://img.shields.io/badge/docs-complete-blue.svg)](docs/index.md)
15
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
16
+
17
+ > *What OpenAPI is for REST APIs, OpenAgentFlow (`.oaf`) is for AI agent workflows.*
18
+
19
+ <p align="center">
20
+ <img src="docs/assets/demo.gif" alt="OpenAgentFlow Demo" width="800"/>
21
+ </p>
22
+
23
+ ### ⚑ The 60-Second Example
24
+ Define your multi-agent workflow in clean, human-readable `.oaf` textβ€”completely decoupled from Python/Node boilerplate:
25
+
26
+ ```js
27
+ workflow "Quick Summarize" {
28
+
29
+ state {
30
+ source_text: string @required
31
+ extracted_points: string
32
+ summary: string
33
+ }
34
+
35
+ agent Extractor {
36
+ instructions: "Read the `source_text` and extract the most important facts into a concise bulleted list."
37
+ model: "gemini-2.0-flash"
38
+ inputs: [source_text]
39
+ outputs: [extracted_points]
40
+ }
41
+
42
+ agent Synthesizer {
43
+ instructions: "Take the extracted points and weave them into a clear, cohesive summary paragraph."
44
+ model: "gpt-4o"
45
+ inputs: [extracted_points]
46
+ outputs: [summary]
47
+ }
48
+
49
+ flow {
50
+ start -> Extractor
51
+ Extractor -> Synthesizer
52
+ Synthesizer -> end
53
+ }
54
+ }
55
+ ```
56
+
57
+ Install the CLI globally and execute your workflow immediately (or clone our [Starter Repository](https://github.com/OpenAgentFlow/OpenAgentFlow-starter)):
58
+ ```bash
59
+ # Option A: Save the block above to summarize.oaf and run directly
60
+ npm install -g openagentflow
61
+ oaf run summarize.oaf
62
+
63
+ # Option B: Clone our official starter repository with pre-built workflows & inputs
64
+ git clone https://github.com/OpenAgentFlow/OpenAgentFlow-starter.git my-agents
65
+ cd my-agents && npm run setup && npm run triage
66
+ ```
67
+
68
+ ---
69
+
70
+ ## 🌟 Why OpenAgentFlow?
71
+
72
+ Modern AI agent frameworks (like LangGraph, AutoGen, and CrewAI) each introduce distinct concepts, Python/Node boilerplate, and proprietary APIs. **OpenAgentFlow** introduces a neutral, human-readable authoring language (`.oaf`) that separates workflow definition from execution runtimes.
73
+
74
+ ### ✨ Key Features
75
+ - **Write Once, Run Anywhere**: Define multi-agent topologies, state schemas, and agent instructions once in pure `.oaf` text and compile deterministically to production-ready Python code.
76
+ - **Strict Semantic Validation**: Three-phase checking catches dead ends, unreachable agents, and missing fields *before* running expensive LLM calls.
77
+ - **Zero-Config Multi-LLM**: Auto-detects and adapts to Gemini, OpenAI, and Anthropic endpoints without changing your `.oaf` code.
78
+ - **4-Tier Env Hierarchy & Auth**: Seamlessly resolve API keys across CLI flags, local `.env` files, system variables, and global `~/.oaf/.env` credentials (`oaf auth`).
79
+ - **Push-Model State Injection**: Inject JSON payloads (`--input data.json`) directly into workflows for easy backend/API integration.
80
+ - **Zero Core Dependencies**: Pure Node.js compiler (`lexer`, `parser`, `validator`, `IR generator`, and `LangGraph adapter`).
81
+
82
+ ---
83
+
84
+ ## πŸš€ Quick Start
85
+
86
+ ### Option 1: Using the Starter Repository (Recommended β€” 60 Seconds)
87
+ The fastest way to start building executable multi-agent workflows without manual setup or missing file errors is using our official template repository:
88
+
89
+ 1. **Clone the Starter Project:**
90
+ ```bash
91
+ git clone https://github.com/OpenAgentFlow/OpenAgentFlow-starter.git my-agents
92
+ cd my-agents
93
+ ```
94
+
95
+ 2. **Run Automated Environment Setup:**
96
+ Our cross-platform setup script (`setup.js`) checks your system, creates your Python virtual environment (`venv`), installs LangGraph dependencies, and initializes your `.env` configuration automatically across Windows, macOS, and Linux:
97
+ ```bash
98
+ npm install
99
+ npm run setup
100
+ ```
101
+
102
+ 3. **Configure API Keys (`oaf auth`):**
103
+ Set your keys interactively via CLI (or edit the `.env` file generated in your project root):
104
+ ```bash
105
+ npx openagentflow auth
106
+ ```
107
+
108
+ 4. **Run Your First Workflow Live!**
109
+ Execute pre-built multi-agent topologies immediately:
110
+ ```bash
111
+ # Run Customer Support Triage Workflow with injected JSON state
112
+ npm run triage
113
+
114
+ # Or compile directly to a LangGraph Python application
115
+ npm run compile-triage
116
+ ```
117
+
118
+ ---
119
+
120
+ ### Option 2: Standalone Global CLI
121
+ If you prefer creating workflows from scratch in your own workspace without cloning a template:
122
+
123
+ 1. **Install Prerequisites & CLI:**
124
+ Ensure **Node.js** (v18+) and **Python** (v3.10+) are installed, then install the CLI globally:
125
+ ```bash
126
+ npm install -g openagentflow
127
+ ```
128
+
129
+ 2. **Set Your API Keys (`oaf auth`):**
130
+ Configure credentials securely in `~/.oaf/.env` (`0o600` permissions):
131
+ ```bash
132
+ oaf auth
133
+ # Or set manually: export GOOGLE_API_KEY="your-key" / $env:GOOGLE_API_KEY="your-key"
134
+ ```
135
+
136
+ 3. **Set Up Python Runtime & Virtual Environment:**
137
+ To execute compiled `.oaf` workflows live via LangGraph against real LLM endpoints:
138
+ ```bash
139
+ # Create and activate Python virtual environment
140
+ python -m venv venv
141
+ source venv/bin/activate # Windows PowerShell: .\venv\Scripts\Activate.ps1
142
+
143
+ # Install LangGraph and multi-provider LangChain drivers
144
+ pip install langgraph langchain-google-genai langchain-openai langchain-anthropic pydantic
145
+ ```
146
+
147
+ 4. **Create & Execute Workflows Live:**
148
+ Create a `.oaf` workflow file (e.g., `my-workflow.oaf`) along with your JSON data (`data.json`) and run:
149
+ ```bash
150
+ oaf run my-workflow.oaf --input data.json
151
+ ```
152
+
153
+ > πŸ“– **For the full guide, see [Documentation](docs/index.md)**.
154
+
155
+ ---
156
+
157
+ ## πŸ“– Documentation
158
+
159
+ The complete documentation is available in the `docs/` directory, including:
160
+ * **[Language Reference](docs/language/oaf-language.md):** Complete `.oaf` syntax.
161
+ * **[Formal Specs](spec/SPEC.md):** EBNF grammar, semantic rules, and IR schema.
162
+ * **[API & CLI Ref](docs/cli/cli-reference.md):** Programmatic API and command-line flags.
163
+
164
+ ---
165
+
166
+ ## πŸ“ The `.oaf` Language at a Glance
167
+
168
+ OpenAgentFlow provides a clean, declarative syntax for describing stateful multi-agent workflows:
169
+
170
+ ```oaf
171
+ workflow "Quick Summarize" {
172
+
173
+ config {
174
+ max_iterations: 5
175
+ timeout_seconds: 60
176
+ }
177
+
178
+ state {
179
+ request: string
180
+ source_text: string
181
+ key_points: list[string]
182
+ summary: string
183
+ }
184
+
185
+ agent Analyst {
186
+ instructions: """
187
+ Analyze the request and source text.
188
+ Identify the most important facts.
189
+ """
190
+ model: "gpt-4"
191
+ temperature: 0.2
192
+ inputs: [request, source_text]
193
+ outputs: [key_points]
194
+ }
195
+
196
+ agent Writer {
197
+ instructions: """
198
+ Write a clear, concise summary from the key points.
199
+ """
200
+ model: "gpt-4"
201
+ temperature: 0.7
202
+ inputs: [key_points]
203
+ outputs: [summary]
204
+ }
205
+
206
+ flow {
207
+ start -> Analyst
208
+ Analyst -> Writer
209
+ Writer -> end
210
+ }
211
+ }
212
+ ```
213
+
214
+ ---
215
+
216
+ ## βš™οΈ Compilation & Execution Pipeline
217
+
218
+ The OpenAgentFlow compiler transforms raw `.oaf` source code into validated Intermediate Representation (IR) JSON, which runtime adapters then transform into executable source code:
219
+
220
+ ```
221
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
222
+ β”‚ Source Code β”‚ ──▢ β”‚ Lexer β”‚ ──▢ β”‚ Parser β”‚ ──▢ β”‚ AST (JSON) β”‚
223
+ β”‚ (.oaf file)β”‚ β”‚ (lexer.js)β”‚ β”‚(parser.js) β”‚ β”‚ (ast.js) β”‚
224
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
225
+ β”‚
226
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
227
+ β”‚ Execution β”‚ ◀── β”‚ LangGraph β”‚ ◀── β”‚ Compiler β”‚ ◀── β”‚ Semantic Validatorβ”‚
228
+ β”‚ (Live Subproc) β”‚ Adapter β”‚ β”‚ (IR Gen) β”‚ β”‚ (validator.js) β”‚
229
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
230
+ ```
231
+
232
+ ---
233
+
234
+ ## 🧠 Multi-LLM & Runtime Integration
235
+
236
+ When compiling to LangGraph, the runtime automatically manages providers. You can specify `model: "gpt-4o"` or `model: "gemini-2.0-flash"` in your `.oaf` file, and the compiled Python script will auto-detect your API keys (via `.env`, system vars, or `~/.oaf/.env`) and route the request to the correct provider.
237
+
238
+ ---
239
+
240
+ ## πŸ—ΊοΈ Roadmap & Project Status
241
+
242
+ | Phase | Deliverables | Status |
243
+ | :--- | :--- | :--- |
244
+ | **Phase 1** β€” Specification | Language spec (`SPEC.md`), EBNF grammar, examples, IR definition | βœ… Complete |
245
+ | **Phase 2** β€” Compiler MVP | Zero-dependency Lexer, Parser, 3-Phase Validator, IR Generator, CLI | βœ… Complete |
246
+ | **Phase 3** β€” Runtime Integration | LangGraph Python Adapter, Dual-LLM (`get_llm()`), Live `run` CLI, E2E Demo | βœ… Complete |
247
+ | **Phase 4** β€” State Initialization (`--input`) | File-based state injection (`--input data.json`), runtime override (`OAF_INPUT_FILE`) | βœ… Complete |
248
+ | **Phase 4.5** β€” Multi-Provider, Auth & Tooling | Anthropic (`claude-*`) & Google (`gemma-*`) inference, `oaf auth`, VS Code syntax extension (`.oaf`) | βœ… Complete |
249
+ | **Phase 5** β€” Additional Adapters | AutoGen Adapter, CrewAI Adapter, Formal `Adapter` base contract | πŸ”² Planned |
250
+ | **Phase 6** β€” Developer CLI Tooling | `oaf fmt` (auto-formatter), `oaf init` (project scaffolding) | πŸ”² Planned |
251
+
252
+ ---
253
+
254
+ ## 🀝 Contributing
255
+
256
+ We welcome contributions from developers, researchers, and engineers! Whether you want to pick up a [`good first issue`](https://github.com/OpenAgentFlow/openagentflow/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22), help build our planned Phase 5 target adapters (**Microsoft AutoGen** or **CrewAI**), or propose language enhancements, please check out our detailed [Contributing Guide](CONTRIBUTING.md) to get started.
257
+
258
+ ---
259
+
260
+ ## πŸ“„ License
261
+
262
+ This project is open-source and licensed under the [MIT License](LICENSE).
@@ -0,0 +1,104 @@
1
+ /**
2
+ * OpenAgentFlow β€” Isolated Demo Helper Template Module
3
+ *
4
+ * This module generates self-contained Python code (`_DemoChatModel`, `_maybe_get_demo_llm`,
5
+ * `_format_demo_state`) used strictly when `--demo` (OAF_DEMO=1) is active.
6
+ *
7
+ * It can be cleanly deleted from the codebase if demo simulation mode is ever removed.
8
+ * See: llm/handover/2026-07-20-screencast-and-demo-removal-guide.md
9
+ */
10
+
11
+ export function generateDemoHelperTemplate() {
12
+ const lines = [
13
+ `# ─── DEMO HOOK MODULE (Cleanly removable) ───────────────────────────────────`,
14
+ `import hashlib, json, os`,
15
+ `class _DemoChatModel:`,
16
+ ` def __init__(self, model, temperature=0, provider="demo"):`,
17
+ ` self.model = model`,
18
+ ` self.temperature = temperature`,
19
+ ` self._oaf_provider = provider`,
20
+ ``,
21
+ ` def invoke(self, messages, *args, **kwargs):`,
22
+ ` cache_dir = os.path.join(os.path.expanduser("~"), ".oaf")`,
23
+ ` cache_file = os.path.join(cache_dir, "demo_cache.json")`,
24
+ ` prompt_parts = []`,
25
+ ` sys_prompt = ""`,
26
+ ` for m in messages:`,
27
+ ` if isinstance(m, dict):`,
28
+ ` role = m.get("role", "")`,
29
+ ` content_str = str(m.get("content", ""))`,
30
+ ` if role == "system": sys_prompt = content_str`,
31
+ ` prompt_parts.append(f"{role}:{content_str}")`,
32
+ ` elif hasattr(m, "type"):`,
33
+ ` content_str = str(getattr(m, "content", ""))`,
34
+ ` if m.type == "system": sys_prompt = content_str`,
35
+ ` prompt_parts.append(f"{m.type}:{content_str}")`,
36
+ ` else:`,
37
+ ` prompt_parts.append(str(m))`,
38
+ ``,
39
+ ` full_prompt = "|".join(prompt_parts)`,
40
+ ` cache_key = f"{self.model}:{hashlib.sha256(full_prompt.encode('utf-8')).hexdigest()}"`,
41
+ ``,
42
+ ` if os.path.exists(cache_file):`,
43
+ ` try:`,
44
+ ` with open(cache_file, "r", encoding="utf-8") as f:`,
45
+ ` cache_data = json.load(f)`,
46
+ ` if cache_key in cache_data:`,
47
+ ` class _AIMessage:`,
48
+ ` def __init__(self, text): self.content = text`,
49
+ ` return _AIMessage(cache_data[cache_key])`,
50
+ ` except Exception:`,
51
+ ` pass`,
52
+ ``,
53
+ ` if "extract the most important facts" in sys_prompt.lower() or "extractor" in sys_prompt.lower():`,
54
+ ` content = (`,
55
+ ` "- Monolithic LLMs are transitioning to multi-agent pipelines where specialized agents handle distinct sub-tasks.\\n"`,
56
+ ` "- Robust state management and clear communication protocols are critical to prevent information loss and infinite loops.\\n"`,
57
+ ` "- Standardized open-source frameworks provide unified syntax and configurations, lowering the engineering barrier."`,
58
+ ` )`,
59
+ ` elif "weave them into a clear, cohesive summary" in sys_prompt.lower() or "synthesizer" in sys_prompt.lower():`,
60
+ ` content = (`,
61
+ ` "Modern AI is rapidly evolving from monolithic models to collaborative multi-agent pipelines where specialized models execute modular sub-tasks. "`,
62
+ ` "While this approach improves reliability and performance, it introduces orchestration challenges requiring robust state management and structured communication protocols. "`,
63
+ ` "Standardized open-source frameworks address these bottlenecks by offering a unified syntax and automated state coordination, making multi-agent deployment as seamless as containerizing a web application."`,
64
+ ` )`,
65
+ ` else:`,
66
+ ` content = f"[Demo Output for {self.model}]: Successfully processed workflow input."`,
67
+ ``,
68
+ ` class _AIMessage:`,
69
+ ` def __init__(self, text):`,
70
+ ` self.content = text`,
71
+ ``,
72
+ ` try:`,
73
+ ` os.makedirs(cache_dir, exist_ok=True)`,
74
+ ` cache_data = {}`,
75
+ ` if os.path.exists(cache_file):`,
76
+ ` with open(cache_file, "r", encoding="utf-8") as f:`,
77
+ ` cache_data = json.load(f)`,
78
+ ` cache_data[cache_key] = content`,
79
+ ` with open(cache_file, "w", encoding="utf-8") as f:`,
80
+ ` json.dump(cache_data, f, indent=2, ensure_ascii=False)`,
81
+ ` except Exception:`,
82
+ ` pass`,
83
+ ``,
84
+ ` return _AIMessage(content)`,
85
+ ``,
86
+ `def _maybe_get_demo_llm(target_model, temperature, target_provider):`,
87
+ ` if os.environ.get("OAF_DEMO") == "1" or target_provider == "demo":`,
88
+ ` return _DemoChatModel(model=target_model, temperature=temperature, provider=target_provider or "demo")`,
89
+ ` return None`,
90
+ ``,
91
+ `def _format_demo_state(result, initial_state):`,
92
+ ` if os.environ.get("OAF_DEMO") != "1":`,
93
+ ` return result`,
94
+ ` display_state = {}`,
95
+ ` for k, v in result.items():`,
96
+ ` if k in initial_state and isinstance(v, str) and len(v) > 100 and result[k] == initial_state[k]:`,
97
+ ` display_state[k] = f"{v[:80]}... ({len(v)} chars abbreviated)"`,
98
+ ` else:`,
99
+ ` display_state[k] = v`,
100
+ ` return display_state`,
101
+ `# ────────────────────────────────────────────────────────────────────────────`,
102
+ ];
103
+ return lines.join('\n');
104
+ }