{"id":17531135,"url":"https://github.com/milosgajdos/bot-banter","last_synced_at":"2025-07-22T00:33:32.319Z","repository":{"id":236118660,"uuid":"784837240","full_name":"milosgajdos/bot-banter","owner":"milosgajdos","description":"Go vs Rust AI bot voice conversation","archived":false,"fork":false,"pushed_at":"2025-03-30T03:24:42.000Z","size":95,"stargazers_count":29,"open_issues_count":0,"forks_count":4,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-11T15:21:07.470Z","etag":null,"topics":["bot","go","golang","llm","ollama","rust","rust-lang","tts"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/milosgajdos.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-04-10T16:48:38.000Z","updated_at":"2025-04-10T11:05:59.000Z","dependencies_parsed_at":"2024-12-08T22:04:43.221Z","dependency_job_id":"b9457065-bacb-4c01-9d85-88671ebd65a7","html_url":"https://github.com/milosgajdos/bot-banter","commit_stats":null,"previous_names":["milosgajdos/bot-banter"],"tags_count":0,"template":false,"template_full_name":"milosgajdos/go-repo-template","purl":"pkg:github/milosgajdos/bot-banter","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/milosgajdos%2Fbot-banter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/milosgajdos%2Fbot-banter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/milosgajdos%2Fbot-banter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/milosgajdos%2Fbot-banter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/milosgajdos","download_url":"https://codeload.github.com/milosgajdos/bot-banter/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/milosgajdos%2Fbot-banter/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266404943,"owners_count":23923497,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-21T11:47:31.412Z","response_time":64,"last_error":null,"robots_txt_status":null,"robots_txt_updated_at":null,"robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bot","go","golang","llm","ollama","rust","rust-lang","tts"],"created_at":"2024-10-20T17:22:58.595Z","updated_at":"2025-07-22T00:33:32.295Z","avatar_url":"https://github.com/milosgajdos.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# bot-banter\n\nThis is a PoC demonstrating how two bots can autonomously \"speak\" to each other using an [LLM](https://en.wikipedia.org/wiki/Large_language_model) and [TTS](https://simple.wikipedia.org/wiki/Text_to_speech).\nIt uses [NATS jetstream](https://docs.nats.io/nats-concepts/jetstream) for message routing, [ollama](https://ollama.com/) for generating text using an LLM of the user's choice and [playht](https://play.ht) API for TTS speech synthesis.\n\nRead the blog post which motivated this project https://cybernetist.com/2024/04/25/go-or-rust-just-listen-to-the-bots/\n\n[![Build Status](https://github.com/milosgajdos/bot-banter/workflows/CI/badge.svg)](https://github.com/milosgajdos/bot-banter/actions?query=workflow%3ACI)\n[![go.dev reference](https://img.shields.io/badge/go.dev-reference-007d9c?logo=go\u0026logoColor=white\u0026style=flat-square)](https://pkg.go.dev/github.com/milosgajdos/bot-banter)\n[![License: Apache-2.0](https://img.shields.io/badge/License-Apache--2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)\n\n\u003e [!IMPORTANT]\n\u003e This project was built purely for educational purposes and thus is likely ridden with bugs, inefficiencies, etc.\n\u003e You should consider this project as highly experimental.\n\nClick to watch/listen to a sample conversation:\n\n[![Bot Banter](http://img.youtube.com/vi/w01DsREeKU4/0.jpg)](http://www.youtube.com/watch?v=w01DsREeKU4)\n\n## Bot Conversation Flow\n\n```mermaid\nsequenceDiagram\n    participant GoTTS as TTS\n    participant GoLLM as LLM\n    participant Gobot\n    participant Rustbot\n    participant RustLLM as LLM\n    participant RustTTS as TTS\n    Gobot-\u003e\u003e+Rustbot: Hi Rustbot!\n    Rustbot-\u003e\u003eRustLLM: Hi Rustbot!\n    RustLLM-\u003e\u003eRustTTS: Hi Gobot!\n    RustLLM-\u003e\u003eRustbot: Hi Gobot!\n    Rustbot-\u003e\u003e-Gobot: Hi Gobot!\n    activate Gobot\n    Gobot-\u003e\u003eGoLLM: Hi Gobot!\n    GoLLM-\u003e\u003eGoTTS: Teach me about Rust!\n    GoLLM-\u003e\u003eGobot: Teach me about Rust!\n    Gobot-\u003e\u003e-Rustbot: Teach me about Rust!\n```\n\n## Architecture\n\nZoomed in view on the high-level architecture:\n\n```mermaid\nflowchart TB\n    subgraph \" \"\n        playht(PlayHT API)\n        ollama(Ollama)\n    end\n    bot \u003c--\u003eollama\n    bot \u003c--\u003eplayht\n    bot \u003c--\u003e NATS[[NATS JetStream]]\n```\n\n## Tasks, Goroutines, Channels\n\n\u003e [!NOTE]\n\u003e Mermaid does not have proper support for controlling layout or even basic graph legends\n\u003e There are some terrible workarounds, so I've opted not to use them in this README, hence\n\u003e the diagram might feel a bit unwieldy\n\n```mermaid\nflowchart TB\n    ollama{Ollama}\n    playht{PlayHT}\n    llm((llm))\n    tts((tts))\n    jetWriter((jetWriter))\n    jetReader((jetReader))\n    ttsChunks(ttsChunks)\n    jetChunks(jetChunks)\n    prompts(prompts)\n    ttsDone(ttsDone)\n    subgraph NATS JetStream\n        Go(go)\n        Rust(rust)\n    end\n    Go-- 1. --\u003ejetReader\n    jetWriter-- 7. --\u003eRust\n    jetReader-- 2. --\u003eprompts\n    prompts-- 3. --\u003ellm\n    llm--\u003eollama\n    llm-- 4. --\u003ettsChunks\n    llm-- 4. --\u003ejetChunks\n    jetChunks--\u003ejetWriter\n    ttsChunks--\u003etts\n    tts-- 5. --\u003eplayht\n    tts-- 6. --\u003ettsDone\n    ttsDone--\u003ejetWriter\n```\n\n1. `jet.Reader` receives a message published on a JetStream subject\n2. `jet.Reader` sends this message to the `prompts` channel\n3. `llm` worker reads the messages sent to the `prompts` channel and forwards them to ollama for LLM generation\n4. ollama generates the response and the `llm` worker sends it to both `ttsChunks` and `jetChunks` channels\n5. `tts` worker reads the message and sends the message to PlayHT API and streams the audio to the default audio device;\n6.  once the playback has finished `tts` worker notifies `jet.Writer` via the `ttsDone` channel that it's done playing audio\n6. `jet.Writer` receives the notification on the `ttsDone` channel and publishes the message it received on `jetChunks` channel\n     to a JetStream subject\n\n# HOWTO\n\nThere are a few prerequisites:\n* [nats](https://nats.io/)\n* [ollama](https://ollama.com/)\n* Create an account on [playht](https://play.ht/)\n* sound/audio libraries on some platforms e.g. Linux\n\n## Run NATS\n\nBoth bots use [nats](https://nats.io/) as their communication channel.\n\n### Homebrew\n\nInstall\n```shell\nbrew tap nats-io/nats-tools\nbrew install nats nats-server\n```\n\nRun:\n```shell\nnats-server -js\n```\n\n### Nix\n\n```shell\nnix-shell -p nats-server natscli\nnats-server -js\n```\n\n## Run Ollama\n\nDownload it from the [official site](https://ollama.com/) or see the Nix install below.\n\n### Nix\n\n```\nnix-shell -p ollama\n```\n\nRun a model you decide to use\n```shell\nollama run llama2\n```\n\n## Audio libraries\n\nIf you are running on Linux you need to install the following libraries -- assuming you want to play with the bot-speaking service\n\n\u003e [!NOTE]\n\u003e This is for Ubuntu Linux, other distros have likely different package names\n```shell\nsudo apt install -y --no-install-recommends libasound2-dev pkg-config\n```\n\n## playht API credentials\n\nOnce you've created an account on [playht](https://play.ht) you need to generate API keys.\nSee [here](https://docs.play.ht/reference/api-authentication) for more details.\n\nNow, you need to export them via the following environment variables which are read by the client libraries we use ([go-playht](https://github.com/milosgajdos/go-playht), [playht_rs](https://github.com/milosgajdos/playht_rs)):\n```shell\nexport PLAYHT_SECRET_KEY=XXXX\nexport PLAYHT_USER_ID=XXX\n```\n\n## Run the bots\n\n\u003e [!IMPORTANT]\n\u003e Once you've started `gobot` you need to prompt it.\n\u003e `gobot` reads prompt from `stdin` which kickstarts the conversation:\n\u003e `rusbot` waits for `gobot` before it responds!\n\nStart the `gobot`:\n```shell\ngo run ./gobot/...\n```\n\nStart the `rustbot`:\n```shell\ncargo run --manifest-path rustbot/Cargo.toml\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmilosgajdos%2Fbot-banter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmilosgajdos%2Fbot-banter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmilosgajdos%2Fbot-banter/lists"}