@kkodo/bettersync
v0.10.1
Published
Drop any chat export — WhatsApp, Telegram, Facebook Messenger, more — into your S16 Brain. Run any Brain agent locally with your own LLM (Groq, OpenAI, Ollama, etc.).
Maintainers
Readme
BetterSync
Drop any chat export — WhatsApp, Telegram, Facebook Messenger, more — into your S16 Brain. Then run any of your Brain's agents locally with your own free LLM key. Pluggable parsers, no LLM in the data path, no S16 wallet charges for AI.
$ npm install -g bettersync
$ bettersync init # one-time S16 token setup
$ bettersync auth llm --provider groq --key gsk_... # any LLM you want
$ bettersync config defaultMode local # or platform | auto
# Ingest any chat export
$ bettersync ingest ~/Downloads/facebook-export/
Parsed: 40 conversations, 2657 messages (0.1s)
✓ Ingested 2657/2657 in 38.2s
# Run any agent in your Brain — interactive picker if you don't pass args
$ bettersync run
? Pick an agent (type to filter): Conversation Insight Extractor
? Where is the target page? 💬 Conversations
? Pick a page in "Conversations": Aime Sien
▸ Conversation Insight Extractor · local · https://api.groq.com/openai/v1
status: success (1.59s)What's new in v0.3.0
- Interactive picker —
bettersync runwith no args opens a fuzzy-search menu of your agents and target pages. No more remembering names or typing UUIDs. - Shell completions —
bettersync completions bash | zsh | fishprints a script tosourcefor tab-complete on agent and database names. One-time install per shell.
Why
Two problems BetterSync solves:
Bulk data ingest into S16 was awkward. Every chat platform has its own export format, and LLM-based ingest tools choke on bulk data because the LLM becomes the data conduit. BetterSync talks directly to your S16 workspace's MCP-over-HTTP endpoint with your API token — no model in the loop, just HTTP at network speed.
Running S16 agents costs $$. S16's built-in
s16.ai()goes through their gateway and charges your workspace wallet. BetterSync's local runner fetches an agent's compiled script via MCP, executes it on your machine in a Node sandbox, and intercepts everys16.ai()call to route it to any LLM you choose — Groq's free tier, a paid OpenAI/Anthropic key via OpenRouter, fully-local Ollama, your own self-hosted endpoint, anything that speaks the OpenAI Chat Completions protocol. Same agent, same script, same output — your AI bill, your rules.
Install
npm install -g bettersync
bettersync initinit walks you through getting an API token from your Brain
(Settings → Development → API Tokens) and verifies the connection.
If you want to use the local agent runner, point it at any LLM you like:
# Free, fast — Groq's free tier
bettersync auth llm --provider groq --key gsk_... # console.groq.com/keys
# Free, fully local
bettersync auth llm --provider ollama # ollama pull llama3.3 first
bettersync auth llm --provider lmstudio
# Bring your own paid keys
bettersync auth llm --provider openai --key sk-...
bettersync auth llm --provider openrouter --key sk-or-v1-...
bettersync auth llm --provider together --key tgp_v1_...
bettersync auth llm --provider fireworks --key fw_...
bettersync auth llm --provider cerebras --key csk-...
bettersync auth llm --provider deepinfra --key ...
# Or any OpenAI-compatible endpoint at all
bettersync auth llm --base-url https://my-internal-llm/v1 --key xxx --model my-modelIf you prefer not to install globally, use npx:
npx bettersync ingest ~/Downloads/whatsapp-export/Supported chat formats
| ID | Source |
|---|---|
| facebook-messenger | Facebook DYI Messenger HTML export |
| whatsapp | WhatsApp text export (iOS _chat.txt and Android WhatsApp Chat with X.txt) |
| telegram | Telegram Desktop JSON export (single chat or whole-account) |
Auto-detect picks the right one:
$ bettersync detect ~/Downloads/some-export/
whatsapp (WhatsApp (text export))Want a different format? Adding one is one file under src/parsers/. See
CONTRIBUTING.md.
Commands
bettersync init Interactive first-time setup
bettersync auth login --token <token> Save your S16 API token
bettersync auth llm --provider <id> --key <key> Configure your LLM provider
(groq | openai | openrouter |
together | fireworks | cerebras |
deepinfra | ollama | lmstudio)
bettersync auth llm --base-url <url> [--key] Or any OpenAI-compatible URL
[--model <id>]
bettersync auth groq --key <key> Shortcut for `auth llm --provider groq`
bettersync auth status Show saved credentials (masked)
bettersync auth logout Clear all saved credentials
bettersync formats List supported source formats
bettersync detect <folder> Auto-detect a folder's format
bettersync ingest <folder> Parse + push to Brain
[--dry-run] [--format <id>]
bettersync extract-insights Extract structured insights from
[--limit <n>] your Conversations using your LLM
bettersync run <name> Run an agent (mode from config:
[--input <json>] local | platform | auto)
[--input-file <path>]
[--mode <mode>] override defaultMode for this call
bettersync config Show all settings (secrets masked)
bettersync config <key> Get one value (dotted path ok)
bettersync config <key> <value> Set one value
bettersync config edit Open the config file in $EDITOR
bettersync agents list List all agents in your Brain
bettersync agents run <name> (advanced) explicit platform run
bettersync agents run-local <name> (advanced) explicit local runHow it works under the hood
Ingest pipeline
[your machine] [api.team-brain.com]
bettersync ingest ./folder MCP HTTP
│ server
├── parser/<source>.mjs → uniform schema ───► s16_create_page
│ (one of 3 today) ↓
│ database
└── pipeline row
• bootstrap schema (idempotent)
• dedupe Conversations by handle
• bulk-insert Messages (concurrency 12)
• progress + retryLocal agent runner
bettersync agents run-local "X"
│
├── 1. fetch agent.compiledScript via s16_get_agent
│
├── 2. spin up a Node sandbox with a custom `s16` global:
│ s16.ai(...) → your configured LLM (Groq / OpenAI /
│ Ollama / OpenRouter / etc.)
│ s16.httpRequest(...) → native fetch
│ s16.createPage(...) → MCP call to your workspace
│ s16.readDatabase(...) → MCP call to your workspace
│ s16.getCredential('groq') → returns local key only when
│ provider is groq (so existing
│ Groq-hardcoded agents still work)
│ s16.store / sharedStore → in-memory KV (this run only)
│
└── 3. execute the script. Same agent, your chosen LLM, no S16 wallet.The CLI speaks MCP-over-HTTP (JSON-RPC 2.0 on a single endpoint) using your bearer token. Same surface that Claude Desktop / Claude Code use, just called from a regular HTTP client. No tunnel, no intermediate storage.
Limitations of the local runner
- Workspace credentials/secrets other than Groq aren't auto-forwarded — your
agent's
s16.getCredential('telegram')returnsnulllocally. s16.storeandsharedStoreare in-memory for the run only; no persistence.- Webhook/event/cron triggers obviously don't apply —
run-localis on-demand. - File uploads (
s16.uploadFile) aren't implemented yet.
For these cases, fall back to bettersync agents run <name> which triggers
the agent on the platform.
Adding a parser
See CONTRIBUTING.md. Short version: write one file under
src/parsers/, register it in src/parsers/index.mjs, done. Each parser is
~150 lines and ~30 minutes of work.
License
MIT — see LICENSE.
