> ## Documentation Index
> Fetch the complete documentation index at: https://ago.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# JavaScript SDK

> Build custom chat experiences with the AGO JavaScript SDK

The AGO JavaScript SDK (`@useago/sdk`) lets you integrate AGO agents into any web application. Use it to build fully custom chat interfaces, handle streaming responses, manage conversations, and register client-side functions that agents can invoke.

## Installation

```bash theme={null}
npm install @useago/sdk
```

For React applications, the SDK also exports hooks and pre-built components:

```bash theme={null}
npm install @useago/sdk react react-dom
```

## Quick Start

### Vanilla JavaScript

```javascript theme={null}
import { AgoClient } from "@useago/sdk";

const client = new AgoClient({
  baseUrl: "https://YOUR-DOMAIN.useago.com",
  widgetId: "unique-user-id",
});

// Send a message and receive a streaming response
const response = await client.sendMessage("How do I reset my password?");
console.log(response.content);
```

### Zero-Config Setup

If your page already includes the AGO widget script or meta tags, use `createAgo` to auto-detect configuration:

```javascript theme={null}
import { createAgo } from "@useago/sdk";

const client = createAgo(); // Detects config from page environment
```

The SDK looks for configuration in this order:

1. `<meta name="ago-base-url">` tag
2. `data-ago-base-url` attribute on the script tag
3. `window.AGO.basepath` global variable

You can still pass overrides:

```javascript theme={null}
const client = createAgo({ debug: true, widgetId: "user-123" });
```

### React

```jsx theme={null}
import { AgoProvider } from "@useago/sdk/react";
import { ChatWidget } from "@useago/sdk/react";

function App() {
  return (
    <AgoProvider baseUrl="https://YOUR-DOMAIN.useago.com">
      <ChatWidget
        title="Support"
        welcomeMessage="Hello! How can I help you?"
      />
    </AgoProvider>
  );
}
```

### Vue.js

```javascript theme={null}
import { createApp } from "vue";
import { AgoPlugin } from "@useago/sdk/vue";

const app = createApp(App);
app.use(AgoPlugin, { baseUrl: "https://YOUR-DOMAIN.useago.com" });
app.mount("#app");
```

Then use composables in your components:

```vue theme={null}
<script setup>
import { useAgo, useMessages } from "@useago/sdk/vue";

const { client } = useAgo();
const { messages, sendMessage } = useMessages();
</script>
```

### Angular

```typescript theme={null}
import { provideAgo, AgoService } from "@useago/sdk/angular";

bootstrapApplication(AppComponent, {
  providers: [
    provideAgo({ baseUrl: "https://YOUR-DOMAIN.useago.com" }),
  ],
});
```

Then inject in any component or service:

```typescript theme={null}
import { AgoService } from "@useago/sdk/angular";

@Component({ ... })
export class ChatComponent {
  constructor(private ago: AgoService) {}
}
```

***

## Configuration

Create a client instance with the following options:

| Option           | Required | Description                                                                                                                         |
| ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `baseUrl`        | Yes      | Your AGO instance URL (e.g., `https://YOUR-DOMAIN.useago.com`)                                                                      |
| `widgetId`       | No       | A unique identifier for the current user (auto-generated if omitted)                                                                |
| `agent`          | No       | Default agent (id or slug) for new conversations. Shorthand for `defaultAgentId`.                                                   |
| `defaultAgentId` | No       | Default agent for new conversations. Prefer `agent`.                                                                                |
| `permission`     | No       | Permission name to apply to all requests (sent as `X-Widget-Permission`). Same value the widget reads from `window.AGO.permission`. |
| `userEmail`      | No       | User email for identification                                                                                                       |
| `userJwt`        | No       | JWT token for authenticated users (see [Widget Authentication](/security/widget-authentication))                                    |
| `debug`          | No       | Enable debug logging in the console                                                                                                 |

```javascript theme={null}
const client = new AgoClient({
  baseUrl: "https://YOUR-DOMAIN.useago.com",
  widgetId: "user-12345",
  defaultAgentId: "agent-uuid",
  userEmail: "user@example.com",
  debug: true,
});
```

You can update configuration after initialization:

```javascript theme={null}
client.updateConfig({
  userJwt: "new-jwt-token",
  defaultAgentId: "another-agent-uuid",
});
```

***

## Sending Messages

### Basic Message

```javascript theme={null}
const response = await client.sendMessage("What are your business hours?");

console.log(response.content);    // The agent's reply
console.log(response.sources);    // Knowledge sources cited
console.log(response.agent);      // Agent info (name, id)
```

### Message with Options

```javascript theme={null}
const response = await client.sendMessage("Follow-up question", {
  conversationId: "existing-conversation-uuid",  // Continue a conversation
  agentId: "specific-agent-uuid",                // Override default agent
  files: [fileObject],                           // Attach files
});
```

### Streaming Events

Listen to events for real-time updates as the agent responds:

```javascript theme={null}
// Content arrives in chunks for live display
client.on("message:chunk", (data) => {
  updateUI(data.content);  // Append this chunk to the displayed text
});

// Fires when streaming starts
client.on("message:start", (data) => {
  console.log("Response started:", data.messageId);
});

// Fires when the complete message is ready
client.on("message:complete", (message) => {
  displayFinalMessage(message.content, message.sources);
});

// Handle errors
client.on("message:error", (data) => {
  showError(data.error);
});

// Send the message (events fire during processing)
await client.sendMessage("Hello!");
```

***

## Conversations

### List Conversations

```javascript theme={null}
const conversations = await client.getConversations();

conversations.forEach((conv) => {
  console.log(conv.id, conv.title, conv.lastMessageDate);
});
```

### Load a Conversation

```javascript theme={null}
const conversation = await client.getConversation("conversation-uuid");

conversation.messages.forEach((msg) => {
  console.log(`${msg.role}: ${msg.content}`);
});
```

### Get Messages

```javascript theme={null}
const messages = await client.getMessages("conversation-uuid");
```

***

## Feedback

Submit thumbs-up or thumbs-down feedback on agent responses:

```javascript theme={null}
await client.submitFeedback("message-uuid", "positive");
await client.submitFeedback("message-uuid", "negative");
```

***

## Tool Call Interactions

When an agent invokes a tool that requires user input (such as a form or a confirmation), the SDK emits events you can handle:

```javascript theme={null}
// A tool call with a form was received
client.on("toolCall:form", (toolCall) => {
  // Display the form to the user using toolCall.formSchema
  showForm(toolCall.formSchema, async (formData) => {
    await client.submitToolCallForm(toolCall.id, formData);
  });
});

// Any tool call received (forms, confirmations, status messages, etc.)
client.on("toolCall:received", (toolCall) => {
  console.log("Tool call:", toolCall.type, toolCall.toolName);
});
```

### Confirm or Reject a Tool Call

```javascript theme={null}
await client.confirmToolCall("tool-call-uuid");
await client.rejectToolCall("tool-call-uuid");
```

***

## Events Reference

| Event               | Payload                                                     | Description                           |
| ------------------- | ----------------------------------------------------------- | ------------------------------------- |
| `message:start`     | `{ conversationId, messageId }`                             | Streaming response started            |
| `message:chunk`     | `{ content, conversationId, messageId }`                    | A chunk of the response content       |
| `message:complete`  | Full message object                                         | Response is fully received            |
| `message:error`     | `{ error, conversationId?, messageId? }`                    | An error occurred                     |
| `toolCall:received` | Tool call data                                              | Any tool call was received            |
| `toolCall:form`     | Tool call data with form schema                             | A form tool call requires user input  |
| `function:invoke`   | `{ invocationId, functionName, arguments, conversationId }` | A client function is being invoked    |
| `function:result`   | `{ invocationId, result, error? }`                          | A client function execution completed |
| `connection:status` | `{ connected }`                                             | Connection status changed             |

```javascript theme={null}
// Subscribe
client.on("message:complete", handler);

// Unsubscribe
client.off("message:complete", handler);
```

***

## Defining Reusable Functions

Use `defineFunction` to create reusable function definitions that agents can invoke on the client side:

```javascript theme={null}
import { defineFunction } from "@useago/sdk";

export const lookupOrder = defineFunction({
  name: "lookupOrder",
  description: "Look up an order by ID",
  parameters: {
    type: "object",
    properties: { id: { type: "string" } },
    required: ["id"],
  },
  handler: async (args) => fetchOrder(args.id),
});

// Register with the client
client.registerFunction(lookupOrder);
```

In React, use the `useAgoFunction` hook:

```jsx theme={null}
import { useAgoFunction } from "@useago/sdk/react";

useAgoFunction(lookupOrder);
```

See [Client Functions](/features/client-functions) for more details on how agents invoke client-side functions.

***

## Page Context

Give the agent awareness of what the user is currently looking at — the active order, the visible dashboard filter, the open ticket. Context entries are attached to every message and surfaced to the agent as a structured prompt section.

### Vanilla JavaScript

```javascript theme={null}
client.setContext("order-page", {
  name: "Order detail",
  description: "The user is viewing a specific order",
  data: { orderId: "12345", status: "shipped" },
});

// Remove when the view is no longer relevant
client.removeContext("order-page");
```

For context that lives outside your application state (global stores, refs, computed values), register a provider function that runs at each message send so the agent always receives the freshest value:

```javascript theme={null}
client.addDynamicContext("app-shell", () => ({
  name: "App shell",
  data: { userId: currentStore.getState().auth.userId },
}));
```

### React

Use the `useAgoContext` hook to attach context declaratively. It registers when the component mounts and cleans up on unmount:

```jsx theme={null}
import { useAgoContext } from "@useago/sdk/react";

function OrderPage({ order }) {
  useAgoContext({
    name: "Order detail",
    description: "The user is viewing a specific order",
    data: { orderId: order.id, status: order.status },
  });

  return <OrderView order={order} />;
}
```

Pass a function instead of an object for values that aren't captured in React state:

```jsx theme={null}
useAgoContext(() => ({
  name: "App shell",
  data: { userId: storeRef.current.getState().auth.userId },
}));
```

Each entry carries three optional fields:

| Field         | Description                                                              |
| ------------- | ------------------------------------------------------------------------ |
| `name`        | Short label for the context slice (e.g., "Order detail")                 |
| `description` | One-sentence explanation of what this context represents                 |
| `data`        | Arbitrary JSON payload — the structured data the agent should know about |

***

## SSE Streaming Helpers

The SDK provides helper functions for working with streaming responses:

```javascript theme={null}
import {
  onMessage,
  onMessageChunk,
  onMessageStart,
  onMessageError,
  onToolCall,
  createMessageStream,
} from "@useago/sdk";

// Subscribe to complete messages
const unsub = onMessage(client, (message) => {
  console.log("Complete:", message.content);
});

// Subscribe to streaming chunks for real-time display
onMessageChunk(client, ({ content }) => {
  appendToUI(content);
});

// Advanced: async generator for full stream control
for await (const event of createMessageStream(client, "Hello!")) {
  if (event.type === "chunk") {
    console.log(event.data.content);
  }
}
```

| Helper                | Description                             |
| --------------------- | --------------------------------------- |
| `onMessage`           | Subscribe to complete finished messages |
| `onMessageChunk`      | Subscribe to streaming text chunks      |
| `onMessageStart`      | React to message start events           |
| `onMessageError`      | Handle message errors                   |
| `onToolCall`          | React to tool invocations               |
| `onFunctionInvoke`    | React to client function invocations    |
| `createMessageStream` | Async generator for full stream control |

***

## React Components

The SDK provides pre-built React components for common use cases.

### AgoProvider

Provides the AgoClient to your entire React app via context:

```jsx theme={null}
import { AgoProvider } from "@useago/sdk/react";

function App() {
  return (
    <AgoProvider baseUrl="https://YOUR-DOMAIN.useago.com" widgetId="user-123">
      <MyChat />
    </AgoProvider>
  );
}
```

Access the client from any child component:

```jsx theme={null}
import { useAgoClient } from "@useago/sdk/react";

function MyChat() {
  const client = useAgoClient();
  // ...
}
```

| Prop             | Type      | Required | Description                                     |
| ---------------- | --------- | -------- | ----------------------------------------------- |
| `baseUrl`        | string    | Yes      | Your AGO instance URL                           |
| `client`         | AgoClient | No       | Pass a pre-built client instead of creating one |
| `widgetId`       | string    | No       | User identifier (auto-generated if omitted)     |
| `agent`          | string    | No       | Default agent (shorthand for `defaultAgentId`)  |
| `defaultAgentId` | string    | No       | Default agent for new conversations             |
| `permission`     | string    | No       | Permission name to apply to all requests        |
| `userEmail`      | string    | No       | User email for identification                   |
| `userJwt`        | string    | No       | JWT token for authenticated users               |
| `debug`          | boolean   | No       | Enable debug logging                            |

### ChatWidget

A complete, ready-to-use chat interface:

```jsx theme={null}
import { ChatWidget } from "@useago/sdk/react";

<ChatWidget
  client={client}
  title="Support Chat"
  welcomeMessage="Hello! How can I help you?"
  placeholder="Type a message..."
  allowFiles={true}
  height={600}
  onMessageSent={(content) => console.log("Sent:", content)}
  onMessageReceived={(msg) => console.log("Received:", msg.content)}
/>
```

| Prop                | Type             | Default                              | Description                                                            |
| ------------------- | ---------------- | ------------------------------------ | ---------------------------------------------------------------------- |
| `client`            | AgoClient        | Required                             | The SDK client instance                                                |
| `conversationId`    | string           | —                                    | Resume an existing conversation                                        |
| `title`             | string           | `"Chat"`                             | Header title                                                           |
| `welcomeMessage`    | string           | `"Hello! How can I help you today?"` | Empty state text                                                       |
| `placeholder`       | string           | `"Type a message..."`                | Input placeholder                                                      |
| `allowFiles`        | boolean          | `false`                              | Enable file attachments                                                |
| `height`            | string or number | `500`                                | Widget height (px or CSS value)                                        |
| `logoUrl`           | string           | —                                    | Logo shown in the header                                               |
| `showAgentName`     | boolean          | `true`                               | Show the agent name above assistant replies. Set to `false` to hide it |
| `className`         | string           | —                                    | Additional CSS class                                                   |
| `onMessageSent`     | function         | —                                    | Called when the user sends a message                                   |
| `onMessageReceived` | function         | —                                    | Called when an agent response is complete                              |

### Message

Renders a single message with markdown formatting, sources, and follow-up suggestions:

```jsx theme={null}
import { Message } from "@useago/sdk/react";

<Message message={agoMessage} className="my-message" showAgentName={false} />
```

The Message component automatically handles:

* Markdown rendering, including GitHub-flavored markdown: bold, italic, headings, lists, code blocks, links, blockquotes, tables, task lists, and strikethrough
* Agent name display for assistant messages (set `showAgentName={false}` to hide it)
* Knowledge source citations with links
* Follow-up reply buttons
* Streaming indicator while a response is in progress

### Markdown

Renders a raw markdown string the same way `Message` renders assistant content. Use it when you build a fully custom chat UI but still want consistent markdown output:

```jsx theme={null}
import { Markdown } from "@useago/sdk/react";

<Markdown content="**Bold**, a [link](https://useago.com), and a | table |" />
```

## React Hooks

### useAgo

Creates and manages the SDK client lifecycle:

```jsx theme={null}
import { useAgo } from "@useago/sdk/react";

const { client, isReady } = useAgo({
  baseUrl: "https://YOUR-DOMAIN.useago.com",
  widgetId: "unique-user-id",
  defaultAgentId: "agent-uuid",
});
```

The hook handles client creation, cleanup on unmount, and dynamic config updates.

### useMessages

Manages messages within a conversation:

```jsx theme={null}
import { useMessages } from "@useago/sdk/react";

const {
  messages,          // Array of messages
  isLoading,         // True while sending
  error,             // Current error (if any)
  sendMessage,       // (content: string, files?: File[]) => Promise
  clearMessages,     // Reset the conversation
  conversationId,    // Current conversation ID
} = useMessages({ client, conversationId: "optional-uuid" });
```

### useConversation

Manages the conversation list and selection:

```jsx theme={null}
import { useConversation } from "@useago/sdk/react";

const {
  conversations,         // List of conversations
  currentConversation,   // Currently selected conversation
  isLoading,
  error,
  selectConversation,    // (id: string) => Promise
  startNewConversation,  // () => void
  refreshConversations,  // () => Promise
} = useConversation({ client, autoLoad: true });
```

***

## Custom Chat UI Example

Build a fully custom interface using hooks:

```jsx theme={null}
import { useAgo, useMessages, useConversation } from "@useago/sdk/react";
import { Message } from "@useago/sdk/react";

function CustomChat() {
  const { client, isReady } = useAgo({
    baseUrl: "https://YOUR-DOMAIN.useago.com",
    widgetId: "user-123",
  });

  const { messages, sendMessage, isLoading } = useMessages({ client });
  const [input, setInput] = useState("");

  const handleSend = async () => {
    if (!input.trim()) return;
    const content = input;
    setInput("");
    await sendMessage(content);
  };

  return (
    <div>
      <div className="messages">
        {messages.map((msg) => (
          <Message key={msg.id} message={msg} />
        ))}
      </div>
      <input
        value={input}
        onChange={(e) => setInput(e.target.value)}
        onKeyDown={(e) => e.key === "Enter" && handleSend()}
        placeholder="Ask a question..."
      />
      <button onClick={handleSend} disabled={isLoading}>
        Send
      </button>
    </div>
  );
}
```

***

## Cleanup

Always destroy the client when it is no longer needed to free resources:

```javascript theme={null}
client.destroy();
```

In React, the `useAgo` hook handles cleanup automatically on unmount.

***

## Related

* [Client Functions](./client-functions) — SDK API reference
* [Widget Configuration](./widget-configuration-admin) — Widget settings
* [Widget & SDK Authentication](../security/widget-authentication) — Authentication setup
* [Deploy the Chat Widget](../guides/widget-deployment-howto) — Deployment guide
