# Streaming

Replies in Chats and in chatbots appear word by word while the model writes
them. SleekAI finds out by itself whether your server can deliver them that
way, and falls back to polling where it cannot. Nothing needs configuring.

## How SleekAI decides

Before the first reply, the browser opens a short test stream from the
server. If it arrives intact, replies are streamed as server-sent events; if
it does not, as on some shared hosting and behind buffering proxies, replies
are polled. The browser reports the result to the server, which keeps it.
Chatbot widgets on your pages use the stored result once there is one instead
of testing again, and the server answers every reply the same way.

## Polling

When replies are polled, the server writes each reply to a temporary file
under `uploads/sleek-ai/completions` while the model writes it, and the
browser reads that file several times a second until the reply is complete.
Each file is served only to the browser that asked for the reply, and only
for ten minutes after its last change. An hourly WordPress cron event
deletes older ones, and `wp sleek ai cleanup completions` does the same on
demand.

Both ways show the same reply; polling only adds a little delay.

## Choosing the method yourself

The `sleekAi/polling` filter overrides the stored result: return `true` to
always poll or `false` to always stream. The server applies it when it
answers, and chatbot widgets receive it with the page.

```php
add_filter('sleekAi/polling', '__return_true');
```

`sleekAi_use_polling()` returns the filtered value; see the
[Developer API](/docs/ai/api.md) and the [hooks reference](/docs/ai/reference/hooks.md).

## Troubleshooting

**A reply never arrives or stops early.** A proxy or cache in front of the
site may hold back streamed responses. Exclude the site's REST API
(`/wp-json/`) from buffering and caching, or force polling with the filter
above.

**A request is rejected with "Invalid JSON data" or "Invalid messages."** The
conversation did not reach the server intact, usually because a proxy or
security plugin rewrote the request body.
