TinkerUp User Guide

How to use TinkerMem, TinkerMeet, and the unified dashboard.

v0.2ActiveProject-scoped

Overview

TinkerUp is a team-memory platform. Two modules work standalone or together:

💬
TinkerMem
Slack bot + Drive ingest. Builds a project-scoped memory graph with RAG over file content. Answers via /ask, @mention, web chat.
🎙️
TinkerMeet
Records meeting audio, transcribes, generates Minutes of Meeting (MoM). Posts to Slack optionally.
📁
Projects
Optional grouping. Assign Slack channels to a project; queries scope to that project — no cross-leakage.
💰
Cost Tracker
Centralized LLM usage table — every Bedrock and OpenAI call logged. Pie + bar charts in dashboard.

Listen → Capture → Decay → Act

ListenCaptureDecayAct

Bot listens to Slack + meetings, captures into the graph, decays outdated context automatically, and surfaces relevant memory on demand.

Quick Start

Choose your path
You don't need both modules. Pick what you need:
  1. Run only TinkerMeet (record + MoM, no memory)
    Start tinkermeet/backend + tinkermeet/frontend. Record audio in the browser, download or post MoM. No Slack or DB needed beyond what TinkerMeet ships.
  2. Run only TinkerMem (Slack memory, no meetings)
    Set up Slack app + Google Drive service account + Neon Postgres. Run cd tinkermem && docker compose up -d --build. Bot listens to allowed channels.
  3. Run combined (full team memory)
    Both modules + dashboard. TinkerMeet pushes MoM to TinkerMem; queries see Slack + meetings in one memory graph.

Module Choice

Pick by need, not by default. Each module is independent.

NeedModuleSetup
I want to record meetings and get auto MoMtinkermeetOpenAI key + Slack channel for posting (optional)
I want a Slack bot that remembers chat historytinkermemSlack app + Postgres + Bedrock
I want both, queried as one memorytinkermem + tinkermeetAll of the above + TINKERMEM_API_URL in tinkermeet
Just a dashboard for an existing setuptinkerdashPoint NEXT_PUBLIC_TINKERMEM_API_URL at running tinkermem

Slack Integration (TinkerMem)

TinkerMem connects to Slack via Socket Mode — outbound-only WebSocket. No public URL or inbound rules needed — runs fine in a private VPC.

What gets ingested

  • Every message in allowed channels (SLACK_CHANNEL_IDS env)
  • Google Drive links (auto-extracted via service account)
  • Slack file attachments (docx/pdf/xlsx/etc — needs files:read scope)
  • Emoji reactions on bot answers — used for feedback (👍/👎)

Setup steps

  1. Create a Slack app
    api.slack.com/apps → New App → From scratch → enable Socket Mode → generate app-level token.
  2. Add Bot Token Scopes
    app_mentions:read, channels:history, channels:read, chat:write, commands, files:read, users:read, reactions:read
  3. Register slash commands
    /ask, /backfill, /recall, /correct, /usage (placeholder URL is fine — Socket Mode skips it).
  4. Install + invite bot
    Install app to workspace, copy Bot Token (xoxb-) into .env. In channel: /invite @YourBot.
  5. Backfill existing history
    In the channel, run /backfill to pull entire history into memory.

Meeting Recording (TinkerMeet)

Record + transcribe + generate MoM in the browser.

  1. Start the meet UI
    cd tinkermeet/frontend && npm run dev. Open in browser, grant microphone permission.
  2. Record audio
    Click Record. Audio streams over WebSocket to backend → OpenAI gpt-4o-transcribe.
  3. Get auto-MoM
    When you stop recording, the bot sends transcript to Bedrock Haiku for MoM generation (decisions + action items + open questions).
  4. Optional: post to Slack
    Set SLACK_MOM_CHANNEL in tinkermeet/.env. MoM auto-posts after generation.
OpenAI cost reporting
Every transcription token is POSTed to tinkermem/api/usage if you set TINKERMEM_API_URL. See it in the Cost Tracker.

Projects & Scoping

Projects are optional groupings. By default everything is standalone (independent). Assigning a Slack channel to a project gives you scoped queries — no cross-project leakage.

Rules

  • Channel → project mapping is mutable. Reassigning affects future messages only.
  • Each raw_message records the project at INSERT time — immutable after.
  • Query with project_id → strict WHERE project_id = $X across all retrieval paths.
  • NULL project_id = standalone. Standalone messages do not appear in project-scoped queries.
Detach is not exposed
Once a message is tagged with a project, it cannot be moved or untagged. Reassign the channel — past messages keep their original project, future messages get the new one.

Manage projects

Go to /projects on the dashboard: create projects, assign Slack channels, see channel and message counts per project.

Memory Graph

Three tiers, each with confidence + temporal decay.

TierWhatHow it's built
EpisodicSpecific events: a message, a meeting segmentSummarizer loop (30 min) extracts events from raw messages
SemanticAbstract facts consolidated from multiple eventsEpisode detector (24h) clusters similar episodes
ProceduralRules / playbooks induced from repeated patternsMonthly consolidation; PEMS-scored for confidence

Why temporal decay matters

Each node has a confidence_scorethat decreases with age + conflicting newer context. Below threshold → filtered out of retrieval. Notion/Confluence don't have this — pages rot silently. Otter/Fireflies don't either — transcripts sit flat in folders.

File Extraction

Two ingestion paths, both end in file_chunks table for vector RAG.

Slack file uploads

Files dragged into a channel are downloaded via files.info + url_private_download (needs files:read scope). Supports docx, pdf, xlsx, html, md, jsx, and more.

Google Drive links

Drive URLs in chat are detected via regex, then content is exported via the Google Drive API. Requires sharing the file (or parent folder) with the service account email— the SA doesn't inherit creator permissions.

RAG flow

DetectExtractChunkEmbedIndex

Each chunk is prepended with metadata (uploader + file name) before embedding so queries like "what did Nita send?" match by author.

Slash Commands & Mention

CommandPurpose
/ask <question>Query team memory (scoped to project if channel is mapped)
@TinkerMem <question>Same as /ask but replies in thread
/backfillPull entire channel history into memory (one-shot per channel)
/recall [week|about <kw>]Show recent extracted memory nodes
/correct correct <id> "new content"Override a memory node
/correct reject <id>Reject a node (lower confidence)
/usage [today|week|month|all]Show centralized LLM cost report

Web Chat

Same query engine, different UI. Open /chat on the dashboard. Optionally enter a Channel ID to auto-resolve project scope.

When to use web vs Slack
Slack: quick check, in-context with team chat. Web: longer conversations, clearer history, no team channel noise. Both hit the same memory.

Cost Tracker

Open /costs for centralized LLM usage:

  • Pie chart — cost contribution per model
  • Bar chart — input vs output tokens per model
  • Breakdown table — provider, model, calls, tokens, cost
  • Period selector — today, 7d, 30d, all

Tinkermem logs internally; TinkerMeet POSTs to tinkermem/api/usage after each OpenAI/Bedrock call.

Quick Reference

Ports

ServicePort
tinkermem8080 (Slack bot + chat + usage + projects API)
tinkermeet/backend8000 (FastAPI WebSocket + REST)
tinkerdash3000 (Next.js dashboard)
tinkermeet/frontend3000 (use different port if running with tinkerdash)

Routes

RoutePurpose
/Overview dashboard
/chatChat with TinkerMem
/projectsCreate + manage projects
/sessionsMeeting sessions from TinkerMeet
/memoryMemory graph viewer
/costsLLM cost tracker
/settingsSettings
/usageThis guide

Common gotchas

docker compose restart doesn't reload .env
Use docker compose up -d --build after env changes. restart just sends a signal — env stays cached.
Slack files:read scope required for downloads
Without it, file downloads silently return Slack's login HTML — looks like a file but isn't. Detected via BadZipFile on docx parse.
Service account ≠ your Google account
Files must be explicitly sharedwith the SA email. Creating the SA in your project doesn't grant access to your files.
Slash commands collide across apps
If two installed Slack apps both register /ask, only the first-installed wins. Uninstall the other or rename commands.