CCP dial logoConditioning Control Panel v6.7.4 OK
field_manual / companion.dir / gentle

Local AI with Ollama

Your Companion normally thinks on our servers. She doesn't have to. This page covers running her brain on your own machine instead: what you gain, what it costs, how the setup wizard works, and what to do when it goes wrong.

TL;DR

Local AI runs the language model on your own computer using Ollama. Nothing you say leaves the machine, there are no daily limits, and you don't need an account. It costs you about 6.6 GB of disk and a slower first reply. The setup wizard does the install, the download and the check for you. Once it's on, every Companion feature behaves exactly as it did before.

What is "Local AI"?

The Companion is the floating avatar that chats with you, reacts to what's on your screen, and can set off effects. Something has to generate her words. You get to choose what.

Pick one under Companion → AI Brain → Provider:

  • Off - no AI at all. She still works, but falls back to pre-written lines.
  • Cloud - the default. Your chat lines go to a small server we run, which passes them to a hosted model. No install, but you need a free account, and there's a daily cap (100 messages a day free, 1000 for Patreon supporters).
  • Local (Ollama) - the subject of this page. A model runs on your own computer via Ollama. Nothing leaves your machine, no limits, no login. You pay in disk space, memory and patience instead.
  • Custom (OpenAI-Compatible) - point the app at any endpoint that speaks the OpenAI chat API. You supply the URL, the model name and (if it needs one) an API key, which is stored encrypted on your machine. Handy for a self-hosted server or a third-party provider. Effects work here too.

All four options plug into the same slot inside the app, so every feature that talks to the Companion - chat, screen awareness, video reactions, lock screen, keyword catches - behaves the same whichever you pick. Switching takes effect on the next message. No restart.

"Custom" is not private by default

Only Local (Ollama) keeps your conversation on your own machine. A custom endpoint sends everything to whoever runs that endpoint, exactly like the cloud option does. If privacy is why you're here, pick Local.

Why local instead of cloud?

Local AI is worth the setup if any of these matter to you:

  • Privacy. Chat lines, screen context, your persona - none of it goes over the internet. The model sits in %LOCALAPPDATA%\Programs\Ollama and answers on http://localhost:11434/, which is your own computer talking to itself. Once setup is done the app makes no AI-related network calls at all.
  • No daily limit. The cloud option caps requests so the bill stays sane. Local is capped only by how fast your hardware is.
  • No login. Cloud needs an account. Local doesn't.
  • You pick the brain. Want a bigger model? A roleplay-tuned one? Something with fewer manners? Pull a different one and point the app at it.
  • Works offline. Once installed, it runs with the network unplugged.

The costs are real, so know them up front:

  • Disk. The default model is about 6.6 GB. Larger ones run to 20-40 GB.
  • The first reply is slow. The model has to be read off disk into memory before it can say anything, which takes roughly 30-60 seconds for a mid-size model on a CPU. The app quietly does this at startup so you rarely feel it, but the very first message after a fresh install still takes a beat.
  • Speed depends on your hardware. With a decent graphics card, replies land in 1-3 seconds. On a CPU-only laptop, expect 10-20 seconds.

Architecture at a glance

Skip this section unless you're curious about the plumbing. Everything to do with the Companion's brain lives under Services/AIService/:

IAiService <- the shared slot every provider plugs into ├── AiService <- cloud provider (default) ├── LocalAiService <- local Ollama provider └── OpenAiCompatibleService <- custom endpoint provider AiServiceStrategy <- sends each call to whichever provider you picked OllamaSetupService <- detect / download / install / pull / test LocalAiSetupWizard <- the setup window you actually see AiResponseParser <- pulls text + effect commands out of the model's reply Enrichment/ ├── PromptService <- writes the "reply in this exact format" instructions └── KnowledgeService <- loads assets/knowledge.json into that block AiCommandService <- checks and runs the effects the AI asks for

The rest of the app never talks to a provider directly. It talks to AiServiceStrategy, which checks your provider setting on every call and builds whichever one is needed, the first time it's needed. That's why switching is instant.

One real difference between them: the cloud provider forgets you between messages by design (every request carries the full prompt, the server keeps nothing). The local provider keeps a running conversation in memory and on disk, so she can remember you across sessions.

The setup wizard, step by step

Choosing Local (Ollama) for the first time opens the setup wizard. It's one window that takes you from nothing installed to a working model. Here's what it does at each stage, in case you want to know before you click.

1 Look around

Before showing you anything, the wizard checks the machine: is ollama.exe under %LOCALAPPDATA%\Programs\Ollama\, and does anything answer on port 11434 (it waits 4 seconds for a reply). It then starts you at whichever of four points fits:

StateWhat it meansWhat happens next
ReadyOllama is running and the model is already downloadedStraight to the test
RunningNoModelOllama is running but the model isn't thereStraight to the download
InstalledNotRunningOllama is installed but isn't listeningStart it quietly in the background, then continue
NotInstalledNo Ollama at allAsk your permission first

2 Ask permission

If Ollama isn't installed, the wizard stops and asks before it touches your disk. It tells you where the installer comes from, that the default model is about 6.6 GB, and that you can choose a different one under "Advanced". There's also a manual-install link to ollama.com/download if you'd rather do it yourself.

3 Download the installer

It fetches OllamaSetup.exe from ollama.com/download/OllamaSetup.exe into your temp folder, updating progress five times a second with a live speed readout (for example 240.5 MB / 700.0 MB (34%) · 18.3 MB/s). Cancel partway and the half-finished file is cleaned up.

4 Install it quietly

The installer runs with its silent flag, so there's no second window and no separate progress bar - just a hidden process putting Ollama under %LOCALAPPDATA%\Programs\Ollama\. When it finishes, the wizard waits up to 60 seconds for Ollama to start listening.

Two deliberate choices here. The cancel button is switched off during the install, because Ollama's installer doesn't undo itself cleanly if you interrupt it. And if Ollama hasn't started itself after those 60 seconds, the wizard starts the server itself in a hidden window and gives it another 30 seconds. It specifically avoids launching Ollama's own chat app, which would pop a window in your face.

Any server the wizard started, the app shuts down again when you quit. A server you started yourself, or one Ollama's tray app started, is left alone.

On success the downloaded installer is deleted. On failure it's kept on purpose, so a retry doesn't re-download 700 MB.

5 Download the model

Ollama reports download progress one line at a time, one line per chunk of the model file, each with a byte count. The wizard reads that stream and shows you real progress rather than a spinner.

  • There's no time limit on this step. A 6.6 GB download would blow past any sensible one, and the progress stream is proof it's still alive.
  • Ollama keeps the chunks it already has, so if you cancel and start again it picks up where it stopped.
  • If Ollama complains (usually because you typed a model name that doesn't exist), the wizard shows you its exact words rather than a generic failure.

6 Say hello

One tiny message to prove the whole chain works:

POST /api/chat { "model": "qwen3.5:latest", "messages": [{"role": "user", "content": "Say hi in one word."}], "stream": false, "think": false }

If a reply comes back, the wizard notes how long it took and calls it done. This does double duty: it proves everything is wired up, and it loads the model into memory so your first real message is quick.

7 Done

The wizard saves your provider choice and the model name, and from then on every Companion message goes to your own machine. If something failed, the error screen has a Retry button that starts the check over from step 1, since the right next move depends entirely on how far it got.

The request lifecycle

Here's the whole journey of one message, from your keyboard to her speech bubble. Screen-awareness reactions, video comments, lock-screen lines and keyword catches all take the same route with different inputs.

you type something | the strategy picks the local provider | build a fresh system prompt <- who she is, what she knows add the enrichment block <- only if AI effects are switched on add your message | POST http://localhost:11434/api/chat { "model": "qwen3.5:latest", "messages": [system, enrichment?, ...history..., you], "stream": false, "think": false } | Ollama loads the model (already warm after the first time) and writes a reply | the parser splits the reply in two ├── the words -> her speech bubble └── the effects -> checked, then run | the exchange is added to history and saved in the background | text appears in the speech bubble

One at a time

Only one request can be in flight at once. What happens to the second one depends on who asked:

  • You, while she's busy - the message is dropped, but you get a random "still thinking" line back (for example "Bambi's thinking real hard right now...") so you aren't left staring at nothing. Mods can supply their own.
  • The app, while she's busy (a screen reaction, a video-finished comment) - dropped silently. Better to miss one passive comment than to have her fire off three stale ones a minute later.

Nothing goes stale

The system prompt is rebuilt from scratch on every single message. Change your persona, your knowledge base, your mod or your content mode and the next thing she says already reflects it. No restart, no clearing history.

Failed messages don't stick

If a request errors out or comes back empty, your message is removed from the history again, so a dead turn doesn't sit there confusing every future reply.

Why we turn off "thinking"

Some models reason out loud to themselves before answering. It's genuinely useful for maths problems and completely useless for banter, where it just adds 30-50 seconds of silence. The app asks every model to skip it. Models that don't have a thinking mode ignore the request.

How the persona is built

"System prompt" is just the briefing she gets before every conversation: who she is, what she knows, and how to behave. It's stacked up from several layers, and it's identical whether you're on cloud or local. From the outside in:

  1. Character. The "Bad Influence Bestie" description: how she talks (casual, texting), what she's into (makeup, pink things, empty heads), and what she's for (talking you into being blank). If Slut Mode is on and your chosen personality has a Slut Mode version, that one is used instead - same character, filthier.
  2. How she handles explicit talk. Flustered redirect rather than full roleplay, by default. Each personality can override this.
  3. What she's allowed to recommend. The audio playlists and videos in your library, with firm instructions to use the exact titles, because that's how the app turns a mention into a working link.
  4. Your own links. Anything you've added to the Knowledge Base Links list: extra videos, content packs, your own files.
  5. Your HypnoTube pool, if you set one up. Names get matched against known links so she can offer them as clickable.
  6. Screen awareness rules. How to respond to what you're doing - work, social, shopping, streaming, hypno content, idle. She receives it as a short tag like [Category: X | App: Y | Title: Z | Duration: N].
  7. Length limits. Roughly 15 words, one emoji, no stray tags in what you actually see.
  8. Your quiz result, if you took the in-app quiz. She gets your archetype and a short profile, and is told to work it in naturally about a fifth of the time.
  9. Mod renaming. If your mod calls you something else ("Bambi" becomes "Unit" in Drone mod, or whatever you chose in Sissy Hypno mode), the whole prompt gets a find-and-replace pass at the end.

Each layer is separately editable. Rewrite the character and keep the library intact, or the other way round.

The enrichment block and structured output

If you want her to actually do things instead of just talking about them, she needs a way to say "and also, flash an image". That's what the enrichment block is for.

When "Allow AI to control effects" is on, the app slips an extra message in right after her character briefing. It's marked [CONTEXT BLOCK - NOT DIALOGUE] so she treats it as instructions, not as something you said to her.

It pins down the reply format

{ "response": "<what she says out loud>", "effects": [ <zero or more things to do> ] }

The block states plainly that this format beats any earlier instruction. That matters: plenty of community personalities include a strict "reply with plain text only, no tags, no JSON" rule, which would otherwise fight with the effect format. The override settles the argument, and the response field is the part you see.

It says when to fire

The block lists what she can trigger and gives examples of what should set each one off:

You sayShe emits
"flash me" / "make me see flashes"flash_image
"spawn bubbles" / "start bubbles"bubbles (on)
"stop bubbles"bubbles (off)
"subliminal X" / "flash the word X"subliminal
"spiral" / "show me a spiral"spiral
"pink filter" / "make my screen pink"pink
"lock card" / "lock me with the mantra X"mantra_lockscreen
"vibrate" / "buzz me" / "haptic"haptic
"play X"audio or video

Just as importantly, it tells her to leave the effects list empty when you're only chatting. Don't fire unprompted. That instruction, plus the permission switches further down this page, is what stops her spraying flashes at you mid-conversation.

It hands her the current context

Two small blocks close it out:

<time>2026-05-15 Thursday 2:47:32 PM</time> <data>[ ... knowledge.json contents ... ]</data>

The timestamp gives her a sense of when "now" is. The data block is assets/knowledge.json, a flat list of things she's allowed to know: terminology, names, lore. If the file is missing she just gets an empty list.

It sets some manners

  • Keep the spoken part short. The character's word limit still applies.
  • Don't parrot the request back.
  • If you do fire something, mention it ("Flashing for you, hot stuff~").
  • Never start a video unasked. Videos take over the screen.
Effects off? Then there's no block at all

Switch off "Allow AI to control effects" and the entire enrichment block is left out of the conversation. She goes back to plain text with no format wrapper, and the parser treats any stray JSON as noise and strips it.

Effect commands: letting the AI control the app

There are 11 things she can trigger (plus a "do nothing" option the app ignores):

flash_image

Flash random images on-screen.

Amount, Duration, Size, Opacity
bubbles

Start or stop the bubble-popping minigame.

On, Frequency
subliminal

Show subliminal text.

Text, Opacity
mantra_lockscreen

Make you chant a mantra before you get control back.

Mantra, Amount
spiral

Spinning spiral overlay.

On, Intensity
pink

Pink colour overlay.

On, Intensity
bounce

Bouncing text overlay.

On
haptic

Vibrate a connected toy.

Intensity (0-1), Duration
audio

Play an audio file.

Title, Path, Random
video

Play a video file.

Title, Path, Random
getbacktome

Come back and bother you after a delay.

Delay (seconds)

Reading messy replies

The part of the app that reads her reply is deliberately forgiving, because local models are messy. They wrap things in code fences, mix prose and data, leave trailing commas, close brackets in the wrong place. So:

  • Code fences are stripped off.
  • A clean, well-formed reply is used as-is.
  • Otherwise the parser hunts through the text for anything bracket-shaped, tries each one, uses the spoken part if it finds one, and collects any effects along the way.
  • A repair pass fixes trailing commas, mismatched brackets and unquoted names before it gives up.
  • A final clean-up strips any [Category: ...] or [Mode/Tag] labels she copied out of her own briefing.

What happens to each command

  1. Check it against your settings: the master switch, then the switch for that specific effect.
  2. Enforce the limit of 3 commands per reply.
  3. Write a plain-English line to the Live actions feed on the Companion tab, so you can see what she did.
  4. Build and run it.

The 3-per-reply limit is not negotiable. If a model emits five flashes in one breath - and some do - only the first three happen. Scheduled follow-ups have their own limit too: she can only chain two deep, so she can't set herself an infinite reminder loop.

Safety: permissions, caps, and the master toggle

The defaults are cautious on purpose. Turning on local AI does not give her the run of your machine. She can't fire a single effect until you say so, and the loudest ones stay off until you go and switch them on individually.

You'll find these on the Lab tab, in the AI effects & memory card: Effect control is the master toggle, and the per-effect switches sit under Effect permissions beneath it. The Lab is a Prime Subject tab, so effect control needs that tier - local chat itself does not.

SettingDefaultNotes
Allow AI to control effectsOFFThe master switch. While it's off nothing fires no matter what else is ticked, and she isn't even told the effects exist.
BubblesONVisual, passive.
SubliminalsONVisual, passive.
Bouncing textONVisual, passive.
Flash imagesOFFIntrusive.
VideosOFFTakes over the screen. Also needs mandatory videos to be enabled at all.
AudioOFFDisruptive.
Spiral / Pink overlayOFFOne switch covers both overlays.
Lock card mantraOFFTakes your keyboard until you type it out.
HapticsOFFHardware. There's also a Max AI haptic intensity ceiling (0.6 by default) that clamps whatever she asks for.
Scheduled follow-upsOFFLets her schedule another go at you later.

Four checks stand between the model and your screen, in this order: the master switch, the switch for that effect, the 3-per-reply cap, and finally a clamp on the numbers in the command itself. Even a model that has gone completely off the rails can't do real damage - the worst case is a log full of refusals.

Persistent chat memory

Local AI remembers your conversation between sessions. The cloud option can't - it's stateless on purpose - so this is one of the more noticeable differences in daily use.

  • Each completed exchange is added to the running conversation.
  • It's written out to %LOCALAPPDATA%\ConditioningControlPanel\local_chat_history.json in the background, so saving never slows down a reply.
  • Next launch, it's read back in. Her character briefing is not saved - that gets rebuilt every time, so any edits you make apply immediately.

The file holds the last 50 exchanges. Older ones drop off the front. That keeps the file small and stops her having to re-read an ever-growing transcript before every reply.

To turn it off, untick Chat memory under Companion → AI Brain. She'll stop both reading and writing the file. There's also a Forget everything button that wipes the conversation from memory and from disk.

Warm-up, lifecycle, and shutdown

Warming her up

Loading a model into memory is the slow part; answering is comparatively quick. So at startup the app sends Ollama an empty request that means "load the model, don't say anything yet", and asks it to stay loaded for 10 minutes rather than the usual 5. Without that, the model would quietly unload while you were away and your next message would pay the loading cost all over again.

If this fails - Ollama isn't running yet, say - nothing is shown. It logs the miss and moves on, and your first real message surfaces a proper error.

Shutting down

When you quit, the app tells Ollama it can drop the model from memory. If the wizard started the Ollama server itself, that process is stopped too. A server you or Ollama's tray app started is left running - it's yours, not ours.

Changing the host mid-session

Point the app at a different Ollama (a machine on your network, say) and the next request notices, throws away the old connection and builds a new one. No restart needed.

Error handling and fallbacks

Local models break in different ways than cloud ones do, so the app translates the technical failure into something you can act on:

SymptomWhat you seeWhat it means
Nothing is listening Can't reach Ollama at ... - looks like it isn't running. Start Ollama, or install it from ollama.com Ollama crashed or never started.
Unknown host name Can't reach Ollama host ... - check the host setting in Companion → AI Almost always a typo in a remote host address.
No answer in time Ollama took too long to respond. The first request after launch can take ~30-60s as the model loads - try once more. The model was cold and didn't finish loading within the 5-minute limit, or it's simply too big for the machine.
Model missing Ollama: model 'X' not found - check 'ollama list' or pull it Your settings name a model you haven't downloaded.
Something else Ollama HTTP NNN: ... Passes through whatever Ollama said, word for word.

If a request succeeds but comes back empty (rare, but some models do it under load) you get the usual fallback line instead of silence, and your message is rolled back out of the history.

Picking a model

The default is qwen3.5:latest, chosen because:

  • At ~6.6 GB it fits on most people's machines.
  • It follows instructions and produces well-formed structured replies, which is what the effects system depends on.
  • It can reason step by step when asked, though the app switches that off for chat to keep replies quick.

Nothing about the app is tied to it. Anything you can download through Ollama and chat with should work. To swap:

  1. Download it: ollama pull mistral-nemo:latest.
  2. Open Companion → AI Brain and pick it from the Model list, or type the name in.
  3. The next message uses it. No restart.

Rough guidance

Model sizes are quoted in "parameters" - roughly, how big the brain is. Bigger writes better and runs slower.

SizeNotes
3B-8BAround 5-8 GB on disk. Best speed on a normal computer. Start here.
13B-22BAround 10-14 GB. Noticeably better writing, noticeably slower without a graphics card.
30B and upYou want a real GPU with 24 GB or more. Loading takes a while.
Reasoning modelsFine to use. The app tells them to skip the thinking phase so replies stay quick.
Uncensored modelsWorth trying if you find the default too prim about explicit roleplay.
Very small (~1B)Usually can't hold the reply format together. Expect raw brackets in her speech bubble.

To see what you already have, run ollama list, or open http://localhost:11434/api/tags in a browser.

Privacy

Once local AI is set up, the app makes exactly two kinds of AI-related network request, both of them optional and both of them one-offs:

  • Downloading the Ollama installer, once, from ollama.com during setup.
  • Downloading a model, when you ask for one. That goes straight to Ollama's servers, not ours.

After that, every message goes to http://localhost:11434/, which is your own computer. The model runs there. We never see it.

One thing to be aware of: the conversation is saved as ordinary readable text at %LOCALAPPDATA%\ConditioningControlPanel\local_chat_history.json. Anyone who can open a file on your machine can read it. If that's a concern, untick Chat memory, use Forget everything when you're done, or turn on full-disk encryption.

For contrast: the cloud option sends each chat line, your character briefing and your screen-awareness context to our proxy, which forwards it to a hosted model. We record request counts and whether you're logged in. We do not record what you say. The Custom (OpenAI-Compatible) option sends the same things to whatever endpoint you configured, and what happens to them there is between you and that provider. See the privacy policy for the full breakdown.

Troubleshooting

"Can't reach Ollama at http://localhost:11434/"

Ollama isn't running. Start it from the Start menu, or run ollama serve in a terminal. To check, open http://localhost:11434 in a browser - you should see "Ollama is running". If you don't, it isn't. If you get "address already in use", something else has the port; check your firewall.

"Ollama took too long to respond"

The model was loading for the first time and ran past the 5-minute limit. Wait a moment and try again, or pick something smaller. ollama ps in a terminal shows what's currently loaded.

"model 'X' not found"

The model named in your settings hasn't been downloaded. Run ollama pull X in a terminal, or re-run the setup wizard.

She replies with brackets and quote marks

That's raw model output the parser couldn't clean up, which means the model isn't producing the format the app asked for. Usually it's too small - anything around 1B struggles with this. Try something bigger. The other cause is a custom personality preset that flatly forbids structured replies; the enrichment block is meant to override that, but some models obey the preset anyway. Either edit the preset or switch off "Allow AI to control effects".

Effects fire when I told them not to

Check three things: the master switch, the switch for that specific effect, and the Live actions feed on the Companion tab, which lists what actually ran. If the feed shows something you've disabled, that's a bug - please report it with your logs/crash.log.

She's repetitive and boring

Usually the chat history. A long conversation can dig the model into a rut it won't climb out of. Hit Forget everything on the Companion tab and start clean.

Effects feel laggy

Some of that is unavoidable: she can't trigger anything until she's finished thinking. On a CPU-only laptop that's 5-15 seconds; the effect itself then fires almost instantly. With a graphics card the thinking drops to 1-3 seconds and the lag stops being noticeable. If you have an NVIDIA card and it still feels slow, run ollama ps - if it says the model is "100% CPU", Ollama hasn't found your GPU. Update your drivers and reinstall Ollama.

Advanced: pointing at a remote Ollama

The host setting takes any address, not just your own machine. If there's a faster computer on your network (or a server you trust), run Ollama there and point the app at it:

  1. On that machine, start Ollama with OLLAMA_HOST=0.0.0.0 so it accepts connections from elsewhere. By default it only talks to itself.
  2. Make sure the model you want is downloaded there.
  3. In the app, set Companion → AI Brain → Host to http://your-server:11434/.
  4. The next message goes to the new address. Nothing else to do.
Read this before you open a port

Ollama has no login and no password. Anyone who can reach it can use it. Do not expose it to the open internet without putting a proxy with authentication in front of it. Also note that network delay is added to every reply (unnoticeable on your own network, painful over the internet), and the 5-minute limit still applies - a slow remote may need a smaller model or a closer server.

Glossary

OllamaA free tool from ollama.com that runs language models on your own computer. It sits in the background, downloads models on request, and answers on port 11434.
Cloud AIOur hosted option, and the default. Needs a free account. Capped daily.
Local AIOllama on your machine, standing in for the cloud. No account, no cap, no data leaving the building.
Custom (OpenAI-Compatible)Any other server that speaks the OpenAI chat format. You provide the address, the model name and an API key if it needs one.
ModelThe actual brain file, named like qwen3.5:latest. The bit after the colon is the version, usually just latest.
System promptThe briefing she gets before every conversation: character, rules, what she's allowed to know.
Enrichment blockAn extra instruction slipped in behind the briefing, telling her how to format effect commands. Only present when "Allow AI to control effects" is on.
Effect commandThe structured way she asks the app to do something - flash, bubbles, haptic and so on.
Master toggle"Allow AI to control effects". The one switch that decides whether she can trigger anything at all.
Warm-upLoading the model into memory ahead of time so your first message isn't slow.
Chat memoryThe saved conversation, kept at %LOCALAPPDATA%\ConditioningControlPanel\local_chat_history.json. Last 50 exchanges. Local provider only.

Spotted something wrong here? Open an issue at CC-Labs-llc/ccp-bugs or say so in the Discord. Local AI shipped in v5.8.4 and these docs move with it.