Skip to main content

LDP Mode 3 (Semantic Graphs) reference implementation using FlowScript IR

Project description

flowscript-ldp

Tests Python License PyPI

First implementation of LDP Mode 3 (Semantic Graphs) using FlowScript IR.

Reference implementation for Mode 3 of the LLM Delegate Protocol (Prakash, 2026). Mode 3 — "structured relationship representations for planning and formal reasoning" — is specified but not yet evaluated in the paper. This package provides the first working implementation: a queryable semantic graph format for inter-agent communication.

What is FlowScript?

FlowScript is a semantic notation that compiles to a typed intermediate representation (IR). The IR is a graph with three collections:

  • Nodes (12 types): statements, questions, thoughts, decisions, blockers, insights, actions, completions, alternatives, exploring, parking, blocks
  • Relationships (10 types): causes, temporal, derives_from, bidirectional, tension, equivalent, different, alternative, alternative_worse, alternative_better
  • States (4 types): blocked, decided, exploring, parking

Every element has provenance metadata (source file, line number, timestamp) and SHA-256 content-addressed deduplication. This gives you a queryable graph where you can trace causal chains, map tradeoffs, find blockers, and reconstruct decisions computationally — without parsing natural language.

Quick Start

Load a pre-compiled IR graph and start querying — no external tools needed:

import json
from flowscript_ldp import FlowScriptPayload

with open("examples/sample_ir.json") as f:
    ir_data = json.load(f)

payload = FlowScriptPayload.from_dict(ir_data)

# Find all tradeoffs in the graph
tensions = payload.query.tensions()
# → 3 tensions: "cost vs control", "latency vs cost", "performance vs freshness"

# Track blockers with impact scores
blocked = payload.query.blocked()
# → 1 blocker: "add cache hit/miss monitoring to Datadog"

# Trace causal ancestry
node_id = "fdc98c25..."  # "centralized cache invalidation"
why = payload.query.why(node_id, format="minimal")
# → root_cause: "Redis cache layer"

# Encode for LDP transport
envelope = payload.encode()
# → {"ldp_version": "1.0", "payload_mode": 3, "payload_format": "flowscript-ir", ...}

If you have the FlowScript CLI installed, you can also parse .fs files directly:

from flowscript_ldp import ParserBridge, FlowScriptPayload
bridge = ParserBridge()
ir = bridge.parse_file("thinking.fs")
payload = FlowScriptPayload(ir)

Why Mode 3?

The LLM Delegate Protocol defines 6 payload modes (0–5) for inter-agent communication:

Mode Name Status
0 Text Evaluated in paper
1 Semantic Frames Evaluated in paper
2 Embedding Hints Specified, unimplemented
3 Semantic Graphs Specified, first implementation here
4 Latent Capsules Future work
5 Cache Slices Future work

Modes 0–1 pass text or structured JSON between agents. Mode 3 passes queryable graphs — agents can trace causality, find tradeoffs, and reconstruct decisions computationally instead of inferring them from prose. Five operations make the structure computable:

Query What it does Example
why(node_id) Trace causal ancestry backward root_cause: "Redis cache layer"
what_if(node_id) Trace downstream impact forward "affects 4 downstream considerations"
tensions() Extract all tradeoffs "cost vs control", "latency vs cost"
blocked() Find blockers with impact scores "Datadog trial expired" (impact: 0)
alternatives(question_id) Reconstruct decisions 3 options considered, chosen: "Redis"

Each query supports multiple output formats (chain/tree/minimal for why, tree/list/summary for what_if, axis/node/flat for tensions, comparison/tree/simple for alternatives).

Fallback Chain

Per LDP spec, when Mode 3 fails or the receiver doesn't support it, the protocol degrades gracefully:

Mode 3 (Semantic Graph) → Mode 1 (Semantic Frame) → Mode 0 (Natural Language)
from flowscript_ldp import FallbackChain

fallback = FallbackChain(ir)

# Mode 3 → Mode 1: Structured semantic frame
mode1 = fallback.to_mode1()
# → {"task_type": "decision_analysis", "instruction": "caching strategy for...", ...}

# Mode 3 → Mode 0: Natural language prose
mode0 = fallback.to_mode0()
# → "Question: caching strategy for read-heavy API endpoints\n  Option: Redis cache layer\n  ..."

Provenance and Quality

The LDP paper's key finding: noisy provenance degrades synthesis quality below the no-provenance baseline. FlowScript IR's temporal graduation model — observations must survive quality gates to persist — acts as a provenance noise filter. Mode 3 payloads carrying pre-filtered relational structure sidestep the degradation the paper identifies.

JamJet Integration

FlowScript query operations are available as JamJet-compatible tools:

from jamjet import Agent
from flowscript_ldp import get_jamjet_tools

agent = Agent(
    "analyst",
    model="claude-haiku-4-5-20251001",
    tools=get_jamjet_tools(),  # 6 async tools: tensions, blocked, why, what_if, alternatives, degrade
    instructions="Analyze the semantic graph for tradeoffs and blockers.",
)
result = await agent.run(f"Analyze this: {ir_json}")

The sync query functions are also available for standalone use without JamJet:

from flowscript_ldp.adapter import flowscript_tensions
result = flowscript_tensions(ir_data)
# → {"tensions": [{"axis": "cost vs control", "source": "...", "target": "..."}], "metadata": {...}}

A standalone FlowScriptMode3Adapter dispatcher is also available, designed to be compatible with a future ProtocolAdapter interface as JamJet adds protocol-level extensibility:

from flowscript_ldp import FlowScriptMode3Adapter

adapter = FlowScriptMode3Adapter()
result = adapter.invoke(envelope, query="tensions", fallback_mode=1)

Note: JamJet v0.1.2 does not yet include a ProtocolAdapter trait. The @tool integration via get_jamjet_tools() works today. The adapter class is forward-looking — designed for when JamJet adds protocol-level extensibility.

See examples/jamjet_workflow.yaml for a complete workflow definition and examples/standalone_demo.py for a runnable demo of all 5 queries.

CLI

flowscript-ldp info graph.json                              # IR statistics
flowscript-ldp query tensions graph.json                    # Find tradeoffs
flowscript-ldp query blocked graph.json                     # Find blockers
flowscript-ldp query why <node_id> graph.json               # Trace causes
flowscript-ldp query what-if <node_id> graph.json           # Impact analysis
flowscript-ldp query alternatives <question_id> graph.json  # Decision reconstruction
flowscript-ldp encode graph.json                            # Wrap in Mode 3 envelope
flowscript-ldp degrade graph.json --mode 0                  # Degrade to natural language

Installation

pip install flowscript-ldp

From source:

pip install git+https://github.com/phillipclapham/flowscript-ldp.git

Dependencies: pydantic>=2.0 (only runtime dependency). JamJet is optional — install separately for get_jamjet_tools().

The core package (IR models, query engine, payload, fallback, adapter, CLI) works standalone. The ParserBridge optionally requires the FlowScript CLI for parsing .fs text files into IR.

Architecture

flowscript_ldp/
├── ir.py              # Pydantic models for FlowScript IR schema
├── parser_bridge.py   # Subprocess bridge to FlowScript CLI (optional)
├── query.py           # 5 query operations, 3 formats each (Python port of TypeScript engine)
├── payload.py         # Mode 3 payload encode/decode/envelope
├── fallback.py        # Mode 3 → Mode 1 → Mode 0 degradation
├── adapter.py         # Sync tool functions + get_jamjet_tools() + standalone adapter
├── round_trip.py      # Round-trip verification utilities
└── cli.py             # Command-line interface

111 tests covering IR models, all 5 query operations with all format variants (edge cases: cycles, diamond graphs, empty graphs, depth limiting), payload round-trips, fallback chain, adapter dispatch, JamJet tool integration, and repr output.

References

License

MIT

Project details


Download files

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

Source Distribution

flowscript_ldp-0.1.0.tar.gz (41.5 kB view details)

Uploaded Source

Built Distribution

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

flowscript_ldp-0.1.0-py3-none-any.whl (29.4 kB view details)

Uploaded Python 3

File details

Details for the file flowscript_ldp-0.1.0.tar.gz.

File metadata

  • Download URL: flowscript_ldp-0.1.0.tar.gz
  • Upload date:
  • Size: 41.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for flowscript_ldp-0.1.0.tar.gz
Algorithm Hash digest
SHA256 c4c7ebec4995814d487dc46d859bcee3bd532be7f128ad02a5841f83db70074a
MD5 9575074755738d5e1e26901044fe3b93
BLAKE2b-256 53210762c75fceed56fc6eb9a1f34ed40e7dfdb9e2e920be34fc24203c8c5bf7

See more details on using hashes here.

File details

Details for the file flowscript_ldp-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: flowscript_ldp-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 29.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for flowscript_ldp-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 cd03eea4ab656b775201a33b11c7cbaaf5fc310488d7512fbc8c1a5dca2d8bfe
MD5 abfb3ae2a5853857c9a9f0474e3151e2
BLAKE2b-256 cb8a6e75840418bfd88c0048f7552fac1935e07723e73387b4deb577594a74a5

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page