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

@standardagents/vue

v0.15.3

Published

Vue SDK for Standard Agents

Downloads

1,940

Readme

@standardagents/vue

Vue 3 composables and components for Standard Agents - connect to AI agent threads with real-time updates, send messages, manage files, and listen for custom events.

Installation

npm install @standardagents/vue
# or
pnpm add @standardagents/vue
# or
yarn add @standardagents/vue

Requirements: Vue 3.3+

Quick Start

// main.ts
import { createApp } from 'vue'
import { StandardAgentsPlugin } from '@standardagents/vue'
import App from './App.vue'

const app = createApp(App)
app.use(StandardAgentsPlugin, { endpoint: 'https://api.example.com' })
app.mount('#app')
<!-- App.vue -->
<script setup lang="ts">
import { ThreadProvider, useThread } from '@standardagents/vue'
</script>

<template>
  <ThreadProvider threadId="thread-123">
    <ChatInterface />
  </ThreadProvider>
</template>
<!-- ChatInterface.vue -->
<script setup lang="ts">
import { ref } from 'vue'
import { useThread } from '@standardagents/vue'

const { messages, sendMessage, status } = useThread()
const input = ref('')

const handleSend = async () => {
  await sendMessage({ role: 'user', content: input.value })
  input.value = ''
}
</script>

<template>
  <div>
    <p>Status: {{ status }}</p>
    <div v-for="msg in messages" :key="msg.id">
      <strong>{{ msg.role }}:</strong> {{ msg.content }}
    </div>
    <input v-model="input" @keyup.enter="handleSend" />
    <button @click="handleSend">Send</button>
  </div>
</template>

Authentication

The package reads the authentication token from localStorage using the key agentbuilder_auth_token:

// Set the token before using the composables
localStorage.setItem('agentbuilder_auth_token', 'your-token-here')

All API requests and WebSocket connections will automatically include this token.

API Reference

StandardAgentsPlugin

Vue plugin that configures the Standard Agents client for all components.

Options:

  • endpoint: string - The API endpoint URL (required)
import { createApp } from 'vue'
import { StandardAgentsPlugin } from '@standardagents/vue'

const app = createApp(App)
app.use(StandardAgentsPlugin, { endpoint: 'https://api.example.com' })

ThreadProvider

Component that establishes a WebSocket connection to a specific thread and provides context to child components.

Props:

  • threadId: string - The thread ID to connect to
  • preload?: boolean - Fetch existing messages on mount (default: true)
  • live?: boolean - Enable WebSocket for real-time updates (default: true)
  • useWorkblocks?: boolean - Group tool calls into workblocks (default: false)
  • depth?: number - Message depth level (default: 0)
  • includeSilent?: boolean - Include silent messages (default: false)
  • endpoint?: string - Override the endpoint from plugin config
<template>
  <ThreadProvider threadId="thread-123" :live="true">
    <YourComponents />
  </ThreadProvider>
</template>

<script setup lang="ts">
import { ThreadProvider } from '@standardagents/vue'
</script>

useThread()

Composable to access the full thread context. Must be used within a ThreadProvider.

Returns:

  • threadId: string - The thread ID
  • messages: Ref<Message[]> - Reactive array of messages
  • workblocks: ComputedRef<ThreadMessage[]> - Messages transformed to workblocks (if useWorkblocks is true)
  • status: Ref<ConnectionStatus> - Connection status ("connecting" | "connected" | "disconnected" | "reconnecting")
  • loading: Ref<boolean> - Loading state (alias: isLoading)
  • error: Ref<Error | null> - Error state
  • options: ThreadProviderOptions - Options passed to the provider
  • sendMessage: (payload: SendMessagePayload) => Promise<Message> - Send a message
  • stopExecution: () => Promise<void> - Stop current execution
  • onEvent: <T>(eventType, callback) => () => void - Subscribe to custom events (alias: subscribeToEvent)
  • files: ComputedRef<ThreadFile[]> - All files (pending + committed)
  • addFiles: (files: File[] | FileList) => void - Upload files
  • removeFile: (id: string) => void - Remove a pending file
  • getFileUrl: (file: ThreadFile) => string - Get file URL
  • getThumbnailUrl: (file: ThreadFile) => string - Get thumbnail URL
  • getPreviewUrl: (file: ThreadFile) => string | null - Get preview URL

Example:

<script setup lang="ts">
import { useThread } from '@standardagents/vue'

const {
  messages,
  sendMessage,
  stopExecution,
  status,
  isLoading,
  files,
  addFiles,
  onEvent,
} = useThread()

// Subscribe to custom events
onEvent<{ todos: string[] }>('todo-updated', (data) => {
  console.log('Todos:', data.todos)
})
</script>

<template>
  <div>
    <p v-if="isLoading">Loading...</p>
    <p>Status: {{ status }}</p>

    <div v-for="msg in messages" :key="msg.id">
      <strong>{{ msg.role }}:</strong> {{ msg.content }}
    </div>

    <input type="file" multiple @change="(e) => addFiles(e.target.files)" />

    <div v-for="file in files" :key="file.id">
      {{ file.name }} ({{ file.status }})
    </div>

    <button @click="sendMessage({ role: 'user', content: 'Hello!' })">Send</button>
    <button @click="stopExecution">Stop</button>
  </div>
</template>

File Management

The useThread() composable provides file management capabilities:

<script setup lang="ts">
import { useThread } from '@standardagents/vue'

const { files, addFiles, removeFile, getPreviewUrl } = useThread()

const handleFileChange = (event: Event) => {
  const input = event.target as HTMLInputElement
  if (input.files) {
    addFiles(input.files)
  }
}
</script>

<template>
  <div>
    <input type="file" multiple accept="image/*,.pdf,.txt" @change="handleFileChange" />

    <div v-for="file in files" :key="file.id">
      <img
        v-if="file.isImage && file.status !== 'uploading'"
        :src="getPreviewUrl(file) || ''"
        :alt="file.name"
        width="50"
      />
      <span>{{ file.name }}</span>
      <span>{{ file.status }}</span>
      <span v-if="file.status === 'uploading'">Uploading...</span>
      <span v-if="file.status === 'error'">Error: {{ file.error }}</span>
      <button v-if="file.status !== 'committed'" @click="removeFile(file.id)">
        Remove
      </button>
    </div>
  </div>
</template>

File States

  • uploading - File is being uploaded
  • ready - Upload complete, file ready to attach to message
  • committed - File is attached to a sent message
  • error - Upload failed

Types

interface Message {
  id: string
  role: 'user' | 'assistant' | 'system' | 'tool'
  content: string | null
  created_at: number
  attachments?: string // JSON array of AttachmentRef
}

interface SendMessagePayload {
  role: 'user' | 'assistant' | 'system'
  content: string
  silent?: boolean
  attachments?: string[]  // Paths of files to attach
}

interface ThreadFile {
  id: string
  name: string
  mimeType: string
  size: number
  isImage: boolean
  status: 'uploading' | 'ready' | 'committed' | 'error'
  error?: string
  path?: string
  localPreviewUrl: string | null
}

type ConnectionStatus = 'connecting' | 'connected' | 'disconnected' | 'reconnecting'

Complete Example

<script setup lang="ts">
import { onMounted } from 'vue'
import { ThreadProvider } from '@standardagents/vue'

onMounted(() => {
  localStorage.setItem('agentbuilder_auth_token', 'your-token')
})
</script>

<template>
  <ThreadProvider threadId="thread-123">
    <AgentChat />
  </ThreadProvider>
</template>
<!-- AgentChat.vue -->
<script setup lang="ts">
import { ref } from 'vue'
import { useThread } from '@standardagents/vue'

const input = ref('')

const {
  messages,
  sendMessage,
  stopExecution,
  status,
  isLoading,
  files,
  addFiles,
  removeFile,
  getPreviewUrl,
} = useThread()

const handleSend = async () => {
  if (!input.value.trim()) return
  await sendMessage({ role: 'user', content: input.value })
  input.value = ''
}

const handleFileChange = (event: Event) => {
  const target = event.target as HTMLInputElement
  if (target.files) addFiles(target.files)
}
</script>

<template>
  <div>
    <p v-if="isLoading">Loading messages...</p>

    <div v-for="msg in messages" :key="msg.id">
      <strong>{{ msg.role }}:</strong> {{ msg.content }}
    </div>

    <input type="file" multiple @change="handleFileChange" />

    <div v-for="file in files.filter(f => f.status !== 'committed')" :key="file.id">
      <img
        v-if="file.isImage && getPreviewUrl(file)"
        :src="getPreviewUrl(file)!"
        :alt="file.name"
        width="50"
      />
      <span>{{ file.name }} ({{ file.status }})</span>
      <button @click="removeFile(file.id)">x</button>
    </div>

    <div>
      <input v-model="input" @keyup.enter="handleSend" />
      <button @click="handleSend">Send</button>
      <button @click="stopExecution">Stop</button>
      <span>Status: {{ status }}</span>
    </div>
  </div>
</template>

TypeScript Support

The package includes full TypeScript definitions:

import type {
  Message,
  SendMessagePayload,
  ThreadFile,
  ConnectionStatus,
  ThreadContext,
} from '@standardagents/vue'