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

@knpkv/ai-runtime

v0.5.3

Published

Provider-neutral Effect runtime protocol for durable local AI agents

Downloads

1,316

Readme

@knpkv/ai-runtime

Provider-neutral Effect protocol for durable local AI-agent runs. Control Center owns durable jobs, leases, authorization, and immutable workspace context; release-independent work carries a null release identity. Provider bridges can implement the small streaming adapter without leaking their native protocol.

import { AgentRuntime, makeDeterministicAgent } from "@knpkv/ai-runtime"
import { Effect, Stream } from "effect"

const fake = makeDeterministicAgent({
  events: [
    { _tag: "started", providerRunRef: null, sessionRef: null },
    { _tag: "completed", outcome: "success", sessionRef: null }
  ]
})

const program = Effect.gen(function* () {
  const runtime = yield* AgentRuntime
  return yield* runtime.run(request).pipe(Stream.runCollect)
}).pipe(Effect.provide(fake.layer))

A successfully exhausted adapter stream must end with exactly one completed event. AgentProviderError is the alternative terminal for a failed run and must occur before completion. Interrupting the stream cancels the provider execution. Provider-native session data remains server-only; consumers receive only opaque session references bound to a context fingerprint.

Runtime identity

readLocalCliRuntimeMetadata executes a trusted local CLI's bounded --version command through Effect Process. It inherits only PATH, applies a five-second timeout, and returns persistence-safe { implementation, version } metadata. Control Center attaches this metadata to the durable started event; executable paths, credentials, and provider-native session data are never persisted.

Structured tool loop

runToolAgent adds a stateless multi-turn loop around any Effect AI LanguageModel.LanguageModel. The caller selects the model, supplies an already handled Effect AI Toolkit, provides structured JSON context and a final Schema, and owns every executable tool:

import { runToolAgent } from "@knpkv/ai-runtime"
import { Effect, Schema, Stream } from "effect"
import { LanguageModel, Tool, Toolkit } from "effect/ai"

const ReadFile = Tool.make("ReadFile", {
  description: "Read one project file",
  parameters: Schema.Struct({ path: Schema.String }),
  success: Schema.Struct({ content: Schema.String })
})
const ProjectTools = Toolkit.make(ReadFile)
const ProjectToolsLive = ProjectTools.toLayer({
  ReadFile: ({ path }) => Effect.succeed({ content: `fixture:${path}` })
})
const ReviewOutput = Schema.Struct({
  summary: Schema.String
})

const review = Effect.gen(function* () {
  const model = yield* LanguageModel.LanguageModel
  const toolkit = yield* ProjectTools
  return yield* runToolAgent({
    budget: "20 minutes",
    context: { base: "abc", head: "def" },
    instructions: "Review the complete project.",
    model,
    outputSchema: ReviewOutput,
    toolkit
  }).pipe(Stream.runCollect)
}).pipe(Effect.provide(ProjectToolsLive))

Events expose run start, model progress, requested/completed/failed tools, usage, repair, validated output, and terminal outcome. Interrupting the event stream interrupts the active model or tool effect. A wall-clock budget fails with ToolAgentTimeoutError; reaching the default 64-step safety boundary emits a max-steps terminal event.

The stateless loop has no user-approval exchange. Toolkits containing a static or dynamic needsApproval policy fail configuration before the model or any handler runs; callers must resolve approval in an outer workflow or supply only tools that are already authorized for the run.

Tool input and output validation remains owned by Effect AI schemas. One malformed tool call or final JSON response receives one schema-guided repair turn; a second malformed response fails with ToolAgentInvalidResponseError and is never coerced. A schema-valid final response is accepted only when the provider reports a complete stop finish reason; incomplete finishes use the same single repair allowance.

Each model-visible tool result is limited to 64 KiB of UTF-8 JSON. Larger results require a ToolAgentArtifactSink; the model receives head/tail excerpts plus the opaque artifact ID. Add caller-owned paging and search tools to the same Toolkit so the model can inspect retained content without raising the bound. The same bound applies to results executed by a provider before they are replayed into its next prompt. makeToolAgentAdapter maps the loop into the existing durable AgentRuntime contract and chunks validated final JSON across ordinary output events. Each encoded event stays within the durable repository byte limit, with no aggregate result-count cap.

Schema-valid void tool results use JSON null on the model wire. Calls marked as provider-executed retain their provider result in the next prompt and are never invoked through a local handler. Handler failures preserve Effect AI tool semantics: the default error mode fails the run in the typed error channel, while failureMode: "return" produces a model-visible failed tool result.