尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證A coach that remembers you. AI coaching chatbot with long-term memory on Walrus (Walrus Memory), Qwen 3.8 27B via Groq. Walrus Session 8 hackathon.
翻譯準備中
取自儲存庫 README
正在載入完整 README。 以下為已儲存的摘錄。
A coaching companion that actually remembers you between conversations. Runs as a
website (primary) and optionally as a Telegram bot — both share the same pipeline.
Long-term memory is stored encrypted on Walrus via
Walrus Memory; the LLM is Qwen 3.8 27B (open-weight) running on Groq
(no Anthropic/OpenAI in the loop).
Built for Walrus Session 8: Chatbots That Remember.
Every message goes through three steps (src/chat.ts):檢視完整 README ↗Live: https://walcoach.vercel.app · Repo: https://github.com/EdCryptoFi/walcoach
A coaching companion that actually remembers you between conversations. Runs as a website (primary) and optionally as a Telegram bot — both share the same pipeline. Long-term memory is stored encrypted on Walrus via Walrus Memory; the LLM is Qwen 3.8 27B (open-weight) running on Groq (no Anthropic/OpenAI in the loop).
Built for Walrus Session 8: Chatbots That Remember.
Every message goes through three steps (src/chat.ts):
coach-<telegram user id>): the message itself (cosine distance < 0.8) and a
fixed "core profile" query (goal, deadline, schedule, constraints), merged and
deduped — so even "hi, I'm back" surfaces what matters. (src/memory.ts → recallForUser)< 0.25), and each one is written as its own
encrypted blob with rememberAndWait. The user never waits on storage.
Set MEMORY_EXTRACTOR=relayer to use Walrus Memory's built-in analyze API
instead of our own model for extraction (src/extract.ts).Short-term context (last 12 turns) lives in RAM. Everything long-term lives on Walrus, so restarting the bot, switching devices, or coming back a week later changes nothing.
Each user owns their own Walrus Memory account on Sui, created for them by a sponsored
transaction, so isolation is an on-chain boundary and not just a namespace string. The
server holds one delegate key, authorised separately on every account, which the user can
revoke. Users created before this change stay on the shared project account and keep
working, isolated by namespace (src/memory.ts identityFor).
Design: "Decentralized AI Glass" — glassmorphism, Outfit + Plus Jakarta Sans, Material
Symbols, cyan/azure palette (tokens in src/styles.css, built with Tailwind v4
to public/app.css via npm run build:css; the static pages are generated by
python3 scripts/site/build.py). Pages:
/ — hero, the seven mentors (Zen, Work, Fitness, Study, Pets, Music, Cooking — each a
Walrus character), and the memory key section (name, generated key, copy, "I saved it").
Clicking a mentor as a new user scrolls to the key section with that mentor pre-selected;
returning users go straight to /chat?context=<mentor>./how — the four steps and the honest data flow (who sees what: Groq, relayer, Walrus)./security — what protects you and its limits, key recovery, plain-language FAQ./privacy — the data table./chat — sidebar, agent card with the modality selector, Durable facts in memory (each
linked to its blob on the Walrus explorer, export as JSON), the conversation with
"Memories used in this reply" chips, and the key modal.All copy is truthful about the architecture: encryption happens at the Walrus Memory relayer (SEAL), not in the browser; Groq sees the conversation text; memories are on Walrus mainnet.
Mentors / life areas. Every stored fact is tagged with one of 7 mentors (+ life)
(src/areas.ts) chosen by the extractor — [training] Ana runs on Tuesdays. The chat shows conversation starters per area on an empty screen and lights
up a badge for each area the user has memories in. It nudges people to bring more of
their life to the coach (which is where memory pays off: bad sleep ruins training), and
it costs no database — the badges are computed from the user's own memories.
public/index.html is a single-page chat served by src/web.ts.
Identity is deliberately Web2-flavoured: no wallet, no account. On first visit you type a
name; the browser generates a memory key (wal_…, an Ed25519 private key), keeps it in
localStorage, and uses it to open a Walrus Memory account owned by that key, paid for
by the project treasury through a sponsored transaction. The key never leaves the browser:
requests carry the account id instead. The key is shown in the side panel
with a Copy button; pasting it on another device ("I have a memory key") restores the same
memories there. Right after the first start a one-time card asks the user to save the key
(notes app, email to self, or Walnotes for Web3 users). Under the hood every memory is still
an encrypted blob on Walrus, in an account the user owns on chain, and the user never sees
a wallet.
The side panel is the point of the UI: it shows which memories were recalled for the last reply (with their cosine distance) and everything stored for this user on Walrus. The "Memory" switch in the header turns recall + learning off so you can see the "before".
API (all JSON): POST /api/chat {userId, name, text} → {reply, memories},
GET /api/memories?userId=, POST /api/remember, POST /api/memory {enabled}, POST /api/reset.
VOICES in src/areas.ts); the chat header toggles
Character voice / Neutral (default neutral, remembered per browser).localStorage, applied before paint).prefers-reduced-motion. No Three.js needed, so the CSP stays script-src 'self'.STARTERS), shown as chips in the chat.POST /api/summary), cached an hour in the browser, refreshed after new facts land.POST /api/handover), proving the seven share one memory.Facts about the user and the coach's concrete suggestions (a recipe, a plan, a routine; stored as "Coach suggested … to ") so "what did you tell me to cook?" works next session. Two more pieces keep this reliable in practice:
localStorage per memory key (24 h), so a refresh restores the
conversation on screen and in the model's short-term context.pending with each message and count as memory until they show up in recall, so a question
asked seconds after the answer is still remembered.Every memory in the panel has an ↗ link to its blob on the Walrus explorer
(walruscan.com/mainnet/blob/<blob_id>), and the "You" dialog links the Walrus Memory
account object on Sui (/api/about exposes network, account id and explorer URLs — nothing
secret). Judges can click any memory and see the encrypted blob on mainnet.
Set TAVILY_API_KEY and the model gets one tool, web_search (src/search.ts).
It is instructed to use it only for current, local or factual questions (a race, a price, a
place) — never for coaching or habits — and to cite sources as [1], [2]. When the user pastes
a link, a second tool read_page (Tavily extract) lets the coach read that page and relate it
to what it remembers. Basic search = 1 credit, extract = 1 credit per 5 pages; keep Tavily's
"pay as you go" off and the free tier (1,000 credits/month) is plenty. The UI shows
"searched the web, N sources" with clickable chips. Search results are never stored as
memories; only facts about the user are. Without the key the coach says plainly when a
question needs information it doesn't have.
/privacy explains in plain language what the service is, that it is an AI and can be wrong,
that there are no cookies or accounts (only a memory key in localStorage), and exactly where
each kind of data goes (Groq, Walrus Memory relayer/Walrus, Tavily, Vercel logs). Both pages
carry a one-line disclaimer.
Memory that only answers is half the story; the coach also reaches out. In the chat
panel, "Daily nudge → Turn on" asks for notification permission and registers a Web Push
subscription. Once a day a Vercel Cron hits /api/cron/nudge, which:
Config: VAPID_PUBLIC_KEY, VAPID_PRIVATE_KEY, VAPID_SUBJECT (generate with
npx web-push generate-vapid-keys) and CRON_SECRET. Trigger manually with
curl -H "Authorization: Bearer $CRON_SECRET" https://<host>/api/cron/nudge.
memoryAvailable: false in the API).localStorage. When the memory list refreshes and a fact still
isn't on Walrus after 90 s, the browser resends it through /api/remember, which dedupes
(distance < 0.15) so late-landing writes never double up.Too Many Requests from its Sui RPC) are retried
with backoff and honour retry_after_seconds.wal_…) is an Ed25519 private key that owns their account. It stays
in the browser, signs the setup transactions locally, and is never sent to the server;
requests carry the account id, which is public. Legacy web-<uuid> keys are still
accepted and are sent in POST bodies only (never URLs) so they stay out of logs.Same pipeline, different adapter (src/telegram.ts). Set TELEGRAM_BOT_TOKEN
and run npm run telegram.
| Command | What it does |
|---|---|
/start | Greets you — and if it knows you, picks up where you left off |
/memories | Lists what the bot remembers about you (straight from Walrus) |
/remember <fact> | Stores a fact explicitly |
/memory on|off | Toggles long-term memory — off shows the "before" behaviour |
/reset | Clears short-term context only |
Requirements: Node.js ≥ 18.
git clone https://github.com/EdCryptoFi/walcoach.git
cd walcoach
npm install
cp .env.example .env
Fill in .env:
| Variable | Where to get it |
|---|---|
TELEGRAM_BOT_TOKEN | optional, Telegram → @BotFather → /newbot |
GROQ_API_KEY | https://console.groq.com (free tier) |
MEMWAL_PRIVATE_KEY, MEMWAL_ACCOUNT_ID | https://memory.walrus.xyz → create account → delegate key |
SUI_SPONSOR_KEY | a dedicated Sui wallet (bech32 suiprivkey1…) holding ~1 SUI, pays gas for user accounts, about 0.005 SUI each |
MEMWAL_PACKAGE_ID, MEMWAL_REGISTRY_ID | the Walrus Memory package and its shared AccountRegistry on mainnet |
DELEGATE_KEY_SEED | any 32 random bytes, openssl rand -hex 32. Each user's account gets its own delegate key derived from this, so the relayer can tell the accounts apart. Per-user accounts stay off without it, and changing it loses access to every account already created |
MEMWAL_SERVER_URL | https://relayer.memory.walrus.xyz (mainnet) or https://relayer-staging.memory.walrus.xyz (testnet) |
Verify credentials with a real write + recall round-trip:
npm run check
Run the website (http://localhost:3000):
npm run web # or: npm run web:dev (reload on change)
The API is stateless (the browser sends its short-term history; long-term memory is on
Walrus), so it runs as a single Vercel function (src/index.ts, named in vercel.json);
background
learning is kept alive with waitUntil. From the project folder:
vercel deploy --prod \
-e GROQ_API_KEY=... -e GROQ_MODEL=qwen/qwen3.8-27b \
-e MEMWAL_PRIVATE_KEY=... -e MEMWAL_ACCOUNT_ID=... \
-e MEMWAL_SERVER_URL=https://relayer.memory.walrus.xyz -e MEMWAL_NAMESPACE_PREFIX=coach \
-e SUI_SPONSOR_KEY=suiprivkey1... -e DELEGATE_KEY_SEED=$(openssl rand -hex 32)
Leave SUI_SPONSOR_KEY and DELEGATE_KEY_SEED out and the app still works: users fall back to the
shared project account, isolated by namespace, instead of owning one each.
(or set the same variables in the Vercel dashboard and run vercel deploy --prod).
Run the Telegram bot instead (long polling, no public URL needed):
npm run telegram
Usage evidence for the write-up (messages and facts stored per user):
npm run stats
npm run eval simulates 3 users × 2 sessions in an isolated namespace prefix:
session 1 shares facts, session 2 wipes short-term context and sends probes whose
good answer depends on remembering session 1. Every probe is answered with memory
OFF and ON and checked against keywords only a remembering bot could produce.
Full transcripts land in eval/report.md.
The relayer allows ~1000 weighted requests per account per hour; one eval run uses a good share of that, so run it at most once an hour or the writes start failing with 429.
src/app.ts The JSON API (Hono, stateless) shared by local server and Vercel
src/push.ts Web Push subscriptions (stored on Walrus) and the daily nudge job
src/areas.ts Life areas used to tag facts and drive badges
public/sw.js Service worker for push notifications
src/web.ts Local Node server: static page + API
public/index.html The chat UI (vanilla HTML/CSS/JS, light + dark)
src/telegram.ts Telegram adapter (optional)
src/index.ts Vercel entrypoint (re-exports the app)
src/memory.ts Walrus Memory SDK wrapper (per-user namespaces)
src/llm.ts Groq client and coach system prompt
src/extract.ts Fact extraction with our own model (JSON out)
src/chat.ts recall → generate → learn pipeline shared by bot and eval
src/stats.ts Local per-user counters (evidence only; Walrus is the source of truth)
scripts/check.ts Credential + round-trip check
scripts/stats.ts Prints the usage table
scripts/eval.ts Before/after evaluation with 3 simulated users
tsx)qwen/qwen3.8-27b via Groq's OpenAI-compatible API@mysten-incubation/memwal (Walrus + SEAL encryption + Sui ownership)MIT