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

@aiteammate/agent-widget

v0.0.9

Published

React widget for embedding a Trugen agent by agent id.

Readme

@aiteammate/agent-widget

Embed a Trugen AI teammate in any React app.

This package gives you:

  • the widget launcher
  • the avatar/chat/talk experience
  • runtime widget styling
  • support for package-side client tools that your own app can render

Install

npm install @aiteammate/agent-widget

Import styles once

The widget depends on the package stylesheet. Import it once at your app entry.

import "@aiteammate/agent-widget/styles.css";

For Next.js App Router:

import "@aiteammate/agent-widget/styles.css";
import type { Metadata } from "next";

export const metadata: Metadata = {
  title: "My App",
};

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  );
}

Quick start

"use client";

import "@aiteammate/agent-widget/styles.css";
import { TrugenAgentWidget } from "@aiteammate/agent-widget";

export default function Page() {
  return (
    <TrugenAgentWidget
      agentId="your-agent-id"
      userName="Jane Doe"
      userId="[email protected]"
      identityPrompt={false}
      context="User is viewing the pricing page."
    />
  );
}

Widget props

| Prop | Type | Required | Description | | --- | --- | --- | --- | | agentId | string | Yes | Published Trugen agent id. | | context | string | No | Extra runtime context passed to the agent session. | | userName | string | No | Display name for the current user. | | userId | string | No | Stable user identifier, usually email or app user id. | | identityPrompt | boolean | No | Shows a name/email prompt before session start. Defaults to false. |

Next.js example

"use client";

import "@aiteammate/agent-widget/styles.css";
import { TrugenAgentWidget } from "@aiteammate/agent-widget";

export function SupportTeammate() {
  return (
    <TrugenAgentWidget
      agentId={process.env.NEXT_PUBLIC_TRUGEN_AGENT_ID ?? ""}
      userName="Customer"
      userId="[email protected]"
      context="Customer is inside the support portal."
    />
  );
}

Client tools

Client tools let your npm package render custom UI when the agent calls a tool.

This is useful when:

  • you want the agent to open a package-owned panel
  • you want the UI to render inside your app, not inside a public preview
  • you want to keep tool behavior in React components you control

Important

Client tools are package-side runtime features.

They are meant to work inside your app where @aiteammate/agent-widget is installed and running. They are not a public hosted tool runtime by themselves.

Register a client tool

Use createLeftPanelClientTool plus useRegisterClientTool.

"use client";

import {
  TrugenAgentWidget,
  createLeftPanelClientTool,
  useRegisterClientTool,
  type ClientToolPanelProps,
} from "@aiteammate/agent-widget";

type GreetingPayload = {
  message?: string;
};

function GreetingToolPanel({
  payload,
  close,
}: ClientToolPanelProps<GreetingPayload>) {
  return (
    <div className="h-full w-full bg-[#0f1316] p-6 text-white">
      <h2 className="text-2xl font-semibold">Greeting Tool</h2>
      <p className="mt-3 text-white/70">
        {payload.message ?? "Hello from your client tool."}
      </p>
      <button
        type="button"
        onClick={close}
        className="mt-6 rounded-md border border-white/15 px-4 py-2"
      >
        Close
      </button>
    </div>
  );
}

const greetingTool = createLeftPanelClientTool(GreetingToolPanel, {
  parsePayload: (rawPayload) => {
    if (!rawPayload.trim()) return {};
    return JSON.parse(rawPayload) as GreetingPayload;
  },
});

function WidgetWithClientTools() {
  useRegisterClientTool("greet_tool", greetingTool);

  return (
    <TrugenAgentWidget
      agentId="your-agent-id"
      userName="Jane Doe"
      userId="[email protected]"
    />
  );
}

export default WidgetWithClientTools;

Register multiple client tools

"use client";

import {
  TrugenAgentWidget,
  createLeftPanelClientTool,
  useRegisterClientTools,
} from "@aiteammate/agent-widget";

function FirstTool() {
  return <div className="h-full w-full bg-black text-white">First tool</div>;
}

function SecondTool() {
  return <div className="h-full w-full bg-black text-white">Second tool</div>;
}

export default function WidgetWithManyTools() {
  useRegisterClientTools({
    first_tool: createLeftPanelClientTool(FirstTool),
    second_tool: createLeftPanelClientTool(SecondTool),
  });

  return <TrugenAgentWidget agentId="your-agent-id" />;
}

Client tool payloads

When the agent calls a registered tool, the widget passes the tool payload into your panel component.

By default:

  • valid JSON objects are passed through as objects
  • other JSON values are wrapped as { value: parsed }
  • invalid JSON is wrapped as { value: rawPayload }

If you want stricter behavior, provide your own parsePayload.

const scheduleTool = createLeftPanelClientTool(SchedulePanel, {
  parsePayload: (rawPayload) => {
    const parsed = JSON.parse(rawPayload) as {
      date: string;
      participants: string[];
    };

    return {
      date: parsed.date,
      participants: parsed.participants ?? [],
    };
  },
});

Client tool display options

You can customize how the built-in agent/tool switch behaves.

const myTool = createLeftPanelClientTool(MyPanel, {
  display: {
    controlsHoverOnly: true,
    topLeftHoverOnly: true,
  },
});

display options

| Field | Type | Description | | --- | --- | --- | | controlsHoverOnly | boolean | Show panel controls only on hover. | | topLeftHoverOnly | boolean | Show the top-left display toggle only on hover. | | showBuiltInToggle | boolean | Hide the built-in toggle if set to false. | | renderToggle | (props) => ReactNode | Fully replace the built-in toggle UI. |

Use the built-in toggle in your own custom UI

The package exports the default toggle components too.

import {
  ClientToolModeToggle,
  DisplayModeToggle,
} from "@aiteammate/agent-widget";

Most apps do not need this. It is mainly useful when you want a custom wrapper while keeping the same internal interaction pattern.

How the tool flow works

  1. Your app renders TrugenAgentWidget
  2. Your app registers one or more client tools
  3. The agent calls a tool by name
  4. The widget matches that tool name against your registered tool
  5. Your React panel renders inside the widget

If the tool name does not match a registered client tool, nothing custom will render in your package.

Best practices

  • Keep tool names stable and exact
  • Keep payloads small and structured
  • Use parsePayload for validation and normalization
  • Treat client tools as app-owned UI, not public preview UI
  • Prefer one focused React component per tool

Troubleshooting

The widget looks unstyled

Make sure this import exists once in your app:

import "@aiteammate/agent-widget/styles.css";

The widget does not start

Check that:

  • agentId is valid
  • the agent is published
  • the current app can reach the runtime it needs

My client tool is not rendering

Check all of the following:

  • the component is rendered in a client component
  • the tool is registered before the agent calls it
  • the tool name in your registration exactly matches the tool name the agent uses
  • your parsePayload is not throwing

Next.js says this must be a client component

Add this at the top of the file:

"use client";

License

Proprietary. All rights reserved.