Skip to main content

Sley

A structured graph runtime for Python and TypeScript.

Sley is a fork of Caskada. It keeps that history visible while taking the graph runtime forward under its own package and project identity.

Python package TypeScript package GitHub stars

Sley runs ordinary functions as nodes in nested directed graphs. It provides explicit branching, structured fan-out and joining, retries, recovery, local concurrency, and typed execution results without depending on an LLM provider or application framework.

Why Sley

A sley is the moving loom frame that carries the reed, keeps warp threads separated, and advances the fabric. To sley also means threading the warp in a prescribed pattern. The analogy is direct: the graph defines the pattern, branches and state are the threads, Sley executes their arrangement, and a completed run is the woven result.

Install

pip install sley
npm install @jigging/sley

Python 3.13 or newer is required. The TypeScript package ships ESM and CommonJS builds.

Python

import asyncio

from sley import Flow, node


@node
def normalize(context):
    context.state["question"] = context.state["question"].strip()


@node
def answer(context):
    context.state["answer"] = f"You asked: {context.state['question']}"


normalize.link(answer)


async def main() -> None:
    state = await Flow(normalize).run({"question": "  Why?  "})
    print(state["answer"])


asyncio.run(main())

TypeScript

import { Flow, node } from '@jigging/sley'

interface State {
  question: string
  answer?: string
}

const normalize = node<State>((context) => {
  context.state.question = context.state.question.trim()
})

const answer = node<State>((context) => {
  context.state.answer = `You asked: ${context.state.question}`
})

normalize.link(answer)

const state = await new Flow(normalize).run({ question: '  Why?  ' })
console.log(state.answer)

Both programs print You asked: Why?.

Core Model

Nodes

node(handler) turns a function into one graph occurrence. A handler receives one Context and returns no application value.

@node
def decide(context):
    if needs_review(context.state):
        context.emit("review")

Nodes connect target first:

decide.link(review, "review")
decide.link(publish)  # unlabelled link

The equivalent TypeScript spelling is identical:

decide.link(review, 'review')
decide.link(publish)

Control

  • context.emit() selects the unlabelled link.
  • context.emit("review") selects a named link.
  • context.emit("work", item) also supplies the next branch's context.input.
  • A successful normal handler with no control call behaves like one implicit emit().
  • context.end(value) creates a hard terminal for the current branch and bypasses links. It does not stop the handler function, so use a normal return when later statements should not run.

Several control calls create a buffered fan-out. Sley commits that buffer only after the handler returns normally; state writes and external effects are not rolled back.

Data

context.state is the one mutable top-level map shared by every branch in one run. Sley shallow-copies the caller's initial mapping once, so run() returns the authoritative final state and does not mutate the caller's top-level map. Nested values remain shared references.

context.input is the value carried by one branch. Omitted input forwards the current input. Sley preserves application values but does not validate their schema or prove payload compatibility between links.

Flows And Combine

A Flow is a structured scope. It waits until all of its branches settle, then optionally invokes one combine callback.

def combine(context, result):
    context.state["total"] = sum(result.outputs)


batch = Flow(dispatch, combine=combine, concurrency=8)

Worker branches publish values with context.end(value). The combiner reads those values through result.outputs. Zero combiner emissions preserve the original terminals; one or more emissions replace them with new outward continuations.

Results

await flow.run(initial_state) is the simple API. It returns the final state for every completed run and raises RunError on failure. The error retains the failed result and exposes a controlling application error through standard native exception chaining.

flow.start(initial_state) returns a RunHandle whose result() method exposes the completed or failed result, including state and settled terminals.

Learn

License

Sley is licensed under the Mozilla Public License 2.0.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sley-0.0.2.tar.gz (15.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

sley-0.0.2-py3-none-any.whl (14.6 kB view details)

Uploaded Python 3

File details

Details for the file sley-0.0.2.tar.gz.

File metadata

  • Download URL: sley-0.0.2.tar.gz
  • Upload date:
  • Size: 15.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for sley-0.0.2.tar.gz
Algorithm Hash digest
SHA256 6a527fdea29988bb7f71a5c52132109891212c57851867dcd5eaa766a5504b73
MD5 bd37be31f9c9b64e5ebc58224b122cd1
BLAKE2b-256 0c5ae03c74973b72e7d9bdb25a4c306d3e44ee949d372da0cd56095606344cbe

See more details on using hashes here.

Provenance

The following attestation bundles were made for sley-0.0.2.tar.gz:

Publisher: python-publish.yml on jigmd/sley

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file sley-0.0.2-py3-none-any.whl.

File metadata

  • Download URL: sley-0.0.2-py3-none-any.whl
  • Upload date:
  • Size: 14.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for sley-0.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 6a3618ba254a848f580580e58b1d04e71e1ed31ac8ec31cc7fc66174b01b5846
MD5 aa52707201c2469f6ac1a279f5778b4e
BLAKE2b-256 16f1f0f5975108f7f967e84b45e92a8fbeb535e3256738b301cf7f7469a9b102

See more details on using hashes here.

Provenance

The following attestation bundles were made for sley-0.0.2-py3-none-any.whl:

Publisher: python-publish.yml on jigmd/sley

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.0.3

2 files

This release

0.0.2 This release

2 files

0.0.1

2 files

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