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

@tisyn/agent

v0.8.0

Published

`@tisyn/agent` defines the typed capability boundary between Tisyn workflows and the work that actually gets performed. It turns effectful calls into explicit contracts: named agent boundaries, typed operation payloads, and handlers the runtime can dispat

Downloads

1,093

Readme

@tisyn/agent

@tisyn/agent defines the typed capability boundary between Tisyn workflows and the work that actually gets performed. It turns effectful calls into explicit contracts: named agent boundaries, typed operation payloads, and handlers the runtime can dispatch locally or across a transport boundary.

If @tisyn/ir describes what work should happen, @tisyn/agent describes who can do it and how it is called.

Where It Fits

This package sits between authored workflow logic and concrete side effects.

  • The compiler lowers authored calls like yield* Service().method(...) into effectful IR.
  • The runtime resolves those effects through installed agent handlers.
  • The transport layer can expose the same declarations across process, worker, or network boundaries.

@tisyn/agent is the capability layer that gives effect IDs stable names, payload shapes, and implementations.

Core Concepts

  • agent(id, operations) declares a named capability boundary.
  • operation<Spec>() declares one typed operation on that boundary.
  • implementAgent() binds handlers to a declaration.
  • Effects.around() installs Effection middleware layers that intercept or route effect invocations.
  • dispatch() performs an effect call through the current Effects middleware boundary.
  • invoke() executes a declared operation against the current dispatch stack.
  • useAgent() retrieves a typed handle for an agent bound in the current scope via useTransport().

Agent declarations are typed metadata plus call helpers. They describe invocations, but do not execute anything by themselves.

Public API

The public surface exported from src/index.ts includes:

  • agent — declare a named agent boundary and its available operations
  • operation — declare the typed input/output contract for one operation
  • implementAgent — bind handlers to a declaration so the runtime can dispatch them
  • Effects — the Effection middleware context for invocation routing; use Effects.around() to install intercept layers
  • dispatch — perform an effect call through the current Effects middleware boundary
  • invoke — execute a declared operation against the current dispatch stack
  • useAgent — retrieve a typed handle for an agent previously bound via useTransport()
  • installEnforcement — install a non-bypassable enforcement wrapper that runs before the Effects middleware chain
  • installCrossBoundaryMiddleware — install an IR function node as the cross-boundary middleware carrier for further remote delegation
  • getCrossBoundaryMiddleware — read the current cross-boundary middleware carrier from scope (returns null if not set)
  • evaluateMiddlewareFn — drive an IR function node as a middleware function with scope-local dispatch semantics

Important exported types:

  • OperationSpec — describe the typed input and result shape of an operation
  • DeclaredAgent — represent the callable declaration returned by agent()
  • AgentDeclaration — structural type for a declared agent contract
  • AgentImplementation — declaration paired with handlers and install logic
  • ImplementationHandlers — type the handler map expected by implementAgent()
  • Invocation — represent one concrete operation call ready for dispatch
  • ArgsOf — extract the input shape from an operation declaration
  • ResultOf — extract the result type from an operation declaration
  • Workflow — represent the authored workflow return type used in ambient declarations
  • AgentHandle — typed operation handle returned by useAgent()
  • EnforcementFn — function type for enforcement wrappers installed via installEnforcement()

Declare an Agent

import { agent, operation } from "@tisyn/agent";

const orders = agent("orders", {
  fetch: operation<{ input: { orderId: string } }, { id: string; total: number }>(),
  cancel: operation<{ input: { orderId: string } }, void>(),
});

Calling a declared operation produces an invocation description. It is a typed effect request, not a direct function call.

const request = orders.fetch({ input: { orderId: "ord-1" } });

Implement Handlers

import { implementAgent } from "@tisyn/agent";

const ordersImpl = implementAgent(orders, {
  *fetch({ input }) {
    return { id: input.orderId, total: 42 };
  },

  *cancel() {},
});

The implementation exposes call(opName, payload) for use by protocol servers. To make the handlers reachable at the dispatch layer, pass the implementation to a transport (see @tisyn/transport).

Invoke an Operation

import { invoke } from "@tisyn/agent";

const order = yield* invoke(
  orders.fetch({ input: { orderId: "ord-1" } }),
);

This is useful when:

  • application code wants to call an installed agent directly
  • one agent implementation delegates work to another
const checkoutImpl = implementAgent(checkout, {
  *complete({ input }) {
    const order = yield* invoke(
      orders.fetch({ input: { orderId: input.orderId } }),
    );

    return { ok: order.total > 0 };
  },
});

Mental Model

An agent declaration gives Tisyn a typed, named capability boundary.

  • Declarations define what operations exist and what they accept or return.
  • Invocations describe one requested operation call.
  • Implementations attach concrete handlers to those declarations.
  • Effects middleware decides how invocations are routed.

That routing can stay local, or it can be forwarded through another layer such as a worker or network transport. @tisyn/agent stays focused on the contract and dispatch shape rather than the transport itself.

Relationship to the Rest of Tisyn

  • Use @tisyn/agent with @tisyn/runtime when executing IR against real effect handlers.
  • Use it with @tisyn/transport when those handlers must be reached across process, worker, or network boundaries.
  • @tisyn/compiler discovers effect usage from authored workflow source, but does not execute effects.
  • @tisyn/protocol defines wire messages for remote execution, but @tisyn/agent itself remains protocol-agnostic.

What This Package Does Not Define

@tisyn/agent does not define:

  • the IR language
  • durable execution
  • replay semantics
  • transport or protocol messages

It defines the typed capability layer that those systems rely on.

Summary

Use @tisyn/agent when you want effectful workflow calls to become explicit, typed capability contracts.

It gives Tisyn a stable boundary between workflow intent and concrete execution: declarations name the capability, operations define the payload shape, implementations provide handlers, and dispatch makes invocation routable wherever the work actually happens.