Skip to main content

jdsl

jdsl logo

Declarative behavior-tree agents as clean Python combinators, run by a tree-walking interpreter over DeepSeek / Anthropic / OpenAI — with DSPy-style signatures on the LLM leaves.

Determinism lives in the tree (seq / sel / act); the model enters only at predict leaves, typed by a signature like "message -> category". No codegen, no object-literal DSL — the tree structure is the call structure.

from jdsl import tool, root, seq, sel, act, check, predict, ref, store

@tool
def route_to_billing(): print("→ billing")
@tool
def route_to_support(): print("→ support")
@tool
def route_to_human():   print("→ human")

skill = (
    root("Triage", system="Classify inbound messages: billing, support, other.")
    .model("deepseek-chat")                       # provider inferred from the id
    .do(seq(
        predict("message -> category"),           # the model classifies…
        sel(                                      # …and the tree branches on it
            seq(check("category", "billing"), act(route_to_billing)),
            seq(check("category", "support"), act(route_to_support)),
            act(route_to_human),                  # fallback
        ),
    ))
)

ctx = skill.run(message="I was double charged.")
print(ctx.blackboard["category"])                 # -> "billing"

…and the model can drive your tools. A react leaf hands it your @tools and lets it pick and chain them (native function-calling):

from jdsl import tool, root, react

@tool
def distance_km(origin: str, destination: str) -> int: ...   # your Python
@tool
def drive_hours(km: int) -> float: ...

skill = root("Trip").model("deepseek-chat").do(
    react("request -> answer", tools=[distance_km, drive_hours])
)
skill.run(request="Driving Nairobi to Mombasa — how long?")
 > distance_km(origin='Nairobi', destination='Mombasa') -> 485
 > drive_hours(km=485)                                  -> 6.1
answer: About 6.1 hours.

Triage steers the model with the tree; react lets the model steer your tools. Full version: examples/trip.py.

Skill authoring TUI

JDSL includes a compact terminal workbench for building restricted behavior trees without writing the initial Python DSL:

uv run --extra tui jdsl tui

JDSL skill authoring TUI

Add sequence, selector, action, guard, predict, react, and repeat nodes; edit their properties; validate the tree; and save a portable .jdsl package. See the TUI guide for the authoring workflow.

The workbench uses the Gruvbox Material palette, adapted from sainnhe/gruvbox-material and curbol/omarchy-gruvbox-material. Truecolor terminals are recommended (COLORTERM=truecolor). Use Ctrl+M to toggle reduced motion and Ctrl+G to switch between ASCII-safe and Unicode glyphs.

Install & run

Quick install (curl)

curl -fsSL https://cantorindustries.com/jdsl-py/install.sh | bash

Or with options:

curl -fsSL https://cantorindustries.com/jdsl-py/install.sh | bash -s -- --version 0.6.0 --no-modify-path

Requires Python ≥ 3.11. The curl installer includes the harness dependency as well as the runtime CLI. After install:

jdsl about                 # banner + quickstart
jdsl run examples/greeter.py

Upgrade a previous curl installation with:

curl -fsSL https://cantorindustries.com/jdsl-py/install.sh | bash -s -- --uninstall
curl -fsSL https://cantorindustries.com/jdsl-py/install.sh | bash -s -- --version 0.6.0

The installed CLI also supports jdsl uninstall; captures and provider credentials are preserved.

Development (uv)

Requires uv and Python ≥ 3.11.

uv sync

uv run jdsl run examples/greeter.py                       # deterministic, no key
echo 'DEEPSEEK_API_KEY=sk-...' >> .env                    # or ANTHROPIC_API_KEY=...
uv run jdsl run examples/triage.py                        # LLM-driven
uv run pytest                                             # tests (no network)

The provider is inferred from the model id: deepseek-chat → DeepSeek, claude-* → Anthropic, gpt-*/o* → OpenAI. A .env in the working directory is loaded automatically.

The API in one screen

Combinator Meaning
root(name, system=…) Entry point. Chain .model(id) then .do(child).
seq(*children) Run in order; fail fast (behavior-tree AND).
sel(*children) Try until one succeeds (behavior-tree OR).
repeat(child, until=…, max=n) Loop child until until succeeds or max passes (retry/refine).
invert(child) · optional(child) Decorators: flip a status · fail-soft (a failing step won't abort its seq).
timeout(child, seconds=…) · oneshot(child) Decorators: bound wall-clock time · run once per run, replay the status.
act(fn, *args) Leaf calling a @tool; literal args are type-checked.
ref("key") An act argument resolved from the blackboard at run time.
store(act(…), "key") Capture an action's return value onto the blackboard.
check("key", value) Guard leaf on blackboard["key"]; string matches are case/whitespace-lenient.
predict("a -> b") DSPy-style LLM leaf: reads inputs, writes outputs.
react("q -> a", tools=[…]) Agentic leaf: the model calls @tools in a loop (function-calling) until it answers.

Layout

jdsl/          the runtime core — dsl, tree (interpreter), context, provider, render, cli
  trace/       canonical trace events, sinks, storage, redaction, replay
  ir/          Behavior IR: schema, safe guard expressions, validation, lowering
  package/     .jdsl manifest, tool contracts, provenance, export + loader
jdsl_harness/  capture + behavior compiler (separate package; optional [harness] extra)
plugins/       Claude Code plugin + Gemini CLI extension (trace capture)
examples/      runnable skills — see examples/README.md
test/          pytest suite (no network; LLM leaves use fakes)
docs/          concepts, API reference, providers, harness & compiler

Behavior harness & compiler

jdsl can also compile observed frontier-model behavior into portable policy a smaller frozen model runs. The harness captures canonical traces, mines and verifies reusable structure (exact dataflow, sequencing, guards, recovery), and leaves only irreducible semantic decisions as typed signatures — exported as a deterministic .jdsl.

jdsl harness serve                 # local capture daemon
jdsl capture inspect <id>          # exact-lineage report
jdsl compile <id> --out retail.jdsl
jdsl package run retail.jdsl --tools tools.py --model <small-model>

See docs/harness_usage.md for the hands-on guide (all three capture tiers, compile, verify, run) and docs/harness.md for the design-to-code map.

Docs

Status

Work in progress. The interpreter, combinator API, signatures, and the Anthropic / OpenAI-compatible (DeepSeek, OpenAI) backends run today. Not yet built: Google provider, and the DSPy-defining optimization step (tuning prompts against a metric) — the natural next direction now the runtime exists.

License

O`Saasy · Author: Cantor Industries

Metadata

Release files for jdsl 0.6.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for jdsl 0.6.3
File Size Uploaded Provenance
jdsl-0.6.3.tar.gz 311.8 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for jdsl 0.6.3
File Interpreter ABI Platform
jdsl-0.6.3-py3-none-any.whl Python 3 none any Details

Total release size: 467.3 kB

Release files / jdsl-0.6.3.tar.gz

Download URL jdsl-0.6.3.tar.gz
Size 311.8 kB
Tags Source
SHA-256 checksum
How to use checksums
349a50b6bdecb697ff00606a1a1d0608c56faf8a71a22e46a7673d2b9539f67a
BLAKE2b-256 checksum
How to use checksums
fd9b7cc790e38395aff810bc4749891550434bf91018ae755b3599cd0bfc9dc5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 20, 2026.

Transparency log

Release files / jdsl-0.6.3-py3-none-any.whl

Download URL jdsl-0.6.3-py3-none-any.whl
Size 155.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
24c3d0a9b3fe4852ab5bc786c80352af119e52db4422576cdfb1363083c6838c
BLAKE2b-256 checksum
How to use checksums
92c43947b3b0ea500986f89547f330b02c1bbdaa1b5dd406ba96240df1f3b29e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 20, 2026.

Transparency log

Security for jdsl 0.6.3

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for jdsl-0.6.3.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 20, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Release history Release notifications | RSS feed

This release

0.6.3 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page