ๆƒฏๆ€ง่šๅˆ ้ซ˜ๆ•ˆ่ฟฝ่ธชๅ’Œ้˜…่ฏปไฝ ๆ„Ÿๅ…ด่ถฃ็š„ๅšๅฎขใ€ๆ–ฐ้—ปใ€็ง‘ๆŠ€่ต„่ฎฏ
้˜…่ฏปๅŽŸๆ–‡ ๅœจๆƒฏๆ€ง่šๅˆไธญๆ‰“ๅผ€

ๆŽจ่่ฎข้˜…ๆบ

cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
B
Blog RSS Feed
ๅฎ็މ็š„ๅˆ†ไบซ
ๅฎ็މ็š„ๅˆ†ไบซ
่…พ
่…พ่ฎฏCDC
ๅš
ๅšๅฎขๅ›ญ_้ฆ–้กต
T
Tailwind CSS Blog
ๆœˆๅ…‰ๅšๅฎข
ๆœˆๅ…‰ๅšๅฎข
ๅš
ๅšๅฎขๅ›ญ - ๅธๅพ’ๆญฃ็พŽ
ๅฅ‡ๅฎขSolidotโ€“ไผ ้€’ๆœ€ๆ–ฐ็ง‘ๆŠ€ๆƒ…ๆŠฅ
ๅฅ‡ๅฎขSolidotโ€“ไผ ้€’ๆœ€ๆ–ฐ็ง‘ๆŠ€ๆƒ…ๆŠฅ
M
MIT News - Artificial intelligence
A
About on SuperTechFans
ไบ‘้ฃŽ็š„ BLOG
ไบ‘้ฃŽ็š„ BLOG
้’›ๅช’ไฝ“๏ผšๅผ•้ข†ๆœชๆฅๅ•†ไธšไธŽ็”Ÿๆดปๆ–ฐ็Ÿฅ
้’›ๅช’ไฝ“๏ผšๅผ•้ข†ๆœชๆฅๅ•†ไธšไธŽ็”Ÿๆดปๆ–ฐ็Ÿฅ
ๆœ‰่ตžๆŠ€ๆœฏๅ›ข้˜Ÿ
ๆœ‰่ตžๆŠ€ๆœฏๅ›ข้˜Ÿ
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
ๅคง็Œซ็š„ๆ— ้™ๆธธๆˆ
ๅคง็Œซ็š„ๆ— ้™ๆธธๆˆ
MongoDB | Blog
MongoDB | Blog
ๅš
ๅšๅฎขๅ›ญ - ่‚ๅพฎไธœ
V
Visual Studio Blog
H
Hackread โ€“ Cybersecurity News, Data Breaches, AI and More
SecWiki News
SecWiki News
็พŽ
็พŽๅ›ขๆŠ€ๆœฏๅ›ข้˜Ÿ
P
Privacy International News Feed
H
Help Net Security
่ฎฉๅฐไบงๅ“็š„็‹ฌ็ซ‹ๅ˜็Žฐๆ›ด็ฎ€ๅ• - ezindie.com
่ฎฉๅฐไบงๅ“็š„็‹ฌ็ซ‹ๅ˜็Žฐๆ›ด็ฎ€ๅ• - ezindie.com
Microsoft Security Blog
Microsoft Security Blog
Know Your Adversary
Know Your Adversary
Y
Y Combinator Blog
D
DataBreaches.Net
Project Zero
Project Zero
T
The Blog of Author Tim Ferriss
Cyberwarzone
Cyberwarzone
C
Cybersecurity and Infrastructure Security Agency CISA
C
Cisco Blogs
S
Schneier on Security
G
GRAHAM CLULEY
ๅš
ๅšๅฎขๅ›ญ - ไธ‰็”Ÿ็ŸณไธŠ(FineUIๆŽงไปถ)
Cisco Talos Blog
Cisco Talos Blog
ๅฐไผ—่ฝฏไปถ
ๅฐไผ—่ฝฏไปถ
Forbes - Security
Forbes - Security
D
Docker
T
Tenable Blog
S
Secure Thoughts
้›ทๅณฐ็ฝ‘
้›ทๅณฐ็ฝ‘
S
Security @ Cisco Blogs
T
The Exploit Database - CXSecurity.com
The Cloudflare Blog
ๅš
ๅšๅฎขๅ›ญ - ใ€ๅฝ“่€็‰นใ€‘
Spread Privacy
Spread Privacy
้˜ฎไธ€ๅณฐ็š„็ฝ‘็ปœๆ—ฅๅฟ—
้˜ฎไธ€ๅณฐ็š„็ฝ‘็ปœๆ—ฅๅฟ—

Show HN

GitHub - steveking-gh/firmion: Firmion is DSL and engine for firmware image generation. GitHub - villagesql/villagesql-skills: Agent skills for VillageSQL - gemini-cli-extension; claude-code-plugin GitHub - 0gsd/enough: a personal language system for planning, writing, and translation. GitHub - flightdeckhq/flightdeck: Observability and control plane for AI agents. CSP Radar GitHub - Light-Heart-Labs/DreamServer: Turn your PC, Mac, or Linux box into an AI server. LLM inference, chat UI, voice, agents, workflows, RAG, and image generation. GitHub - Diplomat-ai/diplomat-agent-ts: What can your TypeScript AI agent do to the real world? Scan your code. See which tool calls have zero checks Code Block Selector - Visual Studio Marketplace Prometheus dependency graph โ€” interactive showcase | Riftmap Show HN: I made a vi-like modal keyboard plugin for Figma GitHub - run-llama/liteparse: A fast, helpful, and open-source document parser GitHub - dalemyers/Roar: A macOS CLI tool for notifications GitHub - district-solutions/open-agent-tools-coder: Enables small-to-large self-hosted ai models to use local source code when running tool-calling agentic workloads. We actively data mine 20,900+ (2+ TB) popular github repos using large and small ai models to create reuseable: json, markdown and parquet files for local-first tool-calling models. GitHub - progapandist/stripeek: A local TUI proxy for real-time Stripe API debugging, built for navigating complex payloads fast. GitHub - sir1st/hermes-desktop: All-in-one cross-platform desktop app for Hermes Agent โ€” bundles Python + hermes-agent + hermes-web-ui GitHub - astefanutti/shaderbang: Shebang for Shaders Show HN: Generate Claude Code Workflows using Spec Driven Development approach GitHub - nixys/nxs-universal-chart: The Helm chart you can use to install any of your applications into Kubernetes/OpenShift Show HN: AI agents for UK GDAD PCF roles and their skills The Two Pillars: Mixer Mode and Meta-Software in the Reorganization of Software Work After AI GitHub - JaiCode08/teleport-env What 1,000+ Harness Experiments Taught Me About Self-Improving Agents Show HN: Liiists, a Markdown-first, iOS and CLI list app SwiperTab โ€“ Get this Extension for ๐ŸฆŠ Firefox (en-US) GitHub - kouhxp/fftext: Summarize, explain, fact-check, or translate any text, URL, or file. No GPU. No cloud. One command GitHub - sweetpad-dev/sweetpad: Develop Swift/iOS projects using VSCode GitHub - dogmaticdev/IRON: IRON a.k.a. Intermediate Representation Object Notation is a Interpreter/Database that is used to create Programming Languages. GitHub - sjhalani7/vaen: Package your AI coding harness into a portable .agent file, and share it across repos, teams, & the community without ever having to copy-paste instructions, skills, MCP config, or secrets. Show HN: Gandalf the Grader Show HN: Citadeld โ€“ replay any CI failure locally from a single file GitHub - tdortman/cuSBF: High-Performance GPU Super Bloom Filter coral-ai/claude-code-token-xray at main ยท Coral-Bricks-AI/coral-ai GitHub - ulyssestenn/funes: Funes is a Git-based framework for LLM-managed knowledge work: an AI Librarian ingests raw sources, builds an interlinked Markdown knowledge base, and uses it to produce cited reports, analyses, and other outputs. GitHub - ThatXliner/gah: Git Add Hunk, built for agents to use GitHub - harmont-dev/harmont-cli: Command-line client for the Harmont CI platform GitHub - brooksmcmillin/mcp-authflow: OAuth 2.0 Authorization Server framework for MCP servers GitHub - javaid-codes/audit-supply-chain-agents GitHub - amorey/gochan: A small library of common channel architectures for Go, inspired by Rust GitHub - arifozgun/OpenGem: Free, Open-Source AI API Gateway with Gemini, OpenAI & Anthropic Compatibility in 1 file GitHub - Pranesh950/BioPetals: ๐ŸŒธ Run BIOxAI models at home, BitTorrent-style. Fine-tuning and inference up to 10x faster than offloading GitHub - cnguyen14/bounty-doctor: Diagnose a GitHub bounty issue before you waste hours: detects honeypot scam repos, AI-bot attempt swarms, and stale contests. Show HN: CoreMCP โ€“ MCP Server for On-Prem DBs Show HN: KittyHTML โ€“ Render HTML/CSS as an inline image in your terminal GitHub - bingud/filemat: Web-based file manager Show HN: TruthLens โ€“ Free multi-signal deepfake image detector GitHub - apexlocal-jz/claude-usage-tray: Windows system-tray app showing your Claude Code rate-limit usage at a glance. Zero deps, ~300 lines of PowerShell. Cross-IDE (works regardless of VS Code, Cursor, plain terminal). Release v0.1.2.1 ยท kouhxp/yapsnap GitHub - noopolis/moltnet: Self-hostable chat network for AI agents. Pre-built bridges for Claude Code, Codex, and the Claws. Rooms, DMs, history. No Slack bots, no Matrix, no glue code. GitHub - tamerh/enju: Coordinating Humans, AI Agents, and Compute as Peers on a Shared Workflow Graph Show HN: Continuity-auth โ€“ Respect-weighted rate limits for the open web GitHub - luml-ai/luml: AI lifecycle platform where engineers and agents track experiments, train models, and ship to production. GitHub - mrdanielcasper/CoreTex: A UNIX-inspired, biomimetic, flat-file AI harness and knowledge engine. GitHub - clemg/pierre-github: Pierre's diffs.com and trees.software for Github GitHub - lyriks-io/unspaghettit: Behavior-driven AI development without prompt spaghetti. GitHub - sofumel/claude-handoff-revive: Resume Claude Code work after rate/usage/context limits without replaying the prior transcript. Auto-saves at 90%/95% usage. Plugin-installable, 10 languages. GitHub - dotexorg/saferpc: Typed, end-to-end encrypted RPC over any bidirectional channel. GitHub - BeeZeeAgent/beezee: Agent harness orchestration Legato Next.js Boilerplate for Internal Tools ยท CoreUI GitHub - clark-labs-inc/clark-hash: Clark Hash, 32x smaller searchable sketches for embeddings GitHub - ZeroPointRepo/youtube-mcp: The fastest YouTube transcript + YouTube search MCP for AI agents. Try for free. Typing Mastery โ€” climb toward 100+ WPM, deliberately GitHub - Andebugulin/Awareen GitHub - fayzan123/claude-workflow-composer: Visual desktop app for composing multi-agent coding workflows. Drag agents, attach skills and MCPs, wire handoffs, export to .claude/ GitHub - harshaneel/humanize: Best static AI text humanizer. Two research-grounded skills that work in any LLM (Claude, ChatGPT, Gemini, Codex): humanize beats perplexity-based detectors, ai-check produces forensic scoring with evidence-quoted flags. Nine levers, 50+ peer-reviewed sources, 2024-2026 detection literature. GitHub - StackOneHQ/stack-nudge GitHub - nodes-app/swift-markdown-engine: A native AppKit Markdown editor for macOS, built on TextKit 2 and bridged to SwiftUI. We hardened an LLM agent. Each defense we added made it more exploitable. GitHub - alkait/WhatsKept: Agent-queryable WhatsApp history from an iOS backup โ€” a single Go binary. GitHub - octelium/cordium: Open-source, general-purpose sandbox platform for devs and AI agents that provides identity-based secure access to infrastructure without credentials. WAR.GOV/UFO Microfilm5 GitHub - scosman/videowright: Build animated explainer videos with your coding agent GitHub - dipankar/dscode: The code editor you can take apart. GitHub - zoharbabin/web-researcher-mcp: MCP server (Go) for AI assistants: web search, content extraction, academic/patent/news research. Multi-provider routing, 4-tier scraping, search lenses. Works with Claude, Cursor, and any MCP client. GitHub - ruvnet/RuView: ฯ€ RuView turns commodity WiFi signals into real-time spatial intelligence, vital sign monitoring, and presence detection โ€” all without a single pixel of video. GitHub - scanaislop/aislop: Catch the slop AI coding agents leave in your code: narrative comments, swallowed exceptions, as-any casts, dead code, oversized functions. 50+ rules across 7 languages (TypeScript, JavaScript, Python, Go, Rust, Ruby, PHP). Sub-second, deterministic, no LLM at runtime. MIT-licensed. GitHub - unprovable/OrchidMantis: Orchid Mantis โ€” standalone framework for Zero-Knowledge Proofs of eXploit (ZKPoX). GitHub - MarcellM01/TinySearch: Shrink the web for your local LLMs! GitHub - TangibleResearch/Halgorithem: A Algo designed to detect AI Hallucitions GitHub - DO-SAY-GO/freelang: I love freelang GitHub - CarpseDeam/Aura-IDE: An AI coding harness that shaped itself - Planner/Worker agents, repo awareness, surgical edits, validation, recovery, and safe diff approvals. GitHub - chojs23/concord: A feature-rich TUI client for Discord GitHub - tommyjepsen/awesome-ux-skills: UX & AI Product designs skills you can use today in Claude Code GitHub - aerf-spec/aerf: Agent Evidence Receipt Format (AERF) โ€” an open specification for tamper-evident, independently verifiable records of AI agent actions. GitHub - kklimuk/docx-cli: CLI for AI agents (Claude, Codex) to read, edit, and comment on .docx files with full format fidelity. GitHub - Jwrede/tokentoll: Catch LLM cost changes in code review. Infracost for LLM spend. GitHub - samchon/ttsc: A `typescript-go` toolchain for compiler-powered plugins and type-safe execution + 500x faster lint integrated into compiler GitHub - Higangssh/homebutler: ๐Ÿ  Manage your homelab from chat. Single binary, zero dependencies. GitHub - olalie/tapmap: See where your computer connects and what stands out on a live world map. GitHub - Diplomat-ai/diplomat-agent: What can your AI agent do to the real world? Scan your code. See which tool calls have zero checks GitHub - Bajusz15/beacon: Open-source agent for secure remote access, monitoring, and deploys across home-lab and self-hosted machines like Raspberry Pi, N100, or any Linux server. Open web based TTY or tunnel Home Assistant and other local services securely without opening ports. BigTech AI News - Chrome ๅบ”็”จๅ•†ๅบ— GitHub - vinhnx/VTCode: VT Code is an open-source coding agent with LLM-native code understanding and robust shell safety. Supports multiple LLM providers with automatic failover and efficient context management. GitHub - michaelaz774/decision-engine: A decision operating system for startup founders, powered by Claude Code. Synthesizes wisdom from 25+ legendary founders and investors into interactive AI-driven decision frameworks. GitHub - Chrilleweb/dotenv-diff: Validate environment variable usage in your codebase GitHub - Lumen-Labs/brainapi2: BrainAPI is a knowledge graphโ€“powered AI memory layer that transforms unstructured data into structured knowledge, enabling intelligent search, recommendations, and contextual memory for AI agents and applications. GitHub - familiar-software/familiar: Let AI watch you work. Familiar lets your AI update its memory, skills, and knowledge by watching your screen. GitHub - skorotkiewicz/rudo: A small, elegant dock for Wayland GitHub - muxshed/shed: One stream in, or many. Every destination, simultaneously. No cloud middleman, no per-channel fees, no limits. make sidebar/address bar rounded corner toggleable
GitHub - kouhxp/cheap-im: CPU-only voice agent approximating Thinking Machines' Interaction Models demo
mrkn1 ยท 2026-05-18 ยท via Show HN

cheap-im demo

๐Ÿ“บ Watch the demo on YouTube

A CPU-only voice agent that replicates the surface behaviors of Thinking Machines' Interaction Models demo (May 2026) โ€” real-time speech, vision-keyed proactivity, live translation, mid-conversation background tasks โ€” on a laptop, with off-the-shelf parts and minimal LLM calls.

The point isn't to match Thinking Machines' architecture. They trained a 276B MoE from scratch on continuous audio+video with 200ms micro-turns. This project glues commodity models together with a Python event loop and shows how close a careful harness can get on the four behaviors that demo highlighted. Speech and vision are local (Silero VAD, Kroko ASR, YOLO11 pose, Piper TTS); LLM calls go to DeepInfra (Llama-3.1-8B-Instruct-Turbo for the foreground, DeepSeek-V3.2 for structured background work). One CPU laptop, one process, one asyncio loop.

Status of this round

The four demo behaviors all run end to end on a real laptop with a real webcam and mic:

  1. Friend detection โ€” YOLO11-pose on the webcam emits person_count_changed; the registered watcher fires on the non-primary person.
  2. Live translation โ€” Silero VAD cuts phrase-sized chunks, Whisper-large-v3-turbo on DeepInfra translates them to English, Piper speaks each chunk interpreter-style over the user. Exit is automatic when the user speaks English on an end-of-turn pause.
  3. Slouch detection โ€” shoulderโ†’ear vector angle off vertical, debounced over three frames (1.5s) so a momentary lean doesn't fire.
  4. Search + chart with continued conversation โ€” the foreground says "let me find those for you" while a background worker calls Serper, then DeepSeek-V3.2 for a Chart.js spec. The user can interrupt and ask follow-ups while the chart renders in the browser.

Pass --no-cam to skip the camera and the YOLO load entirely; vision-keyed triggers stay in the table but don't fire automatically (VisionWorker.push_event still works for scripted demos). --no-audio runs from stdin without touching mic or TTS. --no-audio --no-cam together gives a headless pure-text session, which is what the integration tests use.

Architecture

flowchart TB
    O["<b>Orchestrator</b><br/>(Python, single process)<br/><br/>โ€ข event loop<br/>โ€ข triggers table<br/>โ€ข foreground queue<br/>โ€ข background queue<br/>โ€ข completed-tasks queue"]
    W["<b>Webcam</b><br/>YOLO11 pose<br/>@ 4 fps"]
    M["<b>Mic</b><br/>Silero + Kroko<br/>+ Whisper"]
    S["<b>Speaker</b><br/>Piper<br/>(VITS / onnx)"]
    N["<b>Network</b><br/>Llama + DeepSeek<br/>+ Serper"]
    B["<b>WebSocket</b><br/>Browser<br/>(Chart.js)"]

    O <--> W
    O <--> M
    O <--> S
    O <--> N
    O <--> B
Loading

The orchestrator runs a single asyncio loop. Three event sources feed it:

  1. Audio events from Silero VAD + Kroko ASR (normal mode) or Silero VAD + Whisper (translate mode): user_started_speaking, partial_transcript, user_finished_speaking, translation_chunk.
  2. Vision events from the YOLO worker: person_count_changed, pose_state_changed.
  3. Background completions from the worker that handles search and chart generation.

The triggers table is the central data structure. It is a list of registered behaviors that the orchestrator consults on every event. Entries are written by the foreground model in response to user instructions and read by the event loop. The orchestrator logs the table after every change, so you can watch the demo's "memory" grow over a session.

Stack

Local (CPU):

  • Silero VAD โ€” endpointing and barge-in gating
  • Kroko ASR via sherpa-onnx โ€” streaming speech-to-text
  • YOLO11-pose via ultralytics โ€” person + pose at 4 fps
  • Piper โ€” TTS (VITS via onnxruntime)
  • WebRTC AEC3 via livekit's Python bindings โ€” acoustic echo cancellation on the mic path, so speaker output doesn't self-barge mid-reply
  • sounddevice + soundfile for mic/speaker I/O and FLAC encoding of translate-mode audio uploads
  • opencv-python for webcam capture

Network APIs (DeepInfra by default, plus Serper):

  • meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo โ€” foreground "interaction" model
  • deepseek-ai/DeepSeek-V3.2 โ€” background reasoning / structured-output model
  • openai/whisper-large-v3-turbo โ€” translation, only invoked in translate mode
  • Serper โ€” web search

The three model calls go through DeepInfra's OpenAI-compatible /v1/openai/chat/completions and /v1/openai/audio/translations endpoints. The base URL is set in src/foreground.py and src/background.py; point them at any OpenAI-format provider (the real OpenAI, Together, Groq, Fireworks, a local vLLM/Ollama server, etc.) and supply matching model names. Cost numbers in this README assume DeepInfra's pricing.

Orchestrator core:

  • httpx for streaming SSE to/from the model endpoints
  • partial-json-parser for incremental extraction of the say field before the full response lands
  • python-dotenv for .env loading

Browser-side:

  • fastapi + uvicorn + websockets serve a single static HTML page that renders charts with Chart.js v4. Used only for behavior #4.

Why Piper for TTS

Earlier rounds used Chatterbox Turbo. Chatterbox sounds better but is comfortably slower than real-time on a single CPU core, which meant the first sentence of every assistant turn was bottlenecked on synthesis rather than on Llama's time-to-first-token. Piper runs the VITS-style synthesizer as an ONNX graph through onnxruntime โ€” no torch at synthesis time โ€” and produces audio at several times real-time on a single core. The cost is some prosody quality; the win is that time-to-first-audio drops by roughly an order of magnitude, which is the latency dimension that matters most for the demo. Piper also streams natively (sub-sentence audio chunks), so barge-in cancels within tens of ms instead of the seconds-per-sentence granularity the old sentence-by-sentence loop gave us.

Why WebRTC AEC

On headphones the mic only hears the user, and barge-in detection is straightforward: VAD says "speech", the orchestrator cancels TTS, the user takes over. On speakers, the mic also hears the assistant's own voice coming back from the speakers a few tens of milliseconds later. VAD can't tell that apart from a real interruption, so a naive setup self-barges on every reply โ€” the assistant cancels itself a second into its first sentence.

WebRTC AEC3 fixes this at the sample level. The TTS playback path tees its int16 PCM into a reference ring buffer (resampled to 16 kHz so it matches the mic rate); the mic loop, on every 10 ms block, hands the reference to process_reverse_stream and the mic to process_stream before VAD or ASR see anything. AEC3's adaptive filter learns the room's impulse response and subtracts the echo. After the filter converges (~0.5โ€“1.5 seconds of TTS), speaker bleed is suppressed by 20โ€“40 dB and VAD only fires on actual user speech.

The convergence window itself is handled separately: the orchestrator ignores user_started_speaking events during the first aec_convergence_ms (default 1200) of each TTS utterance, because the filter hasn't seen enough reference yet to be reliable. The UX cost is essentially zero โ€” nobody interrupts the opening of a reply that just started โ€” and it eliminates the otherwise-persistent opening-sentence self-cancellation.

The token-overlap heuristic in audio._looks_like_self_echo is kept as a backstop on ASR finals (for residual bleed during double-talk or when the platform's render-to-capture delay differs significantly from the configured aec_stream_delay_ms). With AEC active it almost never fires; the log line echo filter: dropping likely self-transcription (post-AEC residual) is your hint that something is misaligned.

If livekit isn't installed at runtime, AEC degrades to no-op with a logged warning and the behaviour matches the pre-AEC version (the token-overlap filter does what it can). Set CHEAPIM_AEC_ENABLED=0 to disable explicitly. Tune the render-to-capture delay with CHEAPIM_AEC_DELAY_MS if echo persists past the convergence window on your hardware (USB devices typically want 80โ€“150ms; bluetooth 200โ€“300ms).

YOLO model size and the fps budget

The default is yolo11n-pose.pt (nano) running at 4 fps, balanced for "feels real time" on a CPU laptop. End-to-end latency from a pose change to a trigger fire lands roughly in the 150โ€“300ms range on a modern laptop in practice (your hardware will vary): camera read is near-instant once buffer-draining is in play, inference is ~60โ€“100ms for n, and the rest is the asyncio hop into the orchestrator and TTS dispatch.

Earlier versions defaulted to yolo11x-pose.pt at 2 fps. That gave beautiful keypoints but a 2โ€“3 second perceived delay โ€” the bottleneck was camera buffering compounding with a slow capture interval, not model size. Both have been fixed (see the buffer-drain note in vision._run_loop), but n is still the right default: it leaves plenty of headroom for the loop to recover from a slow frame without falling behind. m is a good upgrade if your slouch angle jitters on n's noisier keypoints.

Override via env:

CHEAPIM_YOLO_MODEL=yolo11m-pose.pt    # slower, more stable keypoints
CHEAPIM_YOLO_MODEL=yolo11x-pose.pt    # slowest, very stable keypoints

If you switch to x on CPU, also drop VisionConfig.fps to 2.0 (in src/vision.py); the loop will silently fall behind otherwise and you'll see the lag come back.

Setup

Requires Python 3.11.

Built and tested on Linux. The dependencies are cross-platform (sounddevice, opencv-python, onnxruntime, ultralytics all ship macOS and Windows wheels) and nothing in the orchestrator is Linux-specific, so macOS and Windows should work โ€” but they haven't been exercised. The mic/speaker and webcam permission notes below cover the macOS and Linux cases; Windows users will need to adapt.

git clone <this repo>
cd cheap-im
uv venv && source .venv/bin/activate   # or your preferred venv tool
uv pip install -e .

cp .env.example .env
# fill in DEEPINFRA_API_KEY and SERPER_API_KEY

pyproject.toml pins torch and torchvision to PyTorch's CPU-only wheel index (download.pytorch.org/whl/cpu). The demo never uses CUDA; this keeps the install at ~250 MB instead of ~3 GB. (Piper doesn't use torch at all โ€” only Silero VAD does โ€” but torch is still a direct dep so the CPU-index pin applies.) If you're not using uv, install torch from the CPU index manually:

pip install torch torchvision --index-url https://download.pytorch.org/whl/cpu
pip install -e .

Kroko model weights

Download Banafo Kroko ASR weights for English (and any other languages you want) from the HuggingFace mirror. You need four files in one folder:

models/en/kroko_64l/
โ”œโ”€โ”€ encoder.int8.onnx
โ”œโ”€โ”€ decoder.int8.onnx
โ”œโ”€โ”€ joiner.int8.onnx
โ””โ”€โ”€ tokens.txt

Set CHEAPIM_KROKO_MODEL_DIR=./models/en/kroko_64l in your .env.

YOLO weights

ultralytics downloads pose weights on first use. No manual step required; the first cheap-im run with vision enabled will fetch yolo11n-pose.pt (~6 MB) into ultralytics' cache. If you want to pre-cache or use a different size, the model name is read from CHEAPIM_YOLO_MODEL (see above).

Piper voice

Piper ships a downloader. Pick a voice from the Piper voices list and run:

mkdir -p models/piper
python -m piper.download_voices --data-dir models/piper en_US-lessac-medium

That writes both en_US-lessac-medium.onnx and en_US-lessac-medium.onnx.json into models/piper/. Point the env at the .onnx file:

CHEAPIM_PIPER_MODEL_PATH=./models/piper/en_US-lessac-medium.onnx

The .onnx.json file must sit next to the .onnx; Piper reads it automatically. medium is a good default for laptop CPUs; high sounds better but is roughly 2ร— slower. Optional knobs:

  • CHEAPIM_PIPER_LENGTH_SCALE โ€” float; >1.0 slows speech, <1.0 speeds it up. Useful if a particular voice feels rushed.
  • CHEAPIM_PIPER_SPEAKER_ID โ€” int; only meaningful for multi-speaker voices (most en_US voices are single-speaker).

Browser

The orchestrator hosts the chart page itself. Open http://127.0.0.1:8765/ in a regular browser window before starting the demo. The orchestrator doesn't manage the browser lifecycle.

Microphone / speaker permissions

On macOS, grant terminal access to the microphone in System Settings โ†’ Privacy & Security. On Linux, ensure the user is in the audio group and that PulseAudio/PipeWire is running. List devices with python -m sounddevice and set CHEAPIM_AUDIO_DEVICE=<index> if the default doesn't work.

Webcam permissions

On macOS, grant terminal access to the camera in System Settings โ†’ Privacy & Security. On Linux, the user needs read access to /dev/video* (typically via the video group). If your machine has multiple cameras, set CHEAPIM_WEBCAM_INDEX=<index> โ€” OpenCV enumerates in the same order as v4l2-ctl --list-devices on Linux and system_profiler SPCameraDataType on macOS.

Running

Or, to skip mic/TTS and drive the orchestrator from stdin (useful for testing the chart pipeline without audio hardware):

cheap-im --no-audio --log-level=DEBUG

Then type the user's side of the conversation at the you> prompt.

To skip the webcam and YOLO model load (useful on a headless machine, in CI, or when iterating on non-vision behaviors):

Vision-keyed triggers still register and persist in the triggers table; they just don't fire from the camera. Tests and scripted demos can still push synthetic events via VisionWorker.push_event โ€” that path doesn't need a camera.

To watch what YOLO sees while the orchestrator runs โ€” bounding boxes, keypoints, which person is treated as primary, the live slouch angle, and the debounce streak counters โ€” pass --cam-debug:

An OpenCV window opens alongside the chart UI. Press q in the window to close it; the orchestrator keeps running headlessly (closing the preview should not be a way to silently disable triggers). This is the flag to reach for when "the model isn't firing the trigger I expected" โ€” the overlay shows the angle and streak counts that go into the decision. Incompatible with --no-cam.

The two flags compose. cheap-im --no-audio --no-cam runs a pure-text session with no hardware touched at all, which is the configuration the integration tests use.

Demo behaviors

1. Friend detection

User: Every time one of my friends enters the frame, say 'friend'.

The foreground model registers a new_person_in_frame visual watcher. The vision worker tracks a "primary" person (largest bounding box, assumed to be the user) and fires the watcher whenever a non-primary person appears in frame for at least two consecutive frames (~0.5s at 4 fps), subject to the trigger's cooldown.

2. Live translation

User: I'll speak in Hindi. Can you translate to English in real time?

The foreground model emits {"set_mode": {"mode": "translate"}} and the orchestrator flips the audio path. In translate mode, Silero VAD cuts the user's speech at phrase pauses (~400ms of silence) and end-of-turn pauses (~1400ms). Each chunk is sent to Whisper-large-v3-turbo on DeepInfra with task=translate, and the returned English text is spoken by Piper over the user's continued speech โ€” interpreter-style, without barge-in.

Exit is automatic: when Whisper detects a chunk as English and that chunk ended on a full end-of-turn pause, the orchestrator flips mode back to normal and routes the English text to the foreground as an ordinary user turn. The model replies however it wants. Whisper audio is metered in seconds and folded into the cost estimate alongside LLM tokens.

End-to-end latency from end-of-phrase to spoken English is dominated by Whisper round-trip; DeepInfra typically returns in under a second on warm calls, with cold-start spikes of a few seconds on the first chunk.

3. Slouching

User: Tell me when I start slouching.

The foreground model registers a slouch_sustained visual watcher. Slouch is detected from the angle of the shoulder-midpoint โ†’ ear-midpoint vector off vertical, on the primary person only. The state flips between upright and slouching after three consecutive frames (~0.75s at 4 fps) past threshold, so a momentary lean forward doesn't fire and a brief head-bob back doesn't bounce out.

4. Search + chart with continued conversation

User: What are typical human reaction times for auditory, visual, and tactile cues? Could you search?

The foreground model speaks "Let me find those for you" immediately and emits a delegate for search. The background worker runs Serper.

When the search returns, the result is buffered as a system note. The next user turn picks it up and Llama 8B speaks the answer from it.

User: Can you visualize them in a bar chart?

A second delegate, this time for chart. Background worker calls DeepSeek-V3.2 for a Chart.js spec, validates the JSON, pushes to the browser. Chart appears in the open browser window.

User (interrupting): In the meantime, why is auditory faster than visual?

The foreground handles this as an ordinary turn while the chart render completes asynchronously. No notification needed โ€” the chart just shows up in the browser when it's ready.

What this can't do

Things the harness cannot do, and which TM's architecture handles natively:

  • True mid-sentence interruption with learned timing on when to yield. The orchestrator does coarse-grained barge-in: when VAD detects new speech mid-TTS, it cancels the current Piper chunk and truncates the assistant turn in history to roughly what played. WebRTC AEC handles the speaker-bleed case (so the assistant doesn't cancel itself), but the model has no learned policy on whether to yield โ€” every detected user start cancels TTS unconditionally.
  • Backchanneling ("mhm", "right") during user speech.
  • Simultaneous speaking and listening at the token level. The harness cleanly separates these: while TTS plays, the mic is still listened to, but the system can't generate and listen at the same time.
  • Visual proactivity decisions that depend on subtle context (not just hardcoded events like "new person").
  • Sub-400ms turn-taking. Realistic floor here is 500โ€“1200ms on a laptop, dominated by DeepInfra time-to-first-token (Piper itself is fast enough not to be the bottleneck on most hardware).
  • Code-switching mid-utterance during translation.
  • Graceful "I got cut off after saying X" behavior. The orchestrator approximates this by truncating the assistant turn in history to match what was actually played through TTS, but it isn't learned โ€” the model isn't trained on cut-off transcripts.

Cost guard

The orchestrator tracks input/output tokens for every foreground and background call, plus seconds of audio sent to Whisper. The default cap is 100k tokens per session, set via CHEAPIM_TOKEN_CAP. When hit, a warning is logged and the demo continues; the goal is to make the cost claim verifiable from logs, not to enforce a hard limit. The token cap does not gate Whisper minutes.

A typical 5-minute demo run looks like:

  • ~10 foreground turns ร— ~300 input + ~100 output tokens โ†’ 3k input, 1k output Llama 8B tokens โ†’ ~$0.000090
  • ~2 background tasks (one search, one chart) ร— ~500 in + ~600 out โ†’ 1k input, 1.2k output DeepSeek-V3.2 tokens โ†’ ~$0.000716
  • Serper search: 1 call โ†’ $0.001
  • Translate mode (if used): ~$0.0002 per minute of audio

Total: well under a cent of inference for a non-translation demo, plus Serper; a 10-minute translation session adds about $0.002 on top.

File layout

/
โ”œโ”€โ”€ README.md
โ”œโ”€โ”€ SPEC.md                  the design doc this README implements
โ”œโ”€โ”€ pyproject.toml
โ”œโ”€โ”€ .env.example
โ”œโ”€โ”€ src/
โ”‚   โ”œโ”€โ”€ orchestrator.py      event loop, triggers table, queues
โ”‚   โ”œโ”€โ”€ foreground.py        DeepInfra Llama client, streaming JSON parsing
โ”‚   โ”œโ”€โ”€ background.py        DeepInfra DeepSeek client, search/chart tasks
โ”‚   โ”œโ”€โ”€ audio.py             Silero VAD + Kroko ASR + Whisper + Piper TTS + WebRTC AEC
โ”‚   โ”œโ”€โ”€ vision.py            YOLO11-pose @ 4 fps, person count + slouch
โ”‚   โ”œโ”€โ”€ modes.py             normal / translate mode state
โ”‚   โ”œโ”€โ”€ web/
โ”‚   โ”‚   โ”œโ”€โ”€ server.py        FastAPI + WS chart server
โ”‚   โ”‚   โ””โ”€โ”€ chart.html       Chart.js v4 renderer
โ”‚   โ””โ”€โ”€ prompts/
โ”‚       โ”œโ”€โ”€ foreground.txt   system prompt + output grammar
โ”‚       โ””โ”€โ”€ chart.txt        DeepSeek chart-gen prompt
โ”œโ”€โ”€ examples/
โ”‚   โ”œโ”€โ”€ README.md            how to write your own visual watcher
โ”‚   โ””โ”€โ”€ quorum_watcher.py    concrete extension sketch
โ””โ”€โ”€ tests/
    โ””โ”€โ”€ test_foreground_parsing.py

Testing

uv pip install -e ".[dev]"
pytest

The only dev dependency is pytest itself โ€” the streaming integration tests use plain asyncio.run() instead of pulling in pytest-asyncio. The tests cover the foreground JSON-parsing path (streaming-say-early, plain-text fallback, truncated streams, history trimming) and a mock-transport integration test that exercises the full streaming pipeline end-to-end.

License

MIT.