{"id":50030010,"url":"https://github.com/bubustack/livekit-bridge-engram","last_synced_at":"2026-05-20T19:51:38.567Z","repository":{"id":352188430,"uuid":"1094017618","full_name":"bubustack/livekit-bridge-engram","owner":"bubustack","description":"LiveKit bridge Engram for bobrapet — real-time audio/data ingress and egress for streaming Stories.","archived":false,"fork":false,"pushed_at":"2026-05-02T07:11:05.000Z","size":233,"stargazers_count":0,"open_issues_count":8,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-02T09:18:38.961Z","etag":null,"topics":["audio","batch","bubustack","engram","go","kubernetes","livekit","realtime","streaming","webrtc"],"latest_commit_sha":null,"homepage":"https://bubustack.io/","language":"Go","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/bubustack.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":"SUPPORT.md","governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":["bubustack"]}},"created_at":"2025-11-11T06:23:53.000Z","updated_at":"2026-04-24T13:27:35.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/bubustack/livekit-bridge-engram","commit_stats":null,"previous_names":["bubustack/livekit-bridge-engram"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/bubustack/livekit-bridge-engram","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bubustack%2Flivekit-bridge-engram","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bubustack%2Flivekit-bridge-engram/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bubustack%2Flivekit-bridge-engram/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bubustack%2Flivekit-bridge-engram/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bubustack","download_url":"https://codeload.github.com/bubustack/livekit-bridge-engram/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bubustack%2Flivekit-bridge-engram/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33273409,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-20T15:12:43.734Z","status":"ssl_error","status_checked_at":"2026-05-20T15:12:42.300Z","response_time":356,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["audio","batch","bubustack","engram","go","kubernetes","livekit","realtime","streaming","webrtc"],"created_at":"2026-05-20T19:51:37.580Z","updated_at":"2026-05-20T19:51:38.561Z","avatar_url":"https://github.com/bubustack.png","language":"Go","funding_links":["https://github.com/sponsors/bubustack"],"categories":[],"sub_categories":[],"readme":"# 🎧 LiveKit Bridge Engram\n\nA streaming Engram that joins a LiveKit room, mirrors remote audio into the bobrapet story graph, and plays downstream responses back into the room. Pair it with the [`livekit-webhook-impulse`](../livekit-webhook-impulse) to build real-time voice assistants on top of LiveKit Cloud, LiveKit Cloud Sandbox, or self-hosted clusters.\n\n```\nLiveKit Room ⇄ LiveKit Bridge Engram ⇄ Transport (bobravoz-grpc) ⇄ Your realtime story\n```\n\n## 🌟 Highlights\n\n- Authenticates with LiveKit using server-side API keys.\n- Subscribes to remote participant audio tracks (with allowlist support) and emits native streaming `AudioFrame` messages with LiveKit metadata.\n- Publishes a PCM playback track so that LLM / TTS responses can be injected back into the room.\n- Bridges standard LiveKit room chat text streams on `lk.chat` by default, so the same Engram works with the normal room chat UI instead of requiring a custom topic.\n- Ignores any LiveKit participant whose identity matches the configured agent prefix (e.g., other bubu-agent instances) to prevent audio feedback loops.\n- Emits session lifecycle events (`livekit.session.started` / `ended`) so you can orchestrate additional steps.\n\n## 🚀 Quick Start\n\n```bash\nmake lint\ngo test ./...\nmake docker-build\n```\n\nApply `Engram.yaml`, wire the template into a realtime Story, and pass room/session\ncontext from `livekit-webhook-impulse` or your own trigger source.\n\n## ⚙️ Configuration (`Engram.spec.with`)\n\n| Field | Type | Description | Default |\n|-------|------|-------------|---------|\n| `livekitURL` | string | WSS/HTTPS URL for your LiveKit deployment. | *(required)* |\n| `agentIdentityPrefix` | string | Prefix used when auto-generating the bot's participant identity. | `bubu-agent` |\n| `playbackTrackName` | string | Name for the published playback track. | `agent-playback` |\n| `sourceAllowlist` | []string | Optional allowlist for participant identities (exact, `*`, `prefix*`). | accept all |\n| `capture.enabled` | bool | Enable participant audio capture and forwarding into the story pipeline. | `true` |\n| `capture.encoding` | string | PCM encoding advertised to LiveKit. | `pcm` |\n| `capture.sampleRate` | int | Sample rate for capture + playback. | `48000` |\n| `capture.channels` | int | Mono/Stereo selection. | `1` |\n| `playback.enabled` | bool | Enable published playback track and downstream audio playback. | `true` |\n| `chat.enabled` | bool | Enable forwarding LiveKit room chat messages into the story pipeline. | `false` |\n| `chat.topic` | string | Optional custom UserData topic. Leave empty to use standard LiveKit room chat text streams on `lk.chat`. | `lk.chat` |\n\n### 🔐 Secrets\n\nMap the template's secret to a Kubernetes secret that contains:\n\n```yaml\nstringData:\n  API_KEY: lk_api_key\n  API_SECRET: supersecret\n```\n\nThe template mounts these keys with the `LIVEKIT_` prefix, so the container sees\n`LIVEKIT_API_KEY` and `LIVEKIT_API_SECRET` while the Engram reads them as `API_KEY`\nand `API_SECRET` from the secret bundle.\n\n## 📥 Inputs\n\nBootstrap inputs are merged from three sources, in this order:\n\n1. static `spec.with` defaults\n2. runtime trigger context (`BUBU_TRIGGER_DATA`)\n3. first structured inbound stream message (if needed)\n\nLater sources override earlier values, so trigger/session data is not clobbered by static defaults.\n\nThe merged input shape is:\n\n```json\n{\n  \"room\": { \"name\": \"support-room\", \"sid\": \"RM_xxx\" },\n  \"participant\": { \"identity\": \"user-alice\", \"sid\": \"PA_xxx\" },\n  \"event\": { ... },\n  \"policy\": { ... },\n  \"agentIdentity\": \"(optional override)\"\n}\n```\n\nThe `livekit-webhook-impulse` already supplies this structure when you forward its payload into the LiveKit step.\n\n## 📤 Outputs\n\n- **Audio packets**: native `StreamMessage.Audio` frames (`PCM`, `SampleRateHz`, `Channels`, `Codec`) plus metadata keys such as `type=speech.audio.v1`, `room.*`, and `participant.*`.\n- **Chat packets**: JSON payload with `text`, `sender`, and optional `topic`, with metadata `type=chat.message.v1`. By default the bridge reads and writes standard LiveKit room chat text streams on `lk.chat`; nonstandard `chat.topic` values switch the bridge into custom UserData packet mode.\n- **Session events**: JSON payload with `type=livekit.session.started|ended` and matching metadata keys to help you bootstrap additional streaming steps.\n\n## 🔄 Runtime Notes\n\nSend JSON payloads back through the transport (e.g., from a TTS step) to control the agent:\n\n```json\n{\n  \"type\": \"speech.audio.v1\",\n  \"audio\": {\n    \"encoding\": \"pcm\",\n    \"sampleRate\": 48000,\n    \"channels\": 1,\n    \"data\": \"\u003cbase64 PCM chunk\u003e\"\n  }\n}\n```\n\n`type: \"stop\"` or `\"livekit.session.end\"` will gracefully disconnect the bot from the room.\n\n## 📘 Example Story\n\n```yaml\nsteps:\n  - name: ingress\n    ref: { name: livekit-bridge }\n    with:\n      livekitURL: wss://my-sandbox.livekit.cloud\n      playbackTrackName: assistant-playback\n    secrets:\n      livekit: livekit-credentials\n  - name: stt\n    ref: { name: whisper-stream }\n  - name: llm\n    ref: { name: openai-realtime }\n  - name: tts\n    ref: { name: tts-stream }\n```\n\nWire the impulse's policy `storyInputs.entryEngram` to this step so each LiveKit event spins up the correct pipeline.\n\n## 🧪 Local Development\n\n- `make lint` – Run the shared lint and static-analysis checks.\n- `go test ./...` – Run bridge tests in an environment with the required media dependencies.\n- `make docker-build` – Build the bridge image for local clusters.\n\n## 🤝 Community \u0026 Support\n\n- [Contributing](./CONTRIBUTING.md)\n- [Support](./SUPPORT.md)\n- [Security Policy](./SECURITY.md)\n- [Code of Conduct](./CODE_OF_CONDUCT.md)\n- [Discord](https://discord.gg/dysrB7D8H6)\n\n\n## 📄 License\n\nCopyright 2025 BubuStack.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbubustack%2Flivekit-bridge-engram","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbubustack%2Flivekit-bridge-engram","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbubustack%2Flivekit-bridge-engram/lists"}