Site cover image

Daniel Cui's Blog

硬核AI与产品落地笔记

28 秒装好私人 AI:Talorys 实测踩坑 / Half a minute to a private AI

Title (EN/ZH)

Half a minute to a private AI
28 秒装好私人 AI:Talorys 实测踩坑

Executive Summary

create-talorys 0.1.7 deployed to a free Cloudflare account in about 28 seconds on Node 22.23.4 with Wrangler 4.149.0. Real chat (Chinese first token 0.7s / 3.9s total; English 0.44s / 1.4s), login and reminders worked. Hard requirements: Node 22+, API token instead of OAuth on remote hosts, five token scopes (not a Global Key), and a writable Wrangler cache—our first failure looked like a missing Cloudflare permission and was EACCES on node_modules/.cache/wrangler. Free Workers AI: 10,000 Neurons/day; our four calls used ~99 Neurons (~300 short chats/day at measured overhead). Local npm run dev also works (~8s install, ~30s boot) with CSRF header x-talorys-request: 1.

Draft Body

Half a minute to a private AI

create-talorys 0.1.7 really did land on a free Cloudflare account in about 28 seconds. Reaching that point took Node 22, an API token with the right scopes—and reading the error *Details*, not the headline.

The pitch for Talorys is blunt. It is a free, MIT-licensed personal AI assistant that lives inside *your* Cloudflare account: Pages for the UI, a private Worker for the API, a Durable Object with SQLite for chat, memory, tasks, notes and reminders, and Workers AI (default `@cf/zai-org/glm-4.7-flash`) for the model. No rented VPS. No third-party vault for your transcripts. One owner password; no multi-user signup. Chat streams Markdown and can create tasks or reminders mid-conversation. Memory is editable. Automations cover one-shot and recurring reminders. When the AI free allocation is gone, the non-AI surface—tasks, notes, memory, reminders—keeps working.

It suits people who want a single-user assistant they control, who will not rent a server, and who can paste a few shell commands. Two limits up front: the npm 0.1.7 UI is English-only (GitHub main added Korean after mid-October 2026 via #76 and #93; still no Chinese UI), though cloud chat accepts Chinese; and one install equals one owner.

On 27 October 2026 (PDT) we put the pitch through a non-theatrical test: create-talorys 0.1.7, Node 22.23.4 via nvm, bundled Wrangler 4.149.0, a free Cloudflare account, and a non-interactive install with `CLOUDFLARE_API_TOKEN`, `TALORYS_OWNER_PASSWORD` and `--yes`. The run that counted finished in 28 seconds, exit 0. Health checks passed on the first propagation wait. Login, Chinese and English chat against real Workers AI, and a reminder all worked. What follows is a field note on the footguns that spent more calendar time than the successful deploy.

What must be true before you type the command

Node is not a detail. On the system Node 20.19.2 the installer exits immediately:

■ Node.js 22.0 or newer is required (found 20.19.2).

Miniflare and friends also emit EBADENGINE warnings for engines below 22. Install Node 22 or newer. If you use nvm on a host that sets `NPM_CONFIG_PREFIX` (ours pointed at `/home/box/.local`), nvm refuses until you `unset NPM_CONFIG_PREFIX`. Worse: `nvm use 22` is per shell. Open a fresh terminal, forget the alias, and you are back on 20. We did that between attempts; the installer again reported 20.19.2. Fix: `nvm alias default 22`, or check `node -v` every time you open a window.

Authentication is the second fork. On a laptop with a real TTY, interactive `wrangler login` is fine. On a remote host, SSH session, CI job or container it is not. The OAuth redirect is `http://localhost:8976/oauth/callback`—localhost on the machine running the installer, not on your browser. Completing Cloudflare consent on your laptop cannot close the loop to a remote box. Set `CLOUDFLARE_API_TOKEN` instead. Without a TTY and without a token, the installer stops cleanly: not authenticated; run interactively or set the token; no data deleted.

The owner password is the only login forever after. Prefer at least 10 mixed characters or 16+, and avoid common words. The installer hashes it locally before storing secrets on Cloudflare; plaintext is not uploaded. Do not leave `export TALORYS_OWNER_PASSWORD=…` sitting in a shared script.

The token checklist—and the lie that looks like a missing scope

Talorys does not want a Global API Key. Build a custom token with:

• Account → Workers Scripts → Edit
• Account → Cloudflare Pages → Edit
• Account → Workers AI → Read
• Account → Account Settings → Read
• User → User Details → Read (optional; shows your email during install)

Scope Account Resources to the one account you intend to use. Cloudflare's token verify endpoint is a cheap sanity check before you burn another install attempt.

Our first full-auto attempt still died in four seconds at "Reserving resource names," with the comforting accusation that the Cloudflare login lacked a required permission. The Details box told a different story: EACCES on `/node_modules/.cache/wrangler`. Wrangler writes cache under the nearest `node_modules/.cache`. A root-owned `/node_modules` higher up the tree produced a filesystem error; the installer translated it into a permissions sermon about Workers Scripts and Pages. The fix that worked:

export WRANGLER_CACHE_DIR=$PWD/.wrangler-cache

Then rerun in the same directory. Failures leave no half-built wreck; retries resume. Moral: when the installer scolds your token, read the Details block first.

What a clean run looks like

With Node 22, a writable Wrangler cache and the scopes above, the non-interactive path is short:

export CLOUDFLARE_API_TOKEN=…
export TALORYS_OWNER_PASSWORD=…
npx create-talorys@latest --yes --account-id <your-account-id>

Ours reserved a resource id, deployed the private Worker plus SQLite Durable Object, configured Workers AI, hashed the owner password into Cloudflare secrets, published Pages and reported healthy after one wait. The app URL is owner-only (`https://talorys-<id>-web.pages.dev`). Keep the generated `talorys/` directory; upgrades and password resets need it. Mid-install interruption is safe: rerun in the same folder and the installer continues without duplicating resources.

Post-deploy checks need two unadvertised habits. Use a browser-like User-Agent—Python's default urllib UA drew a Cloudflare 403 in our verify script. And every API call needs the CSRF header `x-talorys-request: 1`, or the server answers 403 "Missing CSRF header."

Results:

• `/api/health`: ok, v0.1.7, schema 10, `ai_binding` true
• unauthenticated data routes: 401
• wrong password: 401 "Incorrect password."
• correct login: 200

Chat against the live free-tier model, not a mock:

• Chinese prompt: first token in 0.7s, done in 3.9s, structured Chinese
• English prompt: 0.44s first token, 1.4s total
• "明天早上9点提醒我给妈妈打电话": `create_reminder` fired; once at 2026-10-28 09:00 Asia/Shanghai; reply wording slightly awkward, reminder correct

Usage panel for that session: 4 AI requests, roughly 16.2k input and 269 output tokens, about 99 Neurons. System prompt plus tool schemas alone cost ~4k input tokens per call. On the free 10,000 Neurons per day (reset 00:00 UTC), that ballparks to ~300 short chats before the meter stops—fewer if turns grow or tools fire often. Cloudflare's published rates for glm-4.7-flash (pricing page dated 20 October 2026): 5,500 Neurons per million input tokens, 36,400 per million output. Stay on the free Workers plan if you want a hard stop rather than metered overage at $0.011 per 1,000 Neurons. Talorys's Settings → AI sliders (max output, context, tool calls, daily request cap) and the Usage panel are local estimates, not the Cloudflare invoice.

Timezone defaults to the machine that ran the installer (`detectTimezone` in install.ts). Our box was +08, so Settings showed Asia/Shanghai without edits. Install from a UTC VPS and your "9am" reminders will be wrong until Settings → General → Timezone is fixed; existing reminders reschedule.

Local rehearsal without Cloudflare

If you only want the UI before committing an account, clone the repo and run development mode. `npm install` took ~8s; `npm run dev` brought up ports 5173 / 8788 / 8787 in ~30s. Health was fine (`schema_version` 11 in our local notes—one digit ahead of the cloud build we measured). Default password: `talorys-dev-password`. Mock AI understands a narrow set of English commands. The same CSRF header applies to local API calls.

Smaller traps worth naming once

Multiple Cloudflare accounts under one login: pass `--account-id`. Health checks that fail on a fresh `pages.dev` often need a few minutes for DNS and certificates; rerun the installer in the same folder. A leftover non-Talorys `talorys/` directory blocks overwrite—use an empty path or `--dir`. Too many bad passwords yield a lockout ("Too many failed attempts"); wait 15 minutes or run `reset-password` from the install directory (all sessions drop). `npx create-talorys@latest doctor` is the catch-all self-check. In mainland China, raw `*.pages.dev` is flaky; add the custom hostname on the Pages project *before* pointing DNS, or expect 522s. Screenshots of the token UI should redact account emails and avatars; the token value itself must never appear.

Verdict

Talorys does what the README claims on a free Cloudflare account, in roughly the time it takes to brew coffee, provided four unromantic conditions hold: Node ≥ 22 and stuck that way across shells; API token instead of OAuth on any remote machine; the five scopes above (no Global Key); and a Wrangler cache directory you can actually write. The interesting failure we hit wore a permissions costume and was a filesystem bug underneath. Free AI headroom is real but finite—order-of-hundreds of short chats per UTC day at our measured overhead—while the non-AI surface survives the daily cliff.

A personal assistant that never leaves your Cloudflare bill is no longer a research project. It is a careful afternoon, plus the humility to read the Details box.

Closing Line

A personal assistant that never leaves your Cloudflare bill is a careful afternoon, plus the humility to read the Details box.