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

@etazio/agent-sdk

v0.2.0

Published

Offizielles SDK für KI-Agenten im Etazio-Office – Handshake, Reconnect, typisierte Aufrufe und Sprachschleife (agent-protocol/v1.1).

Readme

@etazio/agent-sdk

Offizielles SDK für KI-Agenten im Etazio-Office.

Ein Agent ist in Etazio ein Teilnehmer wie jeder Mensch: Er steht im Raum, trägt ein KI-Zeichen, läuft über dieselben Wege, schreibt im Chat und kann – wenn man zu ihm hingeht und E drückt – auch sprechen. Das SDK übernimmt Handshake, Fehlerauswertung und Reconnect; alles Weitere sind typisierte Aufrufe.

npm install @etazio/agent-sdk

Voraussetzung: Node.js ≥ 20.19. Das Paket ist ESM mit eigenen TypeScript-Typen.

Agent in 15 Zeilen

import { connect } from '@etazio/agent-sdk'

const agent = await connect({
  url: process.env.ETAZIO_URL!, // z. B. https://app.etazio.de
  token: process.env.ETAZIO_AGENT_TOKEN!, // hag_…
  client: { name: 'hello-world', version: '1.0.0' },
})

console.log('Scopes:', agent.scopes.join(', '))
console.log('Im Office:', agent.world?.participants.map((p) => p.name).join(', '))

// Jemand spricht den Agenten an: @Erwähnung, Direktnachricht, Hingehen + E, Zone oder Arbeitsplatz
agent.on('address', async (a) => {
  await agent.say(a.conv, `Hallo ${a.from.displayName}, ich bin da.`)
})
ETAZIO_URL=https://app.etazio.de ETAZIO_AGENT_TOKEN=hag_… npx tsx agent.ts

Token besorgen

In Etazio auf der Agenten-Seite des Workspace Agent anlegen, Betrieb „Auf eurem eigenen Server“ wählen und die nötigen Berechtigungen (Scopes) setzen. Das Token (hag_…) wird nur einmal angezeigt und kann jederzeit rotiert oder per Kill-Switch gesperrt werden. Behandle es wie ein Passwort.

Aufrufe

| Aufruf | Wofür | Scope | |---|---|---| | connect(options) / new EtazioAgent(options).connect() | Verbinden und Handshake | office.read (+ world.presence) | | agent.refresh() | Frischer Überblick über Personen, Zonen, Objekte | wie oben | | agent.say(conv, text, parentId?) | Nachricht im Chat, Thread oder DM | chat.write | | agent.typing(conv) / agent.typingWhile(conv, work) | Tipp-Anzeige | chat.write | | agent.ask(conv, text, block) | Nachricht mit Bestätigungsknöpfen | chat.write | | agent.goTo({ x, z } \| { zoneId } \| { participantId }) | Hingehen (Wegfindung macht der Server) | world.move | | agent.sit(seatId) / agent.stand() | Hinsetzen, Aufstehen | world.seat | | agent.setState(placementId, state) | Objektzustand setzen | object.state | | agent.action(placementId, action, data?) | Objektaktion auslösen | object.action | | agent.setTv(placementId, tvState) | Fernseher steuern | tv.control | | agent.react(glyph) / agent.wave() | Reaktion, Winken | world.react | | agent.meetingToken(target?) | LiveKit-Token für Audio | meeting.audio | | agent.boardOp(envelope) | Whiteboard bearbeiten | board.write | | agent.can(scope) | Prüfen, ob das Token einen Scope hat | – | | agent.close() | Verbindung beenden | – |

Nützliche Eigenschaften: agent.hello, agent.world, agent.scopes, agent.participantId, agent.connected.

Ereignisse

agent.on('ready', (hello) => { /* nach jedem (Re-)Connect */ })
agent.on('address', (a) => { /* Ansprache */ })
agent.on('chat', (m) => { /* jede sichtbare Chatnachricht (chat.read) */ })
agent.on('participantJoined', (p) => {})
agent.on('zone', (z) => {})
agent.on('throttled', (t) => { /* Budget überschritten – langsamer werden */ })
agent.on('revoked', (r) => { /* Token gesperrt – kein Reconnect */ })

Außerdem: voice, participantLeft, seat, objectState, objectAction, emote, disconnect, error. Welche Ereignisse ankommen, bestimmen die Scopes des Tokens.

Fehler

Jede Ablehnung wird zu einem EtazioAgentError mit code – etwa forbidden (Scope fehlt), rate_limited, not_found, timeout, unavailable.

import { EtazioAgentError } from '@etazio/agent-sdk'

try {
  await agent.goTo({ zoneId: 'meeting-1' })
} catch (err) {
  if (err instanceof EtazioAgentError && err.code === 'forbidden') {
    console.error('Dem Token fehlt world.move')
  }
}

Reconnect

autoReconnect ist standardmäßig an. Nach jedem Wiederverbinden meldet sich das SDK mit derselben participantId zurück, damit Position und Sitzplatz erhalten bleiben, und feuert erneut ready. Nach revoked (Token rotiert, Agent deaktiviert, Kill-Switch) verbindet es sich bewusst nicht neu.

Sprechen

Mit attachVoice() hört der Agent zu, sobald ein Mensch neben ihm E drückt, und antwortet gesprochen – mit Untertitel im Chat. Erkennung (STT) und Stimme (TTS) laufen bei dir; für OpenAI liegen fertige Adapter bei. Eigene Anbieter implementieren SttAdapter bzw. TtsAdapter.

npm install @livekit/rtc-node   # optional, native Bindings (glibc – kein Alpine)
import { attachVoice, connect, openAiStt, openAiTts } from '@etazio/agent-sdk'

const agent = await connect({
  url: process.env.ETAZIO_URL!,
  token: process.env.ETAZIO_AGENT_TOKEN!,
  capabilities: ['chat', 'voice'],
})
const speech = { apiKey: process.env.OPENAI_API_KEY!, voice: 'alloy', language: 'de' }

attachVoice(agent, {
  stt: openAiStt(speech),
  tts: openAiTts(speech),
  async reply({ text, signal }) {
    // eigenes Modell hier – `signal` weiterreichen, damit Dazwischenreden die Anfrage abbricht
    const antwort = await meinModell(text, { signal })
    return antwort
  },
})

Nötige Scopes: meeting.audio, voice.listen, voice.speak (plus chat.write für Untertitel). Der Server entscheidet, wann ein Agent zuhören darf – nur im offenen Gespräch und nur dem Menschen, der es eröffnet hat. Was der Mensch sagt, wird nirgends gespeichert.

Stellschrauben: silenceMs (Standard 700) und threshold (0.02).

Lizenz

MIT

Routinen (ab 0.2, Protokoll v1.1)

Der Server stellt fällige Routinen als eigenes Ereignis zu – nie als address:

agent.onRoutine(async (run) => {
  await agent.setStatus(`${run.name}…`)
  const text = `Guten Morgen! (${run.instructions})`
  if (!run.dryRun) await agent.say(run.conv, text)   // nur ins konfigurierte Ziel schreiben
  await agent.setStatus(null)
  return { status: 'done', toolCalls: [], preview: run.dryRun ? text : null }
})

Der Rückgabewert wird als agent:run:report gemeldet, eine Ausnahme als failed. Details, Regeln (Trockenlauf, Vorab-Freigaben, Bestätigungs-Karten) und Grenzen: docs/agent-protocol.md §5b.