Skip to main content
Unhinted

For people who read source

MIT open source,running on your own machine.

This page is the short version of how Unhinted is built: the stack, the pipeline, and how to self-host. Install details, config, and ADRs live in the repo — no duplication here.

The stack

FastAPI (Python) on the back end, a React SPA on the front, PostgreSQL with pgvector as the database. The agent loop is orchestrated with LangGraph; every model call goes through LiteLLM.

FastAPI
REST API and agent sessions, SSE streaming
React
Single-page app with a chat-style drafting UI
PostgreSQL + pgvector
Data, vectors, and product embeddings in one DB
LangGraph
The agent loop from angle-picking to drafting
LiteLLM
Model-agnostic — swap providers without code changes

From talking point to published

  1. 1

    Hourly signal ingest

    A scheduler pulls Hong Kong talking points every hour (Google Trends HK); Tavily can be added for deeper research.

  2. 2

    The LLM only drafts

    Picking angles, writing captions, revising with you — that loop is LangGraph. Before drafting, local embeddings (FastEmbed) filter out what isn't relevant.

  3. 3

    Publishing is ordinary code

    When you hit Confirm, the backend runs a normal HTTP publish flow. The LLM never touches the publish switch, so nothing goes out on its own.

Bring your own model

OpenAI by default, but any OpenAI-compatible endpoint works — OpenRouter, DeepSeek, Azure, or a local gateway. Models come in cheap / medium / strong tiers, with a separate image model.

Each organization can bring its own LLM API key (BYOK), stored Fernet-encrypted in the database; without one, the env-configured key is the fallback.

One Compose file on your own machine

The all-in-one package bundles pgvector Postgres; once it's up, open localhost:8484 — a first-run setup wizard walks you through. Already have Postgres? There's an external-DB compose file too.

Media lands on local disk by default and can migrate to S3-compatible storage later without downtime. Instagram publishing connects through your own Meta app (BYO app) — nothing routes through us.

Terminal
curl -LO https://github.com/brandon-wsc/unhinted-marketing/releases/latest/download/compose.yaml
docker compose -f compose.yaml up -d
# → http://localhost:8484

Full disclosure

This is still a pre-release (beta): Instagram is the only publish target today, and the default publish adapter is a stub — a real post only goes out once a Meta app is connected.

The whole repo is MIT-licensed. See something off? Issues and PRs are welcome.