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

# TypeScript

> Integrate Glass with your TypeScript application

<Note>
  Requires Node.js 18 or higher.
</Note>

## Installation

```bash theme={null}
npm install glass-ai
```

## Quick Start

```typescript theme={null}
import { init, trace, interaction } from 'glass-ai';
import OpenAI from 'openai';

// Initialize Glass
init({ apiKey: 'your-glass-api-key' });

// Your AI calls are now automatically traced
const client = new OpenAI();

const generateResponse = trace(async function generateResponse(prompt: string): Promise<string> {
  const response = await client.chat.completions.create({
    model: 'gpt-4',
    messages: [{ role: 'user', content: prompt }],
  });
  return response.choices[0].message.content!;
});

// Track user interactions
await interaction({ userId: 'user_123', sessionId: 'sess_abc' }, async (ctx) => {
  const result = await generateResponse('What is the meaning of life?');
  ctx.finish({ output: { response: result } });
});
```

That's it. All your OpenAI, Anthropic, and Google Generative AI calls are now traced automatically.

***

## API Reference

### `init()`

Initializes the Glass SDK. Call this once at application startup.

```typescript theme={null}
import { init } from 'glass-ai';

// Basic initialization
init({ apiKey: 'your-api-key' });

// With debug mode (logs traces to console)
init({ apiKey: 'your-api-key', debug: true });
```

<ParamField path="apiKey" type="string">
  Your Glass API key. Falls back to `GLASS_API_KEY` environment variable if not provided.
</ParamField>

<ParamField path="debug" type="boolean" default="false">
  Enable console output for local development.
</ParamField>

<ParamField path="skipDefaultInstrumentations" type="boolean" default="false">
  Disable automatic tracing of AI providers. See [Instrumentations](/sdk/instrumentations) for details.
</ParamField>

<ParamField path="instrumentations" type="array">
  Custom OpenTelemetry instrumentors. See [Instrumentations](/sdk/instrumentations) for details.
</ParamField>

***

### `trace()`

Wraps any function with tracing. Automatically records arguments, return values, and exceptions.

```typescript theme={null}
import { trace } from 'glass-ai';

// Basic usage
const processData = trace(function processData(data: object): object {
  return { processed: true, ...data };
});

// Custom span name
const myFunction = trace({ name: 'custom-operation' }, function myFunction() {
  // ...
});

// With attributes
const createEmbedding = trace(
  { attributes: { model: 'text-embedding-3-small' } },
  function createEmbedding(text: string): number[] {
    return [0.1, 0.2, 0.3];
  }
);
```

Works with async functions too:

```typescript theme={null}
const asyncProcess = trace(async function asyncProcess(data: string): Promise<string> {
  await someAsyncOperation();
  return `processed: ${data}`;
});
```

<ParamField path="name" type="string">
  Custom span name. Defaults to the function name.
</ParamField>

<ParamField path="attributes" type="object">
  Additional attributes to attach to the span.
</ParamField>

***

### `interaction()`

Tracks a user interaction. Propagates user context to all nested traces.

```typescript theme={null}
import { interaction, trace } from 'glass-ai';

const callLlm = trace(async function callLlm(prompt: string): Promise<string> {
  return 'LLM response';
});

await interaction(
  { userId: 'user_123', sessionId: 'sess_abc', project: 'conversational-chat', input: 'Hello!' },
  async (ctx) => {
    const result = await callLlm('Hello!');
    ctx.finish({ output: { response: result } });
  }
);
```

<ParamField path="userId" type="string">
  Identifier for the user.
</ParamField>

<ParamField path="sessionId" type="string">
  Session identifier.
</ParamField>

<ParamField path="project" type="string">
  In which project to classify traces.
</ParamField>

<ParamField path="input" type="string">
  The user's input/query.
</ParamField>

<ParamField path="service" type="string">
  Service name for routing.
</ParamField>

**Methods on the context:**

| Method                       | Description                                |
| ---------------------------- | ------------------------------------------ |
| `finish(output)`             | Record the final output of the interaction |
| `setAttribute(key, value)`   | Set a custom attribute                     |
| `recordException(exception)` | Record an exception                        |

***

### `taskSpan()`

Creates a task span with explicit input/output recording.

```typescript theme={null}
import { taskSpan } from 'glass-ai';

await taskSpan('embedding-task', { attributes: { model: 'ada-002' } }, async (task) => {
  task.recordInput({ text: 'Hello, world!' });
  const embedding = await computeEmbedding('Hello, world!');
  task.recordOutput({ embedding, dimensions: 1536 });
});
```

<ParamField path="name" type="string" required>
  The name of the task span.
</ParamField>

<ParamField path="attributes" type="object">
  Additional attributes for the span.
</ParamField>

**Methods on the task:**

| Method                       | Description            |
| ---------------------------- | ---------------------- |
| `recordInput(data)`          | Record input data      |
| `recordOutput(data)`         | Record output data     |
| `setAttribute(key, value)`   | Set a custom attribute |
| `recordException(exception)` | Record an exception    |

***

## Full Example: RAG Pipeline

Here's how the primitives compose together:

```typescript theme={null}
import { init, trace, interaction, taskSpan } from 'glass-ai';
import OpenAI from 'openai';

init({ apiKey: 'your-api-key' });
const client = new OpenAI();

const retrieveContext = trace(async function retrieveContext(query: string): Promise<string[]> {
  return ['context 1', 'context 2'];
});

const generateResponse = trace(async function generateResponse(
  query: string,
  context: string[]
): Promise<string> {
  const response = await client.chat.completions.create({
    model: 'gpt-4',
    messages: [
      { role: 'system', content: `Context: ${context}` },
      { role: 'user', content: query },
    ],
  });
  return response.choices[0].message.content!;
});

const ragQuery = trace({ name: 'rag-pipeline' }, async function ragQuery(query: string): Promise<string> {
  let context: string[] = [];

  await taskSpan('retrieval', {}, async (task) => {
    task.recordInput({ query });
    context = await retrieveContext(query);
    task.recordOutput({ numDocs: context.length });
  });

  return generateResponse(query, context);
});

// Track the full user interaction
await interaction({ userId: 'user_123', input: 'What is quantum computing?' }, async (ctx) => {
  const result = await ragQuery('What is quantum computing?');
  ctx.finish({ output: { answer: result } });
});
```

This creates a trace hierarchy like:

```
interaction (userId=user_123)
└── rag-pipeline
    ├── retrieval (taskSpan)
    │   └── retrieveContext
    └── generateResponse
        └── OpenAI chat.completions.create (auto)
```

***

## Environment Variables

| Variable        | Description                                         |
| --------------- | --------------------------------------------------- |
| `GLASS_API_KEY` | Your Glass API key (alternative to passing in code) |

```bash theme={null}
export GLASS_API_KEY="your-api-key"
```

```typescript theme={null}
import { init } from 'glass-ai';

// API key is read from environment
init({});
```
