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

# Narrative Agent

Generate a chart's title, subtitle, and caption with natural language. Send a `GraphConfig` and a prompt, receive a `GraphConfig` with narrative text written into `config.content`.

## Methods

### generateNarrative

Processes the request and returns the final result. Internally handles streaming and collects the response.

```typescript theme={null}
async generateNarrative(
  params: GenerateNarrativeParams,
  onProgress?: (event: ProgressEvent) => void,
  signal?: AbortSignal
): Promise<GenerateNarrativeResponse>
```

### generateNarrativeStream

Returns an async iterator that yields events as they arrive.

```typescript theme={null}
async generateNarrativeStream(
  params: GenerateNarrativeParams,
  signal?: AbortSignal
): Promise<AsyncIterableIterator<SSEEvent<GenerateNarrativeResponse>>>
```

## Parameters

```typescript theme={null}
interface GenerateNarrativeParams {
  config: GraphConfig;
  userPrompt: string;
  metadata?: Metadata;
}
```

| Field | Type | Required | Description |
| - | - | - | - |
| `config` | `GraphConfig` | Yes | The chart configuration to narrate |
| `userPrompt` | `string` | Yes | Natural language instruction for the narrative — tone, focus, or refinements |
| `metadata` | `Metadata` | No | Request tracking information |

## Response

```typescript theme={null}
interface GenerateNarrativeResponse {
  response: {
    message: string;
  };
  config: GraphConfig;
}
```

| Field | Type | Description |
| - | - | - |
| `response.message` | `string` | Explanation of the narrative produced |
| `config` | `GraphConfig` | Updated chart configuration. Title, subtitle, and caption are written into `config.content` as TipTap JSON documents. |

The response is validated with Zod. Invalid responses throw an error.

Which fields are written — title only, title and caption, or all three — depends on the storytelling level. See [Invocation effort and chart narrative](/agents/sdk/chart-maker#invocation-effort-and-chart-narrative) for how `metadata.effort` controls this.

***

## Basic Usage

```typescript theme={null}
import { GraphyAiSdk } from '@graphysdk/agents-sdk';
import type { GraphConfig } from '@graphysdk/agents-sdk';

const ai = new GraphyAiSdk({
  apiKey: process.env.GRAPHY_API_KEY,
  baseUrl: 'https://agents.graphy.dev',
});

const config: GraphConfig = {
  type: 'line',
  data: {
    columns: [
      { key: 'month', label: 'Month' },
      { key: 'users', label: 'Active Users' },
    ],
    rows: [
      { month: 'Jan', users: 1200 },
      { month: 'Feb', users: 1800 },
      { month: 'Mar', users: 3100 },
    ],
  },
};

const result = await ai.generateNarrative({
  config,
  userPrompt: 'Write a punchy title and a one-line caption',
});

// Narrative is embedded in the config content as TipTap JSON
console.log(result.config.content?.title);
console.log(result.config.content?.caption);
```

***

## With Progress Callback

Use the `onProgress` callback to show real-time progress without full streaming:

```typescript theme={null}
const result = await ai.generateNarrative(
  {
    config,
    userPrompt: 'Make the title more specific and lead with the headline number',
  },
  (progress) => {
    console.log(progress.message);
  }
);
```

***

## Streaming

For full control over the event stream:

```typescript theme={null}
import { isProgressEvent, isCompleteEvent, isErrorEvent } from '@graphysdk/agents-sdk';

const stream = await ai.generateNarrativeStream({
  config,
  userPrompt: 'Write a title, subtitle, and caption',
});

for await (const event of stream) {
  if (isProgressEvent(event)) {
    console.log(event.message);
  }

  if (isCompleteEvent(event)) {
    console.log('Result:', event.data.config);
  }

  if (isErrorEvent(event)) {
    console.error('Error:', event.error);
  }
}
```

See [Streaming](/agents/sdk/streaming) for cancellation and React patterns.

***

## Error Handling

```typescript theme={null}
import { isGraphyApiError } from '@graphysdk/agents-sdk';

try {
  const result = await ai.generateNarrative({
    config,
    userPrompt: 'Write a title for this chart',
  });
} catch (error) {
  if (isGraphyApiError(error)) {
    console.error('API error:', error.message);
  }
}
```

See [Error Handling](/agents/sdk/errors) for retry behavior and error types.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.