Convo

How It Works

How Convo assembles a prompt from slots, plans a run from seeds, keeps a friend's memory across a thread, and filters every conversation in three layers, cheapest first.

Three stacked filter layers: Layer 1 rules and Layer 2 diversity make no model calls, Layer 3 is a judge with one cheap call, and what survives is accepted. Each layer shows its reject reason.

Prompts as slots

The generation prompt is assembled from eleven slots in a fixed order: frame, user persona, assistant voice, register, memory, occasion, threads, quirks, ending, examples and output rules. Separate slot families cover the judge, roughening, memory updates, duo mode and drafting new personas.

Each slot holds segments: Mustache-style templates rendered over the seed, so one segment reads differently for every conversation. The segment editor has a variable palette, a live preview against sample seeds, versions with restore, and a diff view. Built-in segments can be copied but never overwritten, and every run snapshots the rendered segment bodies, so later edits never change what a finished run used.

Planning a run

When a run starts, Convo plans every conversation in one pass and stores each seed on its conversation row. Each draw has its own random stream keyed by the run seed, its purpose and the ids involved, so the same inputs always replay the same run.

  • Personas are user cards: name, age, city, occupation, household, preoccupations, a verbal habit and a "this month" block of recent happenings. New cards are drafted by a model into a review queue and only join the pool once a person accepts them. Persona names never appear in exported turns.
  • Voices are the friend's personalities: enthusiasms, humor, warmth, energy and an exclamation budget. A voice never has a hometown, a job, a body or a past.
  • Threads form because a persona appears in several conversations per run and keeps one voice throughout, so the friend stays the same friend.
  • The sampler re-draws when an occasion, mood and first topic combination has already come up in the run, and persona choice leans toward cards earlier runs used less.

Memory across a thread

After a conversation is accepted, a memory-update prompt merges it into the thread's memory: the names the person has mentioned and who they are, places, ongoing situations and open threads. The next conversation in the thread renders that memory into its prompt. Memory is rewritten rather than appended and kept to about two hundred words, and the update drops any name that appears in neither the person's turns nor the previous memory, so the model can't invent a detail that the next conversation then "remembers".

Because each conversation needs the memory from the one before it, the worker only ever dispatches the lowest unfinished conversation of each thread. Parallelism comes from the number of threads with work left.

The run pipeline

A run is a chain of background jobs: plan, then generate, filter, judge and memory update for each conversation. Generation runs in single-pass mode, where one call writes the whole transcript, or duo mode, where a director alternates two contexts and the friend's side never sees the persona card. An optional roughening pass makes the person's side a little messier on a share of accepted conversations and leaves the friend's side alone.

Every job is idempotent: every write is conditional on the row's state and run counters are recomputed from the conversation rows, so a killed worker resumes without duplicates. Pause, resume and cancel are flags every job checks first, and cancel aborts model calls in flight.

Three filter layers, cheapest first

Three stacked filter layers: Layer 1 rules and Layer 2 diversity make no model calls, Layer 3 is a judge with one cheap call, and what survives is accepted. Each layer shows its reject reason.
Only conversations that pass the free checks reach the judge.
  1. Rules, with no model call: line format and role runs, stage directions and markdown, the no-body, no-botspeak and no-invented-memory rules, the friend knowing something only the persona card says, length, a word cap on each friend turn, question ratio, exclamation density per voice, repeated openings and copied examples.
  2. Diversity, also with no model call: MinHash over word shingles against every earlier accepted conversation in the workspace rejects near-duplicates, and a distinct-n ratio tracks how varied recent output is.
  3. Judge, one cheap model call that scores seven dimensions from 1 to 5: whether the person sounds natural, the friend's warmth, its response to the mood, how knowledgeable it is, freedom from body claims, continuity with memory, and whether the conversation leaves something open.

Phrase lists are pools edited in the UI, not constants in code, and a missing filter pool fails closed. Every rejection carries a reason from one list, so the run page can group them by layer. In our paired pilot, where each built-in prompt set wrote conversations for the same 34 seeds, the rules layer caught 60 of the 66 rejects and the judge caught the other 6.