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

# Vision Language Models

> Ask a model about an image

```ts theme={null}
const result = await RunAnywhere.vlm.generate(
  RunAnywhere.image.bytes(data),
  'What is in this screenshot?'
)

console.log(result.text)
```

## Signatures

```ts theme={null}
generate(image: ImageInput, prompt: string, options?: LlmOptions): Promise<GenerationResult>
generateStream(image: ImageInput, prompt: string, options?: LlmOptions): AsyncIterableIterator<GenerationEvent>
```

## Building an ImageInput

Input constructors hang off the facade as `RunAnywhere.image`, so renderer code builds the same
values main-process code does:

```ts theme={null}
RunAnywhere.image.file(path)
RunAnywhere.image.bytes(data)
RunAnywhere.image.rawRgb(data, width, height)
```

## From a file the user picked

```ts theme={null}
import { dialog } from 'electron'

const { filePaths } = await dialog.showOpenDialog({
  filters: [{ name: 'Images', extensions: ['png', 'jpg', 'jpeg'] }],
})

if (filePaths[0]) {
  const result = await RunAnywhere.vlm.generate(
    RunAnywhere.image.file(filePaths[0]),
    'Describe this image in one sentence.'
  )
}
```

Passing the path rather than the bytes avoids reading a large image into JavaScript memory only
to hand it straight back to native code.

## From a screenshot

Desktop is the one platform where screen capture is a normal thing to do:

```ts theme={null}
import { desktopCapturer } from 'electron'

const sources = await desktopCapturer.getSources({
  types: ['window'],
  thumbnailSize: { width: 1280, height: 720 },
})

const image = RunAnywhere.image.bytes(sources[0].thumbnail.toPNG())
const result = await RunAnywhere.vlm.generate(image, 'What is this window showing?')
```

This pairs with the computer-use scaffold: a model reads a screenshot and decides what to do
next.

## Streaming

```ts theme={null}
for await (const event of RunAnywhere.vlm.generateStream(image, 'Describe this in detail.')) {
  if (event.type === 'textDelta') caption += event.text
}
```

## Options

`vlm` takes the same `LlmOptions` as `llm`, so `maxOutputTokens`, `temperature`, and
`systemPrompt` all apply.

## Models

VLM runs on the llama.cpp backend, so the model must be a GGUF vision model with its projector.
Install `@runanywhere/electron-llamacpp`.

On `win32-arm64` llama.cpp does not load at all, so vision is unavailable there. Check
`capabilities()` before putting it in the interface.
