Instant Personas / System

Describe a market. Talk to the people in it.

Instant Personas (2024) turned audience research into a product: a description of a market became a set of personas, each one a structured card you could chat with, and around them a belt of tools that pulled keywords, hashtags, blog drafts and share images for the same audience. It was one of the first tool-calling agents on the Vercel AI SDK. This page is built from what survives: the recorded product, and the first commit of its code.

unique visits at peak, 7K monthly active users
50K+unique visits at peak, 7K monthly active users
tools in the belt: personas, chat, topical authority, keywords, hashtags, blog, Open Graph, survey
8tools in the belt: personas, chat, topical authority, keywords, hashtags, blog, Open Graph, survey
commits in the surviving repository: the scaffold, not the shipped build
4commits in the surviving repository: the scaffold, not the shipped build
route in that scaffold: an edge chat handler on gpt-3.5-turbo
1route in that scaffold: an edge chat handler on gpt-3.5-turbo

Specified from the recorded product and the first commits of its codeThe shipped build’s source is not in the archive

01

The product

Behaviour as the recordings show it. The shipped source is not in the archive; this section describes observed behaviour and the next describes the code that remains.

1.0

Three identities the product is built from.

Named once here; the sections below refer to them.

Design identities and where each appears
IdentityRuleAppears in
Persona as the shared inputOne structured object is the subject of every tool, so the outputs of different tools describe the same person.Generator, chat, every tool in the belt
Structure before textA persona is a typed object with named fields; prose is a field, not the container.The persona type, the card, the chat identity
Terminal inputOne command-line style textarea takes prompts and commands; Enter submits only at the end of the text.The generator input, the chat input

1.1

Run: one market description to a set of chattable persona objects.

Persona as the shared input, structure before text. The generator took a paragraph about a market and returned a set of personas as typed cards: name, role, attributes with icons, sections of narrative. Any card opened as a chat that stayed in character, and every later tool took the card as its subject.

rackrest
16 units
Eight tubes in a rack: the one under the pointer lifts clear, and its neighbours rise a little less each.

The figure is the persona set: eight samples from one market description. Lifting one is opening its chat; the neighbours rise less with distance, standing for the adjacent segments the tools also read.

  1. 01 Describe

    A paragraph about the product or market, typed into the terminal-style input.

    Returns
    The prompt
  2. 02 Generate

    The model returns a set of personas as structured cards.

    Reads
    The description
    Returns
    Name, role, attributes with icons, narrative sections
    When it cannot
    Not recoverable from the archive.
  3. 03 Select

    A persona is chosen from the set.

    Returns
    The subject for the tools
  4. 04 Chat

    A conversation with the persona, kept in character, resumable from history.

    Reads
    The persona and the thread
    Returns
    Streamed replies; chats started are counted
  5. 05 Tools

    Topical authority, keywords, hashtags, a blog draft and share images for that audience.

    Reads
    The persona
    Returns
    Lists, drafts and images to download or post
Limits of this part+

The structured output and the identity prompt that kept a persona in character are not in the surviving code. The scaffold's chat has no system prompt at all (see 2.1).

1.2

Tools: eight functions sharing one persona as input.

Each tool answers one question about the same persona, so the outputs agree with each other.

Each tool, its question and its output, as recorded
ToolQuestionOutput
Persona generatorWho is in this market?A set of structured persona cards
Persona chatWhat would this person say?A conversation kept in character, with history
Topical authorityWhat should we be known for with them?A topic map ranked for the persona
Keyword finderWhat do they search?Keywords for the persona
Hashtag finderWhere do they gather?Hashtags for the persona
Blog creatorWhat would they read?A draft post
OpenGraph creatorWhat would they share?Share-card images from templates
Survey and feedbackAre we right about them?A survey popover; a feedback center with votes

1.3

Usage figures, and what they do not show.

Traffic and active users were real; revenue was not. The product declined after its peak and did not become a durable business.

Unique visits
50 000 and more
Monthly active users at peak
7 000
Subscription
a popover existed; conversion is not recorded
Giveaway
tag the account on X for a free subscription
Mobile
a "no mobile" screen: desktop only
02

The surviving code

The repository holds four commits from March and April 2024: a chat route, a persona card and a dashboard shell. It is the start of the product, not the product. What it shows is still worth reading.

2.1

Chat route: an edge passthrough to gpt-3.5-turbo.

useChat from the AI SDK posts the whole history to one edge route, which forwards it to gpt-3.5-turbo with stream on and returns the stream. The greeting that says what to type is rendered outside the messages, so the model never saw it.

The chat route
export const runtime = 'edge'
const { messages } = await req.json()
const response = await openai.chat.completions.create({
  model: 'gpt-3.5-turbo', stream: true, messages,
})
return new StreamingTextResponse(OpenAIStream(response))
Limits of this part+

No system prompt, no tools, no structured output, no try/catch, no validation, no truncation. The message renderer already maps function, tool and data roles: scaffolding for tool calls that this commit never makes.

2.2

Persona: a TypeScript type, no schema, no generator in this commit.

Structure before text, as the scaffold already has it: the card takes a persona type with name, gender, picture, attributes and sections. One example is hardcoded and the fields are editable in local state.

The persona type
type UserPersona = {
  name: string
  gender: string          // "required for getting the pictureURL"
  pictureURL: string
  personalAttributes: { label: string; description: string; icon: Icon }[]
  sections: { label: string; description: string }[]
}

Dashboard

Two parallel routes.

app/dashboard takes chat and map slots and shows them as two tabs, Persona Chat and Map, inside a resizable, collapsible shell.

Entrance

A spring.

The route template moves content from y 20 to 0 and scale 0.9 to 1 over one second, inside a scroll area of calc(100vh − 58px).

Shell state

Cookies.

Panel layout and collapse are the only things persisted; everything else is component state.

Limits of this part+

It is a TypeScript type, not a schema; nothing validates it and no model fills it here. The Change Colour, Change Picture and Download Image buttons have no handlers.

2.3

Input: a terminal textarea with a cursor-position submit rule.

Terminal input. CommandUserInput is the FCS command line: Enter submits only when the cursor is at the end of the text and not after a space, otherwise it inserts a newline; Ctrl or Cmd with Enter always submits; the box grows to 208 px.

Submit on Enter
cursor at the end, previous character not a space
Always submit
Ctrl or Cmd + Enter
Auto-grow limit
208 px, line height × 1.2
Sidebar breakpoint
1025 px (205 px × 5)
03

Interface rules

A shadcn slate base with a green primary and its own persona palette; Inter for the body and Jost for the brand.

3.1

Tokens and layout.

The tokens are shadcn's with a green primary in light mode and a custom set of persona background, foreground, accent, border, text and title variables for the cards.

Colour

Primary
hsl(142 69% 58%); near-white in dark mode
Persona background / foreground
hsl(250 75% 98%) / hsl(222.2 84% 90%)
Persona accent
hsl(222.2 84% 75%)
Active nav
bg green-100, icon green-500
Chat bubbles
assistant gray-200, user blue-100, mono small
Page
zinc-100

Type and layout

Body
Inter
Brand and nav
Jost
Radius
0.5rem, with lg, md and sm derived
Header
58 px with title and tabs
Persona card
4-column grid, rounded-xl, shadow-lg, editable fields

3.2

Trade-offs.

What the scaffold already decided, and what each decision costs.

Design decisions, reasons and costs
DecisionReasonCost
Persona as a typed objectThe card, the chat and every tool read one shape.In this commit the shape has no schema and no generator.
Edge route, stream passthroughLow latency and very little code.No server-side prompt, validation or logging.
Parallel routes for the dashboardChat and map load as independent slots.The whole dashboard is a client component, so the server-component setup is unused.
A terminal-style inputOne input for prompts and commands, reused from FCS.The Enter rule needs explaining.

3.3

Not in the archive.

The code that ran at 7,000 monthly active users is not in any repository in the archive.

The shipped build’s source
not in any repository in the archive
Tool-calling, schemas, database, auth, billing in the scaffold
none
Routes the scaffold’s sidebar links to
4 of 5 do not exist
Tests in the scaffold
one file, on a helper the app does not use
Dark mode
configured, never mounted
Metadata title
still "Create Next App"