npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@monkagoras/dawl

v0.2.1

Published

Typed deterministic agent language with portable agent definitions, guard policies, replay, and adapter linking

Downloads

283

Readme

DAWL

DAWL is a deterministic language for defining agents, typed capabilities, guard policies, and auditable multi-agent workflows.

The workflow owns control flow. Agents may reason, call allowlisted tools, and return typed data, but they do not silently choose the next workflow node. DAWL compiles the source before execution, links agent contracts to adapters, validates structured values, enforces policy boundaries, and emits a replayable event history.

What DAWL 0.2 provides

  • First-class agent, tool, activity, scope, guard, type, flow, and fn declarations.
  • Named imports, exports, re-exports, relative modules, and manifest-resolved DAWL packages.
  • Structural types compiled to JSON Schema 2020-12 compatible contracts.
  • Typed agent input and output validation in the DAWL runtime.
  • Explicit tool capabilities with effects and idempotency metadata.
  • Input, output, and tool-call guard policies with allow, ask, and deny decisions.
  • Explicit agent-as-tool delegation with cycle detection.
  • Bounded retries with explicit loop-carried state.
  • Deterministic activity and agent replay identities.
  • Runtime enforcement for wall-clock time, tool-call limits, transport retries, tool retries, and output repair retries.
  • dawl.json, dawl.lock, and .dawl/catalog.json with separate intent, resolution, and environment responsibilities.
  • Canonical Agent IR, public descriptors, A2A Agent Card export, and MCP tool normalization.
  • Pre-execution graph compilation and live terminal diagrams.
  • Zero runtime dependencies.

Install

DAWL requires Node.js 22 or newer.

npm install @monkagoras/dawl

For local development:

npm install
npm run verify

Core syntax

use "./contracts.dawl" {
  Task,
  Finding,
  ChangeSet,
  Review,
  RepoRead,
  RepoEdit
}

guard WorkspacePolicy on tool.call {
  deny when tool.effect == open-world

  ask when tool.effect == destructive
       and tool.path outside workspace

  allow otherwise
}

export agent Developer(
  task: Task,
  findings: [Finding] = []
) -> ChangeSet {
  describe "Implements one bounded repository task"

  instruct """
  Implement the supplied task.
  Address every review finding.
  Return only the declared ChangeSet structure.
  """

  model coding {
    require [tool-use, structured-output]
    prefer [reasoning, long-context]
  }

  tools [RepoRead, RepoEdit]
  guards { tool WorkspacePolicy }
  session fresh

  limits {
    tool-calls 40
    time "10m"
    turns 24
    tokens 80000
    concurrency 1
  }

  retry {
    transport 2
    tool 1
    output 2
  }

  observe {
    trace standard
    content redact
  }
}

export agent Reviewer(change: ChangeSet) -> Review {
  describe "Performs a read-only review"
  instruct "Review the change and return pass plus concrete findings."
  model review { require [tool-use, structured-output] }
  tools [RepoRead]
  guards { tool WorkspacePolicy }
  limits { tool-calls 20 time "5m" }
  retry { transport 2 output 2 }
}

export flow review(
  task: Task,
  M: int = 3
) -> "approved" | "failedReview" {
  work:
    return approve(task, M)
}

fn approve(
  task: Task,
  M: int
) -> "approved" | "failedReview" {
  repeat M fresh with findings = [] {
    review = Developer(task, findings) -> Reviewer

    review.pass yes -> return "approved"
                no  -> retry with review.findings
  }

  return "failedReview"
}

The important retry rule is explicit: only values declared after with cross fresh attempt boundaries. retry with review.findings supplies the next value. No hidden caller state is inherited by a function.

Types

DAWL supports a deliberately small JSON-compatible type system:

export type Finding {
  severity: "low" | "medium" | "high"
  message: string
  file: string?
  line: int?
}

export type Result = "approved" | "failed"
export type Findings = [Finding]

Built-in types include:

bool
int
number
string
text
bytes
json
null
[T]
T?
record types
literal unions

A non-text agent output is validated by DAWL after the adapter returns it. Invalid output may be repaired only within the declared retry output budget. There is no silent fallback from typed output to raw text.

Agents

An agent declaration owns the portable semantic contract:

  • name and description
  • typed input and output
  • instructions and instruction digest
  • model profile plus required and preferred capabilities
  • exact logical tool allowlist
  • delegated agent allowlist
  • session mode
  • guard bindings
  • limits and retry budgets
  • observability metadata

Provider IDs, credentials, host paths, and concrete tool implementations do not belong in .dawl source. They are deployment bindings in dawl.json and adapters.

Defaulted agent parameters are materialized before adapter invocation and are included as JSON Schema default annotations in Agent IR. Defaults must be JSON constants.

Agent delegation

A parent may expose another agent as a typed tool:

agent Researcher(topic: string) -> Research {
  instruct "Research the topic."
  model research { require [structured-output] }
}

agent Manager(task: string) -> Plan {
  instruct "Use the Researcher when evidence is needed."
  model planning { require [structured-output] }
  delegate [Researcher]
}

The delegated agent keeps its own model profile, tools, guards, limits, and output validation. DAWL rejects calls to undeclared delegates and rejects circular delegation graphs.

This is not a handoff. The parent retains control and receives a typed result.

Capabilities

DAWL keeps four external concepts distinct.

Tool

A model-selectable operation inside an agent:

export tool RepoRead(path: string) -> text {
  effects [workspace.read]
  idempotency idempotent
}

Activity

A workflow-selected external operation:

export activity PublishRelease(release: json) -> json {
  effects [open-world, destructive]
}

Scope

A resource or lifecycle boundary around nested workflow execution:

export scope Worktree(issue: string) -> json provides json

Agent

A model-driven loop with typed input, typed output, capabilities, policies, and budgets.

Unresolved calls are compile errors. Capitalization is style only and does not decide whether a symbol is an agent.

Guard policies

Policies are deterministic declarations evaluated by DAWL, not prompt hints.

guard WorkspacePolicy on tool.call {
  deny when tool.effect == open-world

  ask when tool.effect == destructive
       and tool.path outside workspace

  allow otherwise
}

Supported lifecycle events are:

agent.input
agent.output
tool.call

Example lifecycle guards:

guard InputPolicy on agent.input {
  deny when input.task == "blocked"
  allow otherwise
}

guard OutputPolicy on agent.output {
  ask when output.status == "needs-approval"
  deny when output.status == "unsafe"
  allow otherwise
}

Bind them in an agent:

guards {
  input InputPolicy
  tool WorkspacePolicy
  output OutputPolicy
}

Multiple guards compose conservatively. deny wins over ask, and ask wins over allow. A guard bound to the wrong lifecycle event is rejected during project checking.

MCP effect annotations are treated as untrusted hints by default. They become enforceable effects only when the caller explicitly marks the MCP source as trusted.

Modifiers

fresh

repeat M fresh creates attempt-local state. Only declared loop state crosses attempts.

once

once gives a call an at-most-once identity at its source call site across repeat attempts. A successful result is reused within the run and remains replayable from recorded history.

summary = Summarizer(results) once

readonly

For declared activities and agents, readonly rejects write, destructive, or open-world effects before execution.

summary = Summarizer(results) readonly

Legacy unresolved activities still receive the modifier for adapter compatibility, but DAWL cannot prove their effects. Security-sensitive projects should declare every activity and tool.

Runtime budgets

DAWL core enforces the limits it can independently observe:

limits {
  tool-calls 40
  time "10m"
}

retry {
  transport 2
  tool 1
  output 2
}
  • time applies to the complete agent invocation and passes an abort signal to the adapter.
  • tool-calls counts every actual tool attempt, including retries.
  • transport retries adapter invocation failures.
  • tool retries tool implementation or tool output validation failures.
  • output retries invalid agent structured output.

turns, tokens, and concurrency remain part of Agent IR and must be enforced or reported by an adapter because the DAWL core cannot reliably observe provider-internal accounting. Silent adapter noncompliance is not acceptable for production adapters.

Project files

dawl.json

Human-authored intent and version ranges:

{
  "$schema": "https://dawl.dev/schemas/project-v1.json",
  "language": "^0.2",
  "entries": ["flows/review.dawl"],
  "packages": {
    "@dawl/repository": {
      "package": "@dawl/repository",
      "entry": "index.dawl",
      "version": "^1.0.0"
    }
  },
  "adapters": {
    "pi": {
      "package": "@dawl/pi-adapter",
      "version": "^1.0.0",
      "protocol": "^1"
    }
  },
  "profiles": {
    "coding": {
      "adapter": "pi",
      "model": "provider/coding-model"
    },
    "review": {
      "adapter": "pi",
      "model": "provider/review-model"
    }
  },
  "bindings": {
    "RepoRead": "pi:read",
    "RepoEdit": "pi:edit"
  },
  "policy": {
    "requireLock": true,
    "denyUnresolvedTools": true
  }
}

A local DAWL package may use path instead of package:

{
  "packages": {
    "@company/contracts": {
      "path": "./packages/contracts",
      "entry": "index.dawl",
      "version": "1.0.0"
    }
  }
}

dawl.lock

Machine-authored approved resolution:

  • manifest digest
  • catalog digest
  • exact adapter protocol and version data
  • adapter and package integrity digests
  • model profiles
  • tool bindings
  • project policy

Commit this file.

.dawl/catalog.json

Machine-local discovery data:

  • installed adapters
  • adapter capabilities
  • available models
  • concrete tools
  • DAWL packages
  • schema and file integrity data

This file describes the current environment and is normally ignored by Git.

CLI

dawl sync
dawl install
dawl update
dawl check flows/review.dawl
dawl check flows/review.dawl --locked
dawl build flows/review.dawl
dawl inspect agents flows/review.dawl
dawl run flows/review.dawl --flow review --input '{"task":{"id":"42","description":"Fix it"}}'
dawl run flows/review.dawl --approve
dawl diagram flows/review.dawl --flow review --plain

Command responsibilities:

  • sync discovers adapters, tools, models, and DAWL packages into the catalog. It does not alter the lock.
  • install installs missing adapters and packages, refreshes the catalog, and writes the lock.
  • update intentionally refreshes installed resolution and the lock.
  • check parses, links, type-checks, and validates environment compatibility.
  • build emits canonical content-addressed Agent IR and workflow graphs.
  • inspect agents emits public exported agent descriptors.
  • run validates the lock and environment before adapter execution.
  • diagram renders a static terminal graph.

Build artifacts

dawl build writes:

.dawl/build/<digest>/module.dawlir.json
.dawl/build/<digest>/agents.json
.dawl/build/<digest>/graphs.json

Adapters consume linked Agent IR, never DAWL source text.

Adapter protocol

A minimal adapter implements:

export function createAdapter(options) {
  return {
    async initialize(request) {
      return {
        name: "example",
        version: "1.0.0",
        protocolVersion: "1"
      };
    },

    async catalog() {
      return {
        capabilities: {
          "tool-use": "native",
          "structured-output": "native"
        },
        tools: [{ name: "example:read" }],
        models: [{ id: "example-model" }]
      };
    },

    async validate(agentIR) {
      return [];
    },

    async invokeAgent(request) {
      const {
        agent,
        input,
        attempt,
        repair,
        runId,
        path,
        callTool,
        signal
      } = request;

      return { status: "ok" };
    }
  };
}

The adapter must create the concrete model session, expose only the linked tools and delegates, honor required capabilities, and return the final JSON-compatible value. DAWL validates the result again.

Interoperability

A2A

import { toAgentCard } from "@monkagoras/dawl";

const card = toAgentCard(publicDescriptor, {
  url: "https://agents.example/reviewer"
});

The exporter targets A2A Agent Card protocol version 1.0.0 and preserves DAWL input schema, output schema, tools, and digest in namespaced skill metadata.

MCP

import { normalizeMcpTool, toMcpTool } from "@monkagoras/dawl";

const untrusted = normalizeMcpTool(mcpTool);
const trusted = normalizeMcpTool(mcpTool, { trusted: true });
const exported = toMcpTool(dawlToolIR);

Untrusted MCP annotations are retained as reportedEffects but are not promoted to enforceable effects.

JavaScript API

import {
  adapterCatalog,
  applyDiagramEvent,
  buildAgentIR,
  checkProject,
  compile,
  createDiagramState,
  createProjectResolver,
  createRuntime,
  loadProject,
  normalizeMcpTool,
  parse,
  publicAgentDescriptor,
  renderDiagram,
  schemaForType,
  toAgentCard,
  toMcpTool,
  validateValue
} from "@monkagoras/dawl";

See examples/agent-project for a complete project with contracts, agents, guard policies, profiles, bindings, an adapter, and a typed review flow.

Determinism and replay

DAWL distinguishes several guarantees:

  • Control determinism: source controls sequence, branch, retry, parallel structure, and scope.
  • Resolution determinism: imports, adapters, packages, profiles, bindings, and integrity data are locked.
  • Contract determinism: input and output schemas are canonical and hashed.
  • Replay determinism: completed activities and agents can be reused from event history.
  • Live model determinism: not guaranteed by DAWL for hosted models.

A replay identity includes source digest, call path, arguments or typed input, attempt identity unless once, and agent digest where applicable.

Security model

DAWL enforces capability reduction, schema validation, policy decisions, and effect-aware readonly checks. It is not an operating-system sandbox.

  • Tool allowlists are exact.
  • Guard policy is evaluated outside the model.
  • Open-world and destructive effects can be denied or approved.
  • Agent delegation is exact and cycle-free.
  • Adapter-reported capabilities are checked before execution.
  • MCP annotations are untrusted by default.
  • Tool implementations still run with the permissions of their process.

Strong multi-tenant isolation requires containers, VMs, or OS-level sandboxing. See ROADMAP.md.

Development

npm run quality
npm test
npm run build
npm run verify
npm run bench
npm run example
npm pack --dry-run

The quality gate enforces source files below 200 lines, functions at or below 20 lines, and low cyclomatic complexity.

Documentation

  • docs/research/architecture.md records the research basis and architecture decisions.
  • docs/superpowers/plans/2026-08-06-agent-language.md records the implementation plan.
  • ROADMAP.md separates intentionally deferred work from the 0.2 contract.