> ## 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.

# Extract Agent

Build a chart-ready dataset from unstructured sources. Send raw text, images, PDFs, or Excel spreadsheets, receive a `GraphConfig` with the extracted data.

## Methods

### extractFromProse

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

```typescript theme={null}
async extractFromProse(
  params: ExtractFromProseParams,
  onProgress?: (event: ProgressEvent) => void,
  signal?: AbortSignal
): Promise<ExtractFromProseResponse>
```

### extractFromProseStream

Returns an async iterator that yields events as they arrive.

```typescript theme={null}
async extractFromProseStream(
  params: ExtractFromProseParams,
  signal?: AbortSignal
): Promise<AsyncIterableIterator<SSEEvent<ExtractFromProseResponse>>>
```

## Parameters

```typescript theme={null}
interface ExtractFromProseParams {
  sourceText?: string;
  attachments?: ExtractAttachmentInput[];
  images?: ExtractImageInput[];
  metadata?: Metadata;
}
```

| Field         | Type                       | Required | Description                                                                          |
| ------------- | -------------------------- | -------- | ------------------------------------------------------------------------------------ |
| `sourceText`  | `string`                   | No       | Raw text to extract data from. Up to 500,000 characters.                             |
| `attachments` | `ExtractAttachmentInput[]` | No       | Images, PDFs, and spreadsheets to extract data from. Up to 12 entries.               |
| `images`      | `ExtractImageInput[]`      | No       | **Deprecated.** Legacy image array — use `attachments` with `kind: 'image'` instead. |
| `metadata`    | `Metadata`                 | No       | Request tracking information                                                         |

<Note>
  Provide `sourceText`, `attachments`, or both — at least one is required. `images` and `attachments` cannot be combined in a single request.
</Note>

## Attachments

`attachments` is a discriminated union tagged by `kind`. Use the builder helpers to construct entries — each accepts base64-encoded file data and returns a correctly-tagged attachment.

```typescript theme={null}
import {
  buildImageAttachment,
  buildPdfAttachment,
  buildSpreadsheetAttachment,
} from '@graphysdk/agents-sdk';

function buildImageAttachment(input: { mimeType: string; dataBase64: string }): ExtractAttachmentInput;
function buildPdfAttachment(input: { dataBase64: string }): ExtractAttachmentInput;
function buildSpreadsheetAttachment(input: { dataBase64: string; filename?: string }): ExtractAttachmentInput;
```

### ExtractAttachmentInput

```typescript theme={null}
type ExtractAttachmentInput =
  | { kind: 'image'; mimeType: string; dataBase64: string }
  | { kind: 'document'; mimeType: string; dataBase64: string }
  | { kind: 'spreadsheet'; mimeType: string; dataBase64: string; filename?: string };
```

| `kind`          | Accepted formats     | Builder                      |
| --------------- | -------------------- | ---------------------------- |
| `'image'`       | PNG, JPEG, WebP, GIF | `buildImageAttachment`       |
| `'document'`    | PDF                  | `buildPdfAttachment`         |
| `'spreadsheet'` | Excel `.xlsx`        | `buildSpreadsheetAttachment` |

`dataBase64` must be RFC 4648 standard base64. The builders set `mimeType` for you (`buildImageAttachment` takes it as input since images have several valid types).

### Size limits

| Attachment   | Max count | Max size each | Max size combined |
| ------------ | --------- | ------------- | ----------------- |
| Images       | 8         | 2 MB          | 7 MB              |
| PDFs         | 2         | 6 MB          | 8 MB              |
| Spreadsheets | 2         | 6 MB          | 8 MB              |

Across all kinds, a request accepts up to **12 attachments** and **12 MB** combined. Limits are measured on the decoded bytes, not the base64 string.

## Response

```typescript theme={null}
interface ExtractFromProseResponse {
  response: {
    message: string;
  };
  config: GraphConfig;
  extractMeta: ExtractMeta | null;
  lastAccuracyEvaluation?: ExtractAccuracyEvaluation;
}
```

| Field                    | Type                        | Description                                                        |
| ------------------------ | --------------------------- | ------------------------------------------------------------------ |
| `response.message`       | `string`                    | Summary of what was extracted                                      |
| `config`                 | `GraphConfig`               | Chart configuration containing the extracted dataset               |
| `extractMeta`            | `ExtractMeta \| null`       | Trust metadata for the extraction, or `null` when unavailable      |
| `lastAccuracyEvaluation` | `ExtractAccuracyEvaluation` | The agent's final self-check of the extracted data, when performed |

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

### ExtractMeta

```typescript theme={null}
interface ExtractMeta {
  confidence: ExtractConfidence;
  needsUserInput: boolean;
  warnings: string[];
  cellConfidence?: Array<{
    rowIndex: number;
    columnKey: string;
    confidence: ExtractConfidence;
    quote?: string;
  }>;
}

type ExtractConfidence = 'high' | 'medium' | 'low';
```

| Field            | Type                | Description                                                       |
| ---------------- | ------------------- | ----------------------------------------------------------------- |
| `confidence`     | `ExtractConfidence` | Overall confidence in the extraction                              |
| `needsUserInput` | `boolean`           | Whether the result should be reviewed before use                  |
| `warnings`       | `string[]`          | Notes about ambiguous, conflicting, or missing source data        |
| `cellConfidence` | `Array<…>`          | Optional per-cell confidence, each with a supporting source quote |

### ExtractAccuracyEvaluation

```typescript theme={null}
interface ExtractAccuracyEvaluation {
  score: number;
  issues: string[];
  sufficient: boolean;
  summary: string;
}
```

| Field        | Type       | Description                                      |
| ------------ | ---------- | ------------------------------------------------ |
| `score`      | `number`   | Accuracy score, from `0` to `1`                  |
| `issues`     | `string[]` | Specific accuracy problems the agent identified  |
| `sufficient` | `boolean`  | Whether the accuracy is good enough to use as-is |
| `summary`    | `string`   | Human-readable summary of the accuracy check     |

***

## Basic Usage

Extract from plain text:

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

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

const result = await ai.extractFromProse({
  sourceText: `
    In Q3, the Direct channel brought in $1.9M, Partner $0.4M,
    and Marketplace $1.1M.
  `,
});

console.log(result.config.data); // Extracted dataset
console.log(result.extractMeta?.confidence); // 'high' | 'medium' | 'low'
```

***

## Extracting from Files

Read a file, base64-encode it, and wrap it with the matching builder:

```typescript theme={null}
import {
  GraphyAiSdk,
  buildImageAttachment,
  buildPdfAttachment,
  buildSpreadsheetAttachment,
} from '@graphysdk/agents-sdk';
import { readFile } from 'node:fs/promises';

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

// From a screenshot of a table
const png = await readFile('./table.png');
const fromImage = await ai.extractFromProse({
  attachments: [buildImageAttachment({ mimeType: 'image/png', dataBase64: png.toString('base64') })],
});

// From a PDF report
const pdf = await readFile('./q3-report.pdf');
const fromPdf = await ai.extractFromProse({
  attachments: [buildPdfAttachment({ dataBase64: pdf.toString('base64') })],
});

// From an Excel spreadsheet
const xlsx = await readFile('./q3-report.xlsx');
const fromSpreadsheet = await ai.extractFromProse({
  attachments: [buildSpreadsheetAttachment({ dataBase64: xlsx.toString('base64'), filename: 'q3-report.xlsx' })],
});
```

You can combine `sourceText` and multiple `attachments` in one request — the agent reconciles all sources into a single dataset.

***

## With Progress Callback

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

```typescript theme={null}
const result = await ai.extractFromProse(
  {
    sourceText: longReport,
  },
  (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.extractFromProseStream({
  sourceText: longReport,
});

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.extractFromProse({ sourceText });
} catch (error) {
  if (isGraphyApiError(error)) {
    console.error('API error:', error.message);
  }
}
```

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