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

@d4y/agent-runtime-nuxt

v0.1.8

Published

Headless Nuxt module that connects a Nuxt app to an agent-runtime server. Ships server-side proxy routes (so your X-Agent-Runtime-App-Key never leaves the server) and a single composable, useAgentRuntime(), that exposes a typed chat client.

Readme

@d4y/agent-runtime-nuxt

Headless Nuxt module that connects a Nuxt app to an agent-runtime server.

It ships:

  • Server-side proxy routes (auto-mounted under a configurable prefix) that inject the X-Agent-Runtime-App-Key header so your secret never reaches the browser.
  • A single composable, useAgentRuntime(), that exposes a typed reactive chat client — conversation lifecycle, SSE stream consumption, generic auth/env state, workspace file listing, and a download URL builder.
  • Optional frontend helpers for common host-app concerns such as rewriting workspace paths to download URLs inside markdown, classifying files for inline preview vs. download, and rendering a minimal artifact preview panel.

It is headless on purpose: the core integration does not require any UI, and the optional frontend exports stay small and app-agnostic. Render whatever you want on top of the reactive state.

The package also exports a small shared helper surface from @d4y/agent-runtime-nuxt/shared for host apps that need generic agent-runtime config / header utilities without pulling in app-specific policy.


Install

pnpm add @d4y/agent-runtime-nuxt
# or
bun add @d4y/agent-runtime-nuxt
// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@d4y/agent-runtime-nuxt'],

  agentRuntime: {
    // All four keys are optional. When omitted they fall back to the
    // matching AGENT_RUNTIME_* environment variable, so the same build works
    // across dev / staging / prod without rebuilding.
    baseUrl: 'http://127.0.0.1:18791', // AGENT_RUNTIME_URL
    appKey: process.env.AGENT_RUNTIME_APP_KEY, // **secret** — server-only
    appId: 'omnisearch', // AGENT_RUNTIME_APP_ID
    apiPrefix: '/api/agent-runtime' // Where the proxy routes mount
  }
})

AGENT_RUNTIME_APP_KEY is mandatory at runtime. The proxy routes will return 500 until it is set.


Quick start

<script setup lang="ts">
const chat = useAgentRuntime()

const input = ref('')
async function onSubmit() {
  const text = input.value.trim()
  input.value = ''
  await chat.send(text)
}
</script>

<template>
  <div v-if="!chat.authReady.value">
    Fill in <code>{{ Object.keys(chat.app.value?.envSchema ?? {}).join(', ') }}</code>
    then call <code>chat.saveAuth({ values: { … } })</code>.
  </div>

  <UChatMessages
    v-else
    :messages="chat.messages.value"
    :status="chat.status.value"
  />

  <UChatPrompt v-model="input" @submit="onSubmit" />
</template>

The composable returns AI-SDK / Nuxt UI compatible UIMessage shapes, so @nuxt/ui's chat components work out of the box.


API

Module options

| Option | Type | Default | Env fallback | Notes | |-------------|-----------|--------------------------|------------------------|---------------------------------------| | baseUrl | string | http://127.0.0.1:18791 | AGENT_RUNTIME_URL | Trailing slashes are stripped. | | appKey | string | (none) | AGENT_RUNTIME_APP_KEY | Server-only secret. Required. | | appId | string | omnisearch | AGENT_RUNTIME_APP_ID | Must match a registered agent-runtime app. | | apiPrefix | string | /api/agent-runtime | — | Where proxy routes mount. |

Server routes (auto-mounted at apiPrefix)

| Route | Method | Purpose | |------------------------------------------------------|--------|----------------------------------------------------------| | /app | GET | Returns the active app's manifest summary. | | /conversations | POST | Open a new conversation. Body: { env?, model? }. | | /conversations/:id | DELETE | Delete a persisted conversation. | | /conversations/:id/history | GET | Return the persisted conversation history. | | /conversations/:id/stream | GET | Pipes the upstream SSE stream verbatim. | | /conversations/:id/messages | POST | Append a user turn. Body: { content, context?, requestOptions? }. | | /conversations/:id/abort | POST | Cancel the in-flight agent run. | | /conversations/:id/env | POST | Patch workspace env. Body: { env, merge? }. | | /conversations/:id/files | GET | List workspace files. | | /conversations/:id/files/raw/<path> | GET | Stream a single workspace file. |

useAgentRuntime()

const {
  conversationId, // Ref<string | null>
  messages,       // Ref<UIMessage[]>
  status,         // Ref<'idle' | 'submitted' | 'streaming' | 'ready' | 'error'>
  error,          // Ref<Error | null>
  uiActions,      // Ref<UiAction[]> — newest first, capped at 50
  app,            // Ref<AppInfo | null>
  auth,           // Ref<AppAuth>
  authReady,      // ComputedRef<boolean>
  files,          // Ref<FileEntry[]>
  fileUrl,        // (relPath: string) => string
  refreshFiles,   // () => Promise<void>
  saveAuth,       // (next: AppAuth) => Promise<void>
  start,          // () => Promise<string>
  send,           // (text: string, options?: SendOptions) => Promise<void>
  abort,          // () => Promise<void>
  reset           // () => Promise<void>
} = useAgentRuntime()

auth and authReady

The active app's manifest declares which env vars are required. The composable fetches the manifest on mount, then loads any previously-saved values from localStorage (scoped per appId). authReady is true iff every required key has a non-empty value.

await chat.saveAuth({
  values: {
    OMNISEARCH_SESSION_TOKEN: 'abc…',
    OMNISEARCH_ORGANIZATION_ID: 'e3db13ed-…'
  }
})

If a conversation is already open, saveAuth also pushes the new map to its workspace via POST /conversations/:id/env, which retriggers any matching bootstrap[] step on the harness side.

send(text, options?)

Lazily calls start() if no conversation exists. The displayed user bubble always shows text.

Use requestOptions for provider-side controls such as Qwen/vLLM chat_template_kwargs:

await chat.start({
  requestOptions: {
    temperature: 0.7,
    topP: 0.8,
    presencePenalty: 1.5
  }
})

await chat.send(input.value, {
  requestOptions: {
    extraBody: {
      top_k: 20,
      chat_template_kwargs: { enable_thinking: false }
    }
  }
})

rewriteContent is still available as a fallback when a model expects prompt text toggles rather than provider payload fields:

await chat.send(input.value, {
  rewriteContent: t => `${t}\n\n/no_think` // Qwen3 soft-switch
})

fileUrl(relPath)

Returns the fully-qualified URL of a workspace file behind the proxy. Empty string when no conversation is open.

<a :href="chat.fileUrl(file.relPath)" download>{{ file.name }}</a>

Optional frontend helpers

The module stays headless, but it exposes a small optional helper surface for host apps that want the same workspace-file ergonomics as the playground.

useAgentRuntimeMarkdown(options)

Auto-imported as a composable. It returns render() / renderInline() helpers built on markdown-it and rewrites workspace references such as sandbox:outputs/foo.png or /workspace/outputs/foo.pdf through your resolveWorkspacePath() callback.

const chat = useAgentRuntime()
const { render } = useAgentRuntimeMarkdown({
  resolveWorkspacePath: relPath => chat.fileUrl(relPath)
})

Markdown image links that point at workspace files render as clickable images. Non-image workspace links render as download links instead of broken <img> tags. Bare /workspace/... paths in plain text are auto-linked as well.

File preview utilities

Available from @d4y/agent-runtime-nuxt/frontend:

import {
  AgentRuntimeArtifactPreview,
  getAgentRuntimeFilePreviewKind,
  canPreviewAgentRuntimeFileInline,
  resolveAgentRuntimeWorkspaceUri,
  toAgentRuntimeWorkspaceRelativePath
} from '@d4y/agent-runtime-nuxt/frontend'

Example:

const kind = getAgentRuntimeFilePreviewKind(file)
// => 'image' | 'pdf' | 'text' | 'download'

Use these helpers to decide whether to render an inline image/PDF/text preview or fall back to a plain download affordance.

Minimal artifact preview component

@d4y/agent-runtime-nuxt/frontend also exports AgentRuntimeArtifactPreview, a tiny optional Vue component for inline image / PDF / text previews:

<script setup lang="ts">
import { AgentRuntimeArtifactPreview } from '@d4y/agent-runtime-nuxt/frontend'

const chat = useAgentRuntime()
</script>

<template>
  <AgentRuntimeArtifactPreview
    :file="file"
    :src="chat.fileUrl(file.relPath)" />
</template>

Local development against a workspace copy

To consume the module from a sibling project (for example, ~/projects/d4y/omnisearch-app) before publishing to npm, link it via your package manager's file: / link: protocol:

// omnisearch-app/package.json
{
  "dependencies": {
    "@d4y/agent-runtime-nuxt": "file:../../agent-runtime/packages/nuxt-module"
  }
}

then pnpm install (or bun install).

Shared helpers

For server-side host integrations, the module exposes a small app-agnostic utility surface:

import {
  normalizeAgentRuntimeBaseUrl,
  createScopeFingerprint,
  resolveAgentRuntimeConfig,
  createAgentRuntimeRequestHeaders
} from '@d4y/agent-runtime-nuxt/shared'

These helpers are intentionally limited to generic concerns such as config normalization, request-header construction, and stable scope hashing. App-level auth, tenancy, and manifest-specific context/env shaping should stay in the host application.


Release

The npm package name is @d4y/agent-runtime-nuxt.

Publishing is handled by .github/workflows/release-nuxt-module.yml using npm trusted publishing from GitHub Actions. Releases are triggered by pushing a tag in this format:

git tag nuxt-module-v0.1.0
git push origin nuxt-module-v0.1.0

The workflow verifies that the tag version matches packages/nuxt-module/package.json before running npm publish --provenance.

Before the first release, configure npm trusted publishing for:

  • npm package: @d4y/agent-runtime-nuxt
  • GitHub repository: digital4you/agent-runtime
  • workflow file: .github/workflows/release-nuxt-module.yml

License

MIT