🔥 Embr DSL: A Shell-Inspired Chat Abstraction for Language Programs
🧠 Overview
Embr is a domain-specific language (DSL) designed for interactive, composable natural language pipelines, inspired by the syntax and philosophy of Unix shell scripting. 🐚
It treats a conversational state (chat log) as a mutable object that can be transformed, extended, and queried using intuitive operators
like <<, >>, |, and |=.
✨ Core Design Principles
- 🧱 Declarative + Composable: Like piping commands in a shell.
- 🧑🎤 Role-aware: Messages are typed with
@(e.g.,user @ "text"). - 🛠️ Reducers as Functions: Language models and tools act like reducers.
- 🔁 Stateful by Default: All operators mutate a shared conversation state (
Embr).
🧮 Operator Table
| 🔣 Operator | 📝 Description | 💡 Example Usage |
|---|---|---|
@ |
Assign role to a message | user @ "message" |
<< |
Append message to chat (in-place) | chat << "text" |
>> |
Also appends in-place. | updated_chat = chat >> gpt |
> |
Send chat to model, get response | chat > gpt |
| |
Apply model and append output | chat = chat << "hello" | gpt |
| = |
Register reducer into chat's pipeline | chat |= gpt | claude |
🔄 Chat Composition and Transfer Patterns
Operator Precedence
In Embr, operators follow standard Python precedence rules. For our operators, from highest to lowest:
| Precedence | Operators | Description |
|---|---|---|
| Highest | @ |
Role annotation |
| High | > |
Process through model |
| Medium | >> |
Chat transfer |
| Low | | |
Pipe and modify |
| Low | << |
Append message |
This affects how expressions are evaluated when chained together.
Chat Transfer Pattern
The chat transfer pattern allows you to process a chat through a model and transfer the results to another chat:
# Process task_chat and transfer results to global_chat
(task_chat > gpt) >> global_chat
This pattern creates a clean separation between task-specific conversations and your main conversation context.
┌────────────┐ ┌─────┐ ┌─────────────┐ ┌────────────┐
│ task_chat │ > │ gpt │ -> │ response │ >> │ global_chat│
└────────────┘ └─────┘ │ (Spark) │ └────────────┘
└─────────────┘
Parenthesis-Free Alternatives
For cleaner code without parentheses, several alternatives exist:
python
# Manual two-step approach
response = task_chat > gpt
global_chat << response
# Using helper methods (proposed)
task_chat.process(gpt).append_to(global_chat)
# Using a new syntax pattern (proposed)
task_chat > gpt > global_chat
The last approach would require updating the implementation of the > operator to handle different right-hand types.
🚀 Example Use Cases
1. 🛠️ Manual append + model roundtrip
python
chat = Embr()
chat << user @ "hello"
response = chat > gpt
chat << response
2. 🧪 Pipe-style chaining
python
chat = Embr()
chat = chat << "what is the weather?" | gpt
3. 🔗 Register reducers to the chat
python
chat |= gpt | claude | other_ai
chat.apply_reducers()
4. ❓ Conditional reducers
python
def gpt_if_question(chat):
if "?" in chat.last.content:
return gpt(chat)
chat |= gpt_if_question
chat << "this is a statement"
chat << "what is this?"
chat.apply_reducers()
5. 🤖 Multi-agent routing
python
chat |= on_call @ gpt | on_call @ images
🧩 Functional Patterns
Currying and Composition
Embr uses a functional programming pattern similar to currying, where functions like gpt are designed to:
- Accept an Embr object: Each reducer (like
gpt,claude) takes a chat as input - Return a result: Either a
Spark(message) or a modifiedEmbrobject - Enable operator-based application: The same function works with
>,>>, and|operators
This pattern enables multiple styles of interaction:
# Direct application returning a response
response = chat > gpt
# Application with returned response
response = chat >> gpt
# Pipeline style with in-place modification
chat = chat | gpt
Embr brings the expressiveness of Unix pipelines 🧵 to AI-assisted conversation flows 💬, making it easy to test, iterate, and layer intelligence like shell commands.
Metadata
Release files for embr 0.0.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| embr-0.0.1.tar.gz | 17.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| embr-0.0.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 38.4 kB
Release files / embr-0.0.1.tar.gz
| Download URL | embr-0.0.1.tar.gz |
|---|---|
| Size | 17.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a2cc2da177e58114dd757b4ab6baa5b59487539ff9fa5b95403ad5e6093a100e
|
|
BLAKE2b-256 checksum How to use checksums |
b95309a7b18ae410e0daa2ab752323bbdd0e63de51a5d056faea37eff3006042
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/1.3.1 CPython/3.9.18 Darwin/24.4.0
|
Release files / embr-0.0.1-py3-none-any.whl
| Download URL | embr-0.0.1-py3-none-any.whl |
|---|---|
| Size | 20.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e83c3654b80ef7cb64e8f35b7b26761ea5e0783449f0dcc260aeb2e07bae2969
|
|
BLAKE2b-256 checksum How to use checksums |
2ccd504afbc52859ee18ac612e40dea592536065536947e61a0a752fb12531ef
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/1.3.1 CPython/3.9.18 Darwin/24.4.0
|