npm.io
0.2.6 • Published 2d ago

assistant-cloud

Licence
MIT
Version
0.2.6
Deps
0
Vulns
0
Weekly
0
Stars
12.4K

assistant-cloud

npm version npm downloads GitHub stars

Server- and client-side SDK for Assistant Cloud, the managed thread-history, telemetry, and file-storage backend for @assistant-ui/react.

Installation

npm install @assistant-ui/react @assistant-ui/ai-sdk ai assistant-cloud

Usage

Pass an AssistantCloud instance to your runtime hook (typically useChatRuntime from @assistant-ui/ai-sdk):

import { AssistantCloud, AssistantRuntimeProvider } from "@assistant-ui/react";
import { useChatRuntime } from "@assistant-ui/ai-sdk";

const cloud = new AssistantCloud({
  baseUrl: process.env.NEXT_PUBLIC_ASSISTANT_BASE_URL!,
  anonymous: true,
});

export function Provider({ children }: { children: React.ReactNode }) {
  const runtime = useChatRuntime({ cloud });
  return <AssistantRuntimeProvider runtime={runtime}>{children}</AssistantRuntimeProvider>;
}

Building an integration

The pieces every client integration needs live in the package, so a runtime binding only maps its own events onto them.

Every API request carries Aui-Sdk with the client's own version and the identities integrations pass to registerSdk (the anonymous token bootstrap requests do not), so the cloud can tell which packages talk to a project.

  • CloudRunReporter sends run reports: nothing while telemetry is off, the cloud's environment, release and tags on every report, the beforeReport hook applied last, and a failed send that never surfaces. Keyed reports are deduplicated while in flight and after an attempt, while rate limiting releases the key for a later attempt; without a key every call reports.
  • CloudEngagementReporter derives engagement events (message_sent, run_stopped, error_shown, suggestions_shown and the rest) from what a chat integration observes and keeps the per thread state they need, such as a run's start for the stop duration. An id resolver turns the integration's own thread and message ids into the ids the cloud stores.
  • assistant-cloud/ai-sdk holds the AI SDK specifics: aiSDKV6FormatAdapter, the stored form of a UIMessage, and extractAISDKRunTelemetry, which reads the run report fields out of one run's assistant messages. The entry types its messages with ai and needs no runtime from it.
import { AssistantCloud, CloudRunReporter } from "assistant-cloud";
import { extractAISDKRunTelemetry } from "assistant-cloud/ai-sdk";

const cloud = new AssistantCloud({ baseUrl, anonymous: true });
const reporter = new CloudRunReporter(cloud);

const run = extractAISDKRunTelemetry(messages);
if (run) {
  await reporter.report(
    { threadId, ...run },
    run.assistantMessageId && `${threadId}:${run.assistantMessageId}`,
  );
}

Server telemetry

Send AI SDK 7 GenAI spans to Assistant Cloud from a Next.js app. The AI SDK emits spans through @ai-sdk/otel, and the assistant-cloud/telemetry entry needs the OpenTelemetry packages installed next to it:

npm i @vercel/otel @ai-sdk/otel @opentelemetry/api @opentelemetry/sdk-trace-base @opentelemetry/exporter-trace-otlp-http

Register the span processor in instrumentation.ts so it starts once per server process:

import { registerOTel } from "@vercel/otel";
import {
  createAssistantCloudSpanProcessor,
  createAssistantCloudTraceExporter,
} from "assistant-cloud/telemetry";

export function register() {
  registerOTel({
    serviceName: "my-app",
    spanProcessors: [
      "auto",
      createAssistantCloudSpanProcessor(
        createAssistantCloudTraceExporter({
          apiKey: process.env.ASSISTANT_API_KEY!,
        }),
      ),
    ],
  });
}

In the route that calls streamText, enable the OpenTelemetry integration and pass the active trace ID to the browser with messageMetadata:

import { OpenTelemetry } from "@ai-sdk/otel";
import { openai } from "@ai-sdk/openai";
import { convertToModelMessages, streamText } from "ai";
import { withAssistantCloudTraceMetadata } from "assistant-cloud/telemetry";

export async function POST(request: Request) {
  const { messages } = await request.json();
  const result = streamText({
    model: openai("gpt-6-luna"),
    messages: await convertToModelMessages(messages),
    telemetry: { integrations: [new OpenTelemetry()] },
  });

  return result.toUIMessageStreamResponse({
    messageMetadata: withAssistantCloudTraceMetadata(),
  });
}

Traces covers the exporter options, the span filter, and how Assistant Cloud merges a trace with the browser's run report.

Authentication

Mode Required fields Use case
Anonymous baseUrl, anonymous: true Demos and unauthenticated playgrounds.
JWT baseUrl, authToken: () => Promise<string | null> Browser apps with their own auth.
API key (server) apiKey, userId, workspaceId Server-side admin and data-plane jobs.

For advanced persistence adapters and MCP sampling instrumentation, see the docs.

Keywords