Observed since 20 Oct, 21:49 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
agentdsl
A token-efficient DSL for Agent-to-Agent and Human-to-Agent communication, optimized for LLM context windows
AgentDSL is a specialized, token-efficient format designed for Agent-to-Agent (A2A) and Human-to-Agent relational data communication. Unlike verbose JSON payloads, AgentDSL uses a concise, delimiter-based Domain Specific Language (DSL) optimized for Large Language Model (LLM) context windows and parsing efficiency.
[!IMPORTANT] Project Status: Pre-Alpha / Experimental This project is in early development. APIs and the DSL specification are subject to change.
str, int, float, any).@.stable (2021 edition)3.10 or higherThe format relies on standard markers (e.g., [SECTION]) and pipe | delimiters.
AgentDSL decouples generic data structure from values to save tokens on repetitive keys.
[SCHEMA:LABEL]Defines the structure of a data block.
FIELD_NAME:type.ID:int as the first column.@SCHEMA.FIELD:type (e.g., @INDIVIDUAL.ID:int) to reference other blocks.[SCHEMA:INDIVIDUAL]
ID:int|NAME:str|AGE:int|GENDER:str|HOBBY:str
[DATA]Contains the actual records. Each row MUST start with an ID, followed by values corresponding to the Schema.
[!TIP] Multi-Value Support: Use a comma
,to separate multiple values within a single column (e.g.,Coding,Reading).
[!NOTE] Empty Columns: Use an underscore
_to represent an empty column to maintain structural integrity while keeping the row token-efficient.
[DATA]
1|Sion|25|MALE|Coding,Reading
2|Alice|30|FEMALE|Reading
3|Bob|35|_|_
Agents broadcast available remote procedures using the [FUNCTIONS] block.
[FUNCTIONS]Defines available functions with descriptions and typed parameters.
* indicates required).[FUNCTIONS]
[GetWeather]
DESC[Get weather for a city]
IN[CITY:str*|FORCAST_DAYS:int]
OUT[TEMPERATURE:str|HUMIDITY:str|WIND_SPEED:str]
[CALL]Invokes a function defined in a [FUNCTIONS] block.
Format: [FunctionName] followed by FIELD:VALUE pairs.
[CALL]
[GetWeather]
CITY:New York
FORCAST_DAYS:3
[RESULT]Contains structured outputs, status, and error messages.
Headers are typed: [FIELD:type|...]. Status and Error blocks provide execution feedback.
[RESULT]
[TEMPERATURE:str|HUMIDITY:str|WIND_SPEED:str]
30C|70%|10mph
[STATUS:str]
SUCCESS
[ERROR:str]
In case of failure:
[RESULT]
...
[STATUS:str]
ERROR
[ERROR:str]
Invalid city name
For nested data structures, AgentDSL generates a sequence of blocks to maintain token efficiency and relational integrity:
[SCHEMA:Details]
ID:int|HUMIDITY:str|UV_INDEX:int
[DATA]
1|60%|5
[RESULT]
[CITY:str|DETAILS:@Details.ID]
Paris|1
[STATUS:str]
SUCCESS
[ERROR:str]
For the formal language specification, grammar, and detailed semantics, refer to DSL_SPECIFICATION.md.
AgentDSL provides a Rust library for parsing and serializing AgentDSL messages.
Add this to your Cargo.toml:
[dependencies]
agentdsl = { path = "." } # Or git/crates.io version
use agentdsl::{parse, serialize, AgentMessage};
fn main() {
let input = r#"
[DATA]
1|Sion|25
"#;
// Parsing
let message = parse(input.to_string()).unwrap();
// Serialization
let dsl_string = serialize(message);
println!("DSL: {}", dsl_string);
}
AgentDSL is available as a Python package.
pip install agentdsl
import agentdsl
# --- DSL to JSON (Parsing) ---
ast = agentdsl.parse("[DATA]\n1|Sion|25")
print(ast)
# --- JSON to DSL (Serialization) ---
dsl = agentdsl.serialize(ast)
print(dsl)
# --- Tool Integration ---
@agentdsl.tool
def get_weather(city: str, forecast_days: int = 1) -> str:
"""Get weather for a city"""
return f"Weather in {city} for {forecast_days} days: Sunny"
# Access generated AgentDSL definition
print(get_weather.__agentdsl__)
# Format execution results (Relational Data Support)
data = get_weather("New York", 3)
result_dsl = agentdsl.serialize_result(get_weather, data)
print(result_dsl)
# --- NEW: Native JSON Support ---
# DSL -> Natural JSON (Resolves relational references)
json_obj = agentdsl.to_json(result_dsl)
print(json_obj)
# Natural JSON -> DSL (Infers schemas & extracts relations)
new_dsl = agentdsl.from_json(json_obj)
print(new_dsl)
For integration with other languages, AgentDSL provides C-compatible bindings in src/ffi.rs.
agentdsl_parse: Convert DSL string to JSON AST string.agentdsl_serialize: Convert JSON AST string to AgentDSL string.agentdsl_to_json: Convert DSL string to Native JSON string.agentdsl_from_json: Convert Native JSON string to AgentDSL string.agentdsl_free_string: Free memory allocated by the library.You can generate headers using cbindgen.
AgentDSL provides "Native JSON" support to bridge the gap between token-efficient DSL and developer-friendly keyed objects. This handles relational resolution (re-hydrating @ references into nested objects).
Converts a sequence of DSL blocks into a nested JSON structure. Relational references are automatically resolved into nested objects when the referenced data is present.
# Returns a dictionary with re-hydrated nested objects
native_json = agentdsl.to_json(dsl_string)
Infers schemas from JSON keys and extracts nested objects into separate schemas with @ references to maintain token efficiency.
# Returns a compact DSL string
dsl_string = agentdsl.from_json(native_json_obj)
AgentDSL excels in agent communication scenarios where token efficiency matters and data is relational or tabular.
When an agent needs to pass a large batch of structured records (like CSV data but type-safe and streamable), AgentDSL's [SCHEMA] and [DATA] blocks provide a flat, high-density alternative to JSON arrays.
Example: Database query results
[SCHEMA:USERS]
ID:int|NAME:str|EMAIL:str|CREATED:int
[DATA]
1|Alice|alice@example.com|1704067200
2|Bob|bob@example.com|1704153600
3|Carol|carol@example.com|1704240000
vs. JSON (much more verbose):
{
"users": [
{
"id": 1,
"name": "Alice",
"email": "alice@example.com",
"created": 1704067200
},
{
"id": 2,
"name": "Bob",
"email": "bob@example.com",
"created": 1704153600
},
{
"id": 3,
"name": "Carol",
"email": "carol@example.com",
"created": 1704240000
}
]
}
Token savings: ~48% compared to JSON (high-density tables)
Instead of nesting deep objects (which confuses LLM attention), AgentDSL uses Relational References (@).
Example: API response with customer → orders → items hierarchy
[SCHEMA:CUSTOMER]
ID:int|NAME:str|ACCOUNT_TYPE:str
[DATA]
1|Acme Corp|ENTERPRISE
[SCHEMA:ORDERS]
ID:int|@CUSTOMER.ID:int|ORDER_NUM:str|TOTAL:float
[DATA]
1|1|ORD-001|5000.50
2|1|ORD-002|3200.00
[SCHEMA:ITEMS]
ID:int|@ORDERS.ID:int|SKU:str|QTY:int|PRICE:float
[DATA]
1|1|SKU-A001|100|50.00
2|1|SKU-A002|50|25.00
3|2|SKU-B001|200|16.00
vs. JSON (deeply nested, harder to parse):
{"customer": {"id": 1, "name": "Acme Corp", "orders": [{"id": 1, "orderId": "ORD-001", "items": [...]}]}}
Benefits:
Agents can broadcast their "Capabilities" in a format that looks like a header file rather than verbose JSON-Schema.
Example: LLM discovering available functions
[FUNCTIONS]
[SearchDocuments]
DESC[Search documentation using keyword or phrase]
IN[QUERY:str*|MAX_RESULTS:int|LANGUAGE:str]
OUT[ID:str|TITLE:str|URL:str|RELEVANCE:float]
[AnalyzeSentiment]
DESC[Analyze sentiment of text]
IN[TEXT:str*|DETAILED:any]
OUT[SENTIMENT:str|SCORE:float|CONFIDENCE:float]
Token savings: ~37% vs. JSON-Schema (from function schema benchmarks)
Function results with relational references improve structure clarity for LLMs.
Example: Search + metadata correlation
[SCHEMA:METADATA]
ID:int|SOURCE:str|INDEXED_DATE:int
[DATA]
1|internal_kb|1704067200
2|public_api|1704153600
[RESULT]
[ID:str|TITLE:str|METADATA:@METADATA.ID]
doc_001|Deployment Guide|1
doc_002|API Reference|2
[STATUS:str]
SUCCESS
[ERROR:str]
Binary or Complex Data Types
Highly Irregular/Sparse Data
Single Small Objects
Example: DON'T do this
[SCHEMA:CONFIG]
ID:int|API_KEY:str|DEBUG:any
[DATA]
1|secret_key_123|true
Use JSON instead:
{ "api_key": "secret_key_123", "debug": true }
When Human Readability is Critical
Unstructured Text
Real-time Streaming with Variable Schema
AgentDSL supports four atomic types and one composite type:
int - 64-bit signed integer: -2^63 to 2^63-1
float - 64-bit IEEE754 double precision
str - UTF-8 string, up to ~2 billion characters
any - JSON-serialized value (arrays, objects, etc.)
Reference - Relational pointer to another schema
| Constraint | Limit | Notes |
|---|---|---|
| Field Count per Schema | 1,000 | Practical limit; performance degrades >500 |
| Nesting Depth | Unlimited | Relational decomposition handles any depth |
| Records per Block | 100,000+ | Limited by memory; tested up to 1M+ records |
| String Length | ~2GB theoretical | Practical limit 10MB+ for efficient parsing |
| Field Name Length | 255 chars | Should be kept <50 for readability |
| Schema Label Length | 100 chars | Avoid special chars, use [A-Za-z0-9_] |
| Single Line Width | Unlimited | Pipe-delimited; no newlines in values except any type |
Array Nesting (in any) | 100 levels | JSON RFC limit not explicitly enforced |
[SCHEMA:LABEL]
FIELDNAME:type|FIELDNAME:type|...
ID:int as first field[A-Za-z0-9_]int, str, float, any, @Schema.Field@ParentSchema.ID:int (the :int is type annotation)[DATA]
id_value|field2|field3|...
|, no escaping needed (pipes in values use any type)_ (underscore)skill1,skill2,skill3)any type for complex data[FUNCTIONS]
[FunctionName]
DESC[Description here]
IN[PARAM1:type*|PARAM2:type]
OUT[RESULT1:type|RESULT2:type]
* marks required parametersstr by default[CALL]
[FunctionName]
PARAM:VALUE
PARAM:VALUE
[FUNCTIONS] block[RESULT]
[FIELD:type|FIELD:type]
value1|value2|...
[STATUS:str]
SUCCESS|ERROR
[ERROR:str]
optional_error_message
SUCCESS or ERROR[DATA]| Operation | Time Complexity | Notes |
|---|---|---|
| Parse DSL to AST | O(n) | Linear in input size; single pass parser |
| Serialize AST to DSL | O(n) | Linear in record count |
| From JSON decompose | O(n × d) | n=records, d=nesting depth; relational extraction |
| To JSON reconstruct | O(n × m) | n=total records, m=average reference depth |
[FUNCTIONS] DESC field for version info if needed✅ DO:
int for IDs, timestamps, countsstr for product names, messages, categoriesfloat for metrics, percentages, financial amounts@Reference for any foreign key relationshipany rarely—only for complex metadata❌ DON'T:
str for large binary blobs (use encoding or external reference)any type)[SCHEMA]—always validate by nameReal-world benchmarks using 8 diverse scenarios (table data, 4-level nested hierarchies, API responses, and tool discovery):
| Metric | Result | Notes |
|---|---|---|
| Character Size Reduction | 46.0% | JSON → AgentDSL compression ratio |
| Token Efficiency Gain | 23.8% | Using OpenAI CL100K encoding |
| Average Per-Scenario | 42.8% / 20.4% | Size reduction / Token reduction |
| Conversion Speed | 0.88ms/item | Single-pass json → DSL decomposition |
| Scenario | Size Reduction | Token Gain | Nesting Depth |
|---|---|---|---|
| Users_Table_500 | 48.3% | 32.1% | 1 (flat) |
| Deep_Org_Hierarchy | 56.2% | 41.3% | 4 |
| E-Commerce_Catalog | 59.1% | 44.8% | 4 |
| API_Response_Nested | 42.1% | 18.5% | 2-3 |
| Database_Orders_4Levels | 47.3% | 17.5% | 4 |
| Documentation_Content | 51.8% | 22.1% | 4 |
| Function_Schema_Discovery | 38.2% | 12.3% | 1 (flat) |
| API_Results_200 | 44.6% | 15.0% | 2 |
✅ High-density flat data: 38-48% size reduction (excellent for tables, schemas) ✅ Nested hierarchies (4-level): 47-59% size reduction (unlimited depth supported) ✅ Mixed relational data: 12-45% token reduction across all nesting levels ✅ Fast conversion: Sub-millisecond decomposition for typical payloads ✅ Scalability: Tested with hundreds of records and thousands of values
Contributions are welcome! Whether it's bug fixes, feature requests, or documentation improvements, please feel free to open an issue or submit a pull request.
git checkout -b feature/AmazingFeature)git commit -m 'Add some AmazingFeature')git push origin feature/AmazingFeature)Distributed under the MIT License. See license.md for more information.
Download counts and popularity will appear here as the collector receives them.
Declarations describe requirements; they are not a resolved dependency graph.
bdist_wheel · 468.33 KB · Python cp310
bdist_wheel · 451.31 KB · Python cp310
bdist_wheel · 511.23 KB · Python cp310
bdist_wheel · 544.92 KB · Python cp310
bdist_wheel · 324.78 KB · Python cp310
bdist_wheel · 359.83 KB · Python cp310
bdist_wheel · 467.74 KB · Python cp311
bdist_wheel · 451.13 KB · Python cp311
bdist_wheel · 511.16 KB · Python cp311
bdist_wheel · 544.96 KB · Python cp311
bdist_wheel · 359.82 KB · Python cp311
bdist_wheel · 465.46 KB · Python cp312
bdist_wheel · 449.01 KB · Python cp312
bdist_wheel · 510.21 KB · Python cp312
bdist_wheel · 544.34 KB · Python cp312
bdist_wheel · 357.75 KB · Python cp312
bdist_wheel · 465.66 KB · Python cp313
bdist_wheel · 449.12 KB · Python cp313
bdist_wheel · 510.85 KB · Python cp313
bdist_wheel · 544.41 KB · Python cp313
bdist_wheel · 358.83 KB · Python cp313
bdist_wheel · 465.66 KB · Python cp314
bdist_wheel · 449.12 KB · Python cp314
bdist_wheel · 510.85 KB · Python cp314
bdist_wheel · 544.41 KB · Python cp314
bdist_wheel · 358.83 KB · Python cp314
bdist_wheel · 511.65 KB · Python cp38
bdist_wheel · 545.31 KB · Python cp38
bdist_wheel · 511.69 KB · Python cp39
bdist_wheel · 545.35 KB · Python cp39
bdist_wheel · 511.28 KB · Python pp311
bdist_wheel · 545.25 KB · Python pp311
sdist · 57.84 KB · Python source
Observed since 20 Oct, 21:49 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package_version:f4d85ec974cb8212aecfc80edcb5891fe5374c1dc06628ac5f6b7dcf1d5065c6