[{"data":1,"prerenderedAt":1052},["ShallowReactive",2],{"page:\u002Farticles\u002Fintroducing-recallwhisper":3},{"id":4,"title":5,"author":6,"body":10,"cover":1039,"date":1040,"description":1041,"extension":1042,"head":1043,"layout":1046,"meta":1047,"navigation":445,"path":1048,"seo":1049,"stem":1050,"__hash__":1051},"pages\u002Farticles\u002F8.introducing-recallwhisper.md","Introducing RecallWhisper",{"name":7,"avatarUrl":8,"link":9},"Likun Cai","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F103620968?v=4","https:\u002F\u002Fgithub.com\u002FAlchemist-Aloha",{"type":11,"value":12,"toc":1021},"minimark",[13,18,22,25,28,33,36,47,50,53,75,79,84,95,141,144,148,168,175,179,182,185,189,192,196,203,207,210,216,219,223,236,267,276,279,367,380,391,395,414,417,472,483,709,712,731,753,767,771,781,821,829,835,839,842,936,942,946,1007,1011,1014,1017],[14,15,17],"h1",{"id":16},"introducing-recallwhisper-private-speech-local-memory","Introducing RecallWhisper: Private Speech, Local Memory",[19,20,21],"p",{},"Important thoughts rarely arrive when it is convenient to write them down. They appear during a walk, in a conversation, or halfway through another task. RecallWhisper is an Android app designed to capture those moments, turn speech into searchable text, and create useful summaries without handing long-term control of your personal archive to a cloud platform.",[19,23,24],{},"The app records through a native Android foreground service, detects conversational pauses with Silero VAD, and stores its durable data on the phone. Audio files are encrypted with AES-256-GCM, with their keys protected by Android Keystore. Transcripts, summaries, processing state, and raw API responses are kept in the app's local Room database.",[19,26,27],{},"RecallWhisper still needs transcription and summarization models, but it talks directly to OpenAI-compatible APIs. You can use compatible hosted services or run both APIs on hardware you control. This guide introduces the normal app workflow and then builds a private processing stack with OpenASR, X-ASR, llama.cpp, and Qwen3.5.",[29,30,32],"h2",{"id":31},"how-recallwhisper-works","How RecallWhisper works",[19,34,35],{},"The processing flow is deliberately simple:",[37,38,44],"pre",{"className":39,"code":41,"language":42,"meta":43},[40],"language-text","Microphone → encrypted local WAV → transcription API\n           → local raw transcript → summarization API\n           → local summary\u002Fsearch\u002Fexport\n","text","",[45,46,41],"code",{"__ignoreMap":43},[19,48,49],{},"The phone remains the permanent home of the recording and its results. The configured transcription server receives audio for speech recognition, while the summarization server receives transcript text. When both servers are self-hosted, the entire workflow can remain on infrastructure you control.",[19,51,52],{},"Key features include:",[54,55,56,60,63,66,69,72],"ul",{},[57,58,59],"li",{},"A native Kotlin foreground recorder and Android Quick Settings tile",[57,61,62],{},"Silero voice activity detection with a configurable 5–60 second pause tolerance",[57,64,65],{},"Separate API URLs, bearer tokens, and model IDs for transcription and summarization",[57,67,68],{},"Wi-Fi-only processing by default, with optional cellular processing",[57,70,71],{},"Local audio playback, transcript search, deletion, and JSON export",[57,73,74],{},"An API playground for model discovery, prompt editing, parameter tuning, and diagnostics",[29,76,78],{"id":77},"using-the-app","Using the app",[80,81,83],"h3",{"id":82},"_1-install-recallwhisper","1. Install RecallWhisper",[19,85,86,87,94],{},"Visit the ",[88,89,93],"a",{"href":90,"rel":91},"https:\u002F\u002Fgithub.com\u002FAlchemist-Aloha\u002FRecallWhisper",[92],"nofollow","RecallWhisper repository"," for the current source and project downloads. To build the Android APK yourself, install Flutter and run:",[37,96,100],{"className":97,"code":98,"language":99,"meta":43,"style":43},"language-sh shiki shiki-themes github-light github-dark","flutter analyze\nflutter test\nflutter build apk --release --split-per-abi\n","sh",[45,101,102,115,123],{"__ignoreMap":43},[103,104,107,111],"span",{"class":105,"line":106},"line",1,[103,108,110],{"class":109},"sScJk","flutter",[103,112,114],{"class":113},"sZZnC"," analyze\n",[103,116,118,120],{"class":105,"line":117},2,[103,119,110],{"class":109},[103,121,122],{"class":113}," test\n",[103,124,126,128,131,134,138],{"class":105,"line":125},3,[103,127,110],{"class":109},[103,129,130],{"class":113}," build",[103,132,133],{"class":113}," apk",[103,135,137],{"class":136},"sj4cs"," --release",[103,139,140],{"class":136}," --split-per-abi\n",[19,142,143],{},"The split build produces separate APKs for Android CPU architectures, allowing you to install the smaller artifact that matches your device.",[80,145,147],{"id":146},"_2-connect-the-processing-apis","2. Connect the processing APIs",[19,149,150,151,155,156,159,160,163,164,167],{},"Open ",[152,153,154],"strong",{},"Settings"," and configure the transcription and summarization services separately. Each base URL must include ",[45,157,158],{},"\u002Fv1",", but should not include a final endpoint such as ",[45,161,162],{},"\u002Faudio\u002Ftranscriptions"," or ",[45,165,166],{},"\u002Fchat\u002Fcompletions","; RecallWhisper adds that route itself.",[19,169,170,171,174],{},"HTTPS is required by default. ",[152,172,173],{},"Allow insecure HTTP"," is available for a controlled development network, but enabling it sends audio and bearer tokens across the network without encryption. It should never be used on public or untrusted networks.",[80,176,178],{"id":177},"_3-record-naturally","3. Record naturally",[19,180,181],{},"Start the recorder in RecallWhisper or from its Quick Settings tile. The foreground service keeps capture active while you use other apps. Silero VAD separates speech from silence, and the conversation pause setting controls how long RecallWhisper waits before closing the current segment.",[19,183,184],{},"A short pause tolerance creates smaller, faster segments. A longer tolerance is useful when a conversation contains natural gaps and should remain grouped together.",[80,186,188],{"id":187},"_4-let-the-phone-process-recordings","4. Let the phone process recordings",[19,190,191],{},"RecallWhisper queues each completed segment for transcription and then summarization. Processing uses Wi-Fi by default; cellular access must be enabled explicitly. The local processing state makes it possible to see whether a segment is queued, being processed, completed, or needs attention.",[80,193,195],{"id":194},"_5-review-and-manage-your-memory","5. Review and manage your memory",[19,197,198,199,202],{},"Use the app to play the encrypted local recording, read its transcript and summary, search transcript text, or delete material you no longer need. ",[152,200,201],{},"Export all data as JSON"," opens Android's document picker and writes metadata, raw transcription results, transcripts, summaries, checksums, and processing state to a file you choose. Audio stays separately encrypted in the app's private storage.",[29,204,206],{"id":205},"build-a-self-hosted-processing-stack","Build a self-hosted processing stack",[19,208,209],{},"The reference setup uses one specialized service for each job:",[37,211,214],{"className":212,"code":213,"language":42,"meta":43},[40],"RecallWhisper\n  ├─ \u002Fv1\u002Faudio\u002Ftranscriptions → OpenASR + X-ASR zh\u002Fen\n  └─ \u002Fv1\u002Fchat\u002Fcompletions     → llama.cpp + Qwen3.5 4B GGUF\n",[45,215,213],{"__ignoreMap":43},[19,217,218],{},"Keeping the services separate lets you choose the best speech model and language model independently. It also explains why RecallWhisper has two sets of URLs, tokens, and model names.",[80,220,222],{"id":221},"_1-start-openasr-with-x-asr-zhen","1. Start OpenASR with X-ASR zh\u002Fen",[19,224,225,226,229,230,235],{},"Install the current ",[45,227,228],{},"openasr"," binary from the ",[88,231,234],{"href":232,"rel":233},"https:\u002F\u002Fgithub.com\u002FQuintinShaw\u002Fopenasr\u002Freleases",[92],"OpenASR releases",", then download the recommended Q8 bilingual model:",[37,237,239],{"className":97,"code":238,"language":99,"meta":43,"style":43},"openasr pull xasr-zh-en:q8\nopenasr transcribe sample.wav --model xasr-zh-en\n",[45,240,241,251],{"__ignoreMap":43},[103,242,243,245,248],{"class":105,"line":106},[103,244,228],{"class":109},[103,246,247],{"class":113}," pull",[103,249,250],{"class":113}," xasr-zh-en:q8\n",[103,252,253,255,258,261,264],{"class":105,"line":117},[103,254,228],{"class":109},[103,256,257],{"class":113}," transcribe",[103,259,260],{"class":113}," sample.wav",[103,262,263],{"class":136}," --model",[103,265,266],{"class":113}," xasr-zh-en\n",[19,268,269,270,275],{},"The ",[88,271,274],{"href":272,"rel":273},"https:\u002F\u002Fhuggingface.co\u002FOpenASR\u002Fxasr-zh-en",[92],"X-ASR model card"," also provides FP16 and Q4 variants. Q8 is a practical default; choose Q4 when memory is limited.",[19,277,278],{},"Create a bearer token and start the service on port 9099:",[37,280,282],{"className":97,"code":281,"language":99,"meta":43,"style":43},"openasr apikey create --name recallwhisper\nexport OPENASR_TOKEN='replace-with-the-created-token'\nopenasr serve --help\nopenasr serve \\\n  --addr 127.0.0.1:9099 \\\n  --model xasr-zh-en \\\n  --pairing-admin-token-env OPENASR_TOKEN\n",[45,283,284,300,316,326,336,347,358],{"__ignoreMap":43},[103,285,286,288,291,294,297],{"class":105,"line":106},[103,287,228],{"class":109},[103,289,290],{"class":113}," apikey",[103,292,293],{"class":113}," create",[103,295,296],{"class":136}," --name",[103,298,299],{"class":113}," recallwhisper\n",[103,301,302,306,310,313],{"class":105,"line":117},[103,303,305],{"class":304},"szBVR","export",[103,307,309],{"class":308},"sVt8B"," OPENASR_TOKEN",[103,311,312],{"class":304},"=",[103,314,315],{"class":113},"'replace-with-the-created-token'\n",[103,317,318,320,323],{"class":105,"line":125},[103,319,228],{"class":109},[103,321,322],{"class":113}," serve",[103,324,325],{"class":136}," --help\n",[103,327,329,331,333],{"class":105,"line":328},4,[103,330,228],{"class":109},[103,332,322],{"class":113},[103,334,335],{"class":136}," \\\n",[103,337,339,342,345],{"class":105,"line":338},5,[103,340,341],{"class":136},"  --addr",[103,343,344],{"class":113}," 127.0.0.1:9099",[103,346,335],{"class":136},[103,348,350,353,356],{"class":105,"line":349},6,[103,351,352],{"class":136},"  --model",[103,354,355],{"class":113}," xasr-zh-en",[103,357,335],{"class":136},[103,359,361,364],{"class":105,"line":360},7,[103,362,363],{"class":136},"  --pairing-admin-token-env",[103,365,366],{"class":113}," OPENASR_TOKEN\n",[19,368,369,370,373,374,379],{},"Save the generated API key: it becomes the transcription token in RecallWhisper. Binding to ",[45,371,372],{},"127.0.0.1"," keeps the plain HTTP service private on the host while a reverse proxy provides HTTPS. If OpenASR runs on a different machine from the proxy, follow the ",[88,375,378],{"href":376,"rel":377},"https:\u002F\u002Fopenasr.org\u002Fdocs\u002Fserver\u002F",[92],"OpenASR server documentation"," for authenticated remote serving and TLS pairing.",[19,381,382,383,386,387,390],{},"OpenASR exposes the OpenAI-compatible ",[45,384,385],{},"\u002Fv1\u002Fmodels"," and ",[45,388,389],{},"\u002Fv1\u002Faudio\u002Ftranscriptions"," routes used by the app.",[80,392,394],{"id":393},"_2-start-llamacpp-with-qwen35-4b","2. Start llama.cpp with Qwen3.5 4B",[19,396,397,398,403,404,407,408,413],{},"The official ",[88,399,402],{"href":400,"rel":401},"https:\u002F\u002Fhuggingface.co\u002FQwen\u002FQwen3.5-4B",[92],"Qwen3.5 4B model"," does not include GGUF files. This example uses the 2.74 GB ",[45,405,406],{},"Q4_K_M"," quantization from the ",[88,409,412],{"href":410,"rel":411},"https:\u002F\u002Fhuggingface.co\u002Funsloth\u002FQwen3.5-4B-GGUF",[92],"Unsloth Qwen3.5-4B GGUF repository",".",[19,415,416],{},"Create a working directory and download the model:",[37,418,420],{"className":97,"code":419,"language":99,"meta":43,"style":43},"mkdir -p recallwhisper-llm\u002Fmodels\ncd recallwhisper-llm\n\ncurl -fL \\\n  'https:\u002F\u002Fhuggingface.co\u002Funsloth\u002FQwen3.5-4B-GGUF\u002Fresolve\u002Fmain\u002FQwen3.5-4B-Q4_K_M.gguf?download=true' \\\n  -o models\u002FQwen3.5-4B-Q4_K_M.gguf\n",[45,421,422,433,441,447,457,464],{"__ignoreMap":43},[103,423,424,427,430],{"class":105,"line":106},[103,425,426],{"class":109},"mkdir",[103,428,429],{"class":136}," -p",[103,431,432],{"class":113}," recallwhisper-llm\u002Fmodels\n",[103,434,435,438],{"class":105,"line":117},[103,436,437],{"class":136},"cd",[103,439,440],{"class":113}," recallwhisper-llm\n",[103,442,443],{"class":105,"line":125},[103,444,446],{"emptyLinePlaceholder":445},true,"\n",[103,448,449,452,455],{"class":105,"line":328},[103,450,451],{"class":109},"curl",[103,453,454],{"class":136}," -fL",[103,456,335],{"class":136},[103,458,459,462],{"class":105,"line":338},[103,460,461],{"class":113},"  'https:\u002F\u002Fhuggingface.co\u002Funsloth\u002FQwen3.5-4B-GGUF\u002Fresolve\u002Fmain\u002FQwen3.5-4B-Q4_K_M.gguf?download=true'",[103,463,335],{"class":136},[103,465,466,469],{"class":105,"line":349},[103,467,468],{"class":136},"  -o",[103,470,471],{"class":113}," models\u002FQwen3.5-4B-Q4_K_M.gguf\n",[19,473,474,475,478,479,482],{},"Create ",[45,476,477],{},"compose.yaml",", replacing ",[45,480,481],{},"\u003CSET_YOUR_LLAMA_API_KEY>"," with a strong, unique value:",[37,484,488],{"className":485,"code":486,"language":487,"meta":43,"style":43},"language-yaml shiki shiki-themes github-light github-dark","services:\n  llama:\n    image: ghcr.io\u002Fggml-org\u002Fllama.cpp:server\n    # NVIDIA: ghcr.io\u002Fggml-org\u002Fllama.cpp:server-cuda\n    # AMD\u002FIntel: ghcr.io\u002Fggml-org\u002Fllama.cpp:server-vulkan\n    restart: unless-stopped\n    ports:\n      - \"127.0.0.1:8181:8080\"\n    volumes:\n      - .\u002Fmodels:\u002Fmodels:ro\n    environment:\n      LLAMA_API_KEY: \u003CSET_YOUR_LLAMA_API_KEY>\n    command:\n      - --model\n      - \u002Fmodels\u002FQwen3.5-4B-Q4_K_M.gguf\n      - --alias\n      - qwen3.5-4b\n      - --host\n      - 0.0.0.0\n      - --port\n      - \"8080\"\n      - --ctx-size\n      - \"16384\"\n      - --parallel\n      - \"1\"\n      - --reasoning\n      - \"off\"\n","yaml",[45,489,490,499,506,517,523,528,538,545,554,562,570,578,589,597,605,613,621,629,637,645,653,661,669,677,685,693,701],{"__ignoreMap":43},[103,491,492,496],{"class":105,"line":106},[103,493,495],{"class":494},"s9eBZ","services",[103,497,498],{"class":308},":\n",[103,500,501,504],{"class":105,"line":117},[103,502,503],{"class":494},"  llama",[103,505,498],{"class":308},[103,507,508,511,514],{"class":105,"line":125},[103,509,510],{"class":494},"    image",[103,512,513],{"class":308},": ",[103,515,516],{"class":113},"ghcr.io\u002Fggml-org\u002Fllama.cpp:server\n",[103,518,519],{"class":105,"line":328},[103,520,522],{"class":521},"sJ8bj","    # NVIDIA: ghcr.io\u002Fggml-org\u002Fllama.cpp:server-cuda\n",[103,524,525],{"class":105,"line":338},[103,526,527],{"class":521},"    # AMD\u002FIntel: ghcr.io\u002Fggml-org\u002Fllama.cpp:server-vulkan\n",[103,529,530,533,535],{"class":105,"line":349},[103,531,532],{"class":494},"    restart",[103,534,513],{"class":308},[103,536,537],{"class":113},"unless-stopped\n",[103,539,540,543],{"class":105,"line":360},[103,541,542],{"class":494},"    ports",[103,544,498],{"class":308},[103,546,548,551],{"class":105,"line":547},8,[103,549,550],{"class":308},"      - ",[103,552,553],{"class":113},"\"127.0.0.1:8181:8080\"\n",[103,555,557,560],{"class":105,"line":556},9,[103,558,559],{"class":494},"    volumes",[103,561,498],{"class":308},[103,563,565,567],{"class":105,"line":564},10,[103,566,550],{"class":308},[103,568,569],{"class":113},".\u002Fmodels:\u002Fmodels:ro\n",[103,571,573,576],{"class":105,"line":572},11,[103,574,575],{"class":494},"    environment",[103,577,498],{"class":308},[103,579,581,584,586],{"class":105,"line":580},12,[103,582,583],{"class":494},"      LLAMA_API_KEY",[103,585,513],{"class":308},[103,587,588],{"class":113},"\u003CSET_YOUR_LLAMA_API_KEY>\n",[103,590,592,595],{"class":105,"line":591},13,[103,593,594],{"class":494},"    command",[103,596,498],{"class":308},[103,598,600,602],{"class":105,"line":599},14,[103,601,550],{"class":308},[103,603,604],{"class":113},"--model\n",[103,606,608,610],{"class":105,"line":607},15,[103,609,550],{"class":308},[103,611,612],{"class":113},"\u002Fmodels\u002FQwen3.5-4B-Q4_K_M.gguf\n",[103,614,616,618],{"class":105,"line":615},16,[103,617,550],{"class":308},[103,619,620],{"class":113},"--alias\n",[103,622,624,626],{"class":105,"line":623},17,[103,625,550],{"class":308},[103,627,628],{"class":113},"qwen3.5-4b\n",[103,630,632,634],{"class":105,"line":631},18,[103,633,550],{"class":308},[103,635,636],{"class":113},"--host\n",[103,638,640,642],{"class":105,"line":639},19,[103,641,550],{"class":308},[103,643,644],{"class":136},"0.0.0.0\n",[103,646,648,650],{"class":105,"line":647},20,[103,649,550],{"class":308},[103,651,652],{"class":113},"--port\n",[103,654,656,658],{"class":105,"line":655},21,[103,657,550],{"class":308},[103,659,660],{"class":113},"\"8080\"\n",[103,662,664,666],{"class":105,"line":663},22,[103,665,550],{"class":308},[103,667,668],{"class":113},"--ctx-size\n",[103,670,672,674],{"class":105,"line":671},23,[103,673,550],{"class":308},[103,675,676],{"class":113},"\"16384\"\n",[103,678,680,682],{"class":105,"line":679},24,[103,681,550],{"class":308},[103,683,684],{"class":113},"--parallel\n",[103,686,688,690],{"class":105,"line":687},25,[103,689,550],{"class":308},[103,691,692],{"class":113},"\"1\"\n",[103,694,696,698],{"class":105,"line":695},26,[103,697,550],{"class":308},[103,699,700],{"class":113},"--reasoning\n",[103,702,704,706],{"class":105,"line":703},27,[103,705,550],{"class":308},[103,707,708],{"class":113},"\"off\"\n",[19,710,711],{},"Start the container:",[37,713,715],{"className":97,"code":714,"language":99,"meta":43,"style":43},"docker compose up -d\n",[45,716,717],{"__ignoreMap":43},[103,718,719,722,725,728],{"class":105,"line":106},[103,720,721],{"class":109},"docker",[103,723,724],{"class":113}," compose",[103,726,727],{"class":113}," up",[103,729,730],{"class":136}," -d\n",[19,732,733,734,737,738,741,742,744,745,748,749,752],{},"The host listens only on ",[45,735,736],{},"127.0.0.1:8181","; port 8080 remains internal to the container. The ",[45,739,740],{},"--alias"," value becomes the model ID returned by ",[45,743,385],{},", and ",[45,746,747],{},"--reasoning off"," ensures that RecallWhisper receives final summary text in ",[45,750,751],{},"choices[0].message.content"," instead of only a reasoning field.",[19,754,397,755,760,761,766],{},[88,756,759],{"href":757,"rel":758},"https:\u002F\u002Fgithub.com\u002Fggml-org\u002Fllama.cpp\u002Fblob\u002Fmaster\u002Fdocs\u002Fdocker.md",[92],"llama.cpp Docker guide"," covers the available server images. See the ",[88,762,765],{"href":763,"rel":764},"https:\u002F\u002Fgithub.com\u002Fggml-org\u002Fllama.cpp\u002Fblob\u002Fmaster\u002Ftools\u002Fserver\u002FREADME.md",[92],"llama.cpp server reference"," when you need GPU offload, TLS, a larger context, or more concurrent requests.",[80,768,770],{"id":769},"_3-put-both-apis-behind-https","3. Put both APIs behind HTTPS",[19,772,773,774,386,777,780],{},"Do not expose the two plain HTTP ports directly to the internet. If DNS for ",[45,775,776],{},"asr.example.com",[45,778,779],{},"llm.example.com"," points to the server, Caddy can obtain trusted certificates and proxy both services:",[37,782,786],{"className":783,"code":784,"language":785,"meta":43,"style":43},"language-caddyfile shiki shiki-themes github-light github-dark","asr.example.com {\n    reverse_proxy 127.0.0.1:9099\n}\n\nllm.example.com {\n    reverse_proxy 127.0.0.1:8181\n}\n","caddyfile",[45,787,788,793,798,803,807,812,817],{"__ignoreMap":43},[103,789,790],{"class":105,"line":106},[103,791,792],{},"asr.example.com {\n",[103,794,795],{"class":105,"line":117},[103,796,797],{},"    reverse_proxy 127.0.0.1:9099\n",[103,799,800],{"class":105,"line":125},[103,801,802],{},"}\n",[103,804,805],{"class":105,"line":328},[103,806,446],{"emptyLinePlaceholder":445},[103,808,809],{"class":105,"line":338},[103,810,811],{},"llm.example.com {\n",[103,813,814],{"class":105,"line":349},[103,815,816],{},"    reverse_proxy 127.0.0.1:8181\n",[103,818,819],{"class":105,"line":360},[103,820,802],{},[19,822,269,823,828],{},[88,824,827],{"href":825,"rel":826},"https:\u002F\u002Fcaddyserver.com\u002Fdocs\u002Fquick-starts\u002Freverse-proxy",[92],"Caddy reverse-proxy guide"," explains the surrounding server setup. Keep authentication enabled in OpenASR and llama.cpp even when Caddy is in front of them.",[19,830,831,832,834],{},"For private-LAN HTTP instead, bind each required port to the LAN interface, restrict access with a firewall, and enable ",[152,833,173],{}," in RecallWhisper. This is a development convenience, not a safe public deployment.",[80,836,838],{"id":837},"_4-enter-the-self-hosted-settings","4. Enter the self-hosted settings",[19,840,841],{},"In RecallWhisper, save the following values with your own domains and secrets:",[843,844,845,858],"table",{},[846,847,848],"thead",{},[849,850,851,855],"tr",{},[852,853,854],"th",{},"Setting",[852,856,857],{},"Example",[859,860,861,872,883,893,903,915,925],"tbody",{},[849,862,863,867],{},[864,865,866],"td",{},"Transcription URL",[864,868,869],{},[45,870,871],{},"https:\u002F\u002Fasr.example.com\u002Fv1",[849,873,874,877],{},[864,875,876],{},"Transcription token",[864,878,879,880],{},"Token from ",[45,881,882],{},"openasr apikey create --name recallwhisper",[849,884,885,888],{},[864,886,887],{},"Transcription model",[864,889,890],{},[45,891,892],{},"xasr-zh-en",[849,894,895,898],{},[864,896,897],{},"Summarization URL",[864,899,900],{},[45,901,902],{},"https:\u002F\u002Fllm.example.com\u002Fv1",[849,904,905,908],{},[864,906,907],{},"Summarization token",[864,909,910,912,913],{},[45,911,481],{}," from ",[45,914,477],{},[849,916,917,920],{},[864,918,919],{},"Summarization model",[864,921,922],{},[45,923,924],{},"qwen3.5-4b",[849,926,927,930],{},[864,928,929],{},"Summary language",[864,931,932,935],{},[45,933,934],{},"Same as transcript"," or a specific language",[19,937,150,938,941],{},[152,939,940],{},"Debug and API playground"," before enabling continuous processing. Run the authenticated transcription health check, load the summarization model list, and send a short JSON-mode test. This catches URL, token, model, and response-format problems before they affect real recordings.",[29,943,945],{"id":944},"troubleshooting","Troubleshooting",[54,947,948,957,963,969,975,989,997],{},[57,949,950,953,954,956],{},[152,951,952],{},"404 Not Found:"," Make sure the configured base URL ends in ",[45,955,158],{}," and does not include the endpoint that RecallWhisper appends.",[57,958,959,962],{},[152,960,961],{},"401 Unauthorized:"," Check transcription and summarization tokens independently; the two credentials are intentionally separate.",[57,964,965,968],{},[152,966,967],{},"Cleartext HTTP rejected:"," Use trusted HTTPS, or enable insecure HTTP only on a controlled private network.",[57,970,971,974],{},[152,972,973],{},"TLS certificate error:"," Install a certificate Android trusts. The insecure HTTP option does not disable HTTPS certificate validation.",[57,976,977,980,981,983,984,986,987,413],{},[152,978,979],{},"Model not found:"," Query ",[45,982,385],{}," and match the configured name exactly to ",[45,985,892],{}," or the llama.cpp ",[45,988,740],{},[57,990,991,994,995,413],{},[152,992,993],{},"No final summary:"," Keep Qwen reasoning disabled so final text appears in ",[45,996,751],{},[57,998,999,1002,1003,1006],{},[152,1000,1001],{},"llama.cpp container exits:"," Run ",[45,1004,1005],{},"docker compose logs llama",", check the GGUF path and permissions, and update the image if its build predates Qwen3.5 support.",[29,1008,1010],{"id":1009},"a-private-memory-system-you-can-inspect","A private memory system you can inspect",[19,1012,1013],{},"RecallWhisper does not try to become another account-based cloud notebook. It gives Android a dependable ambient recorder, keeps the durable archive local, and lets standard APIs handle the expensive model work. That division makes the system practical on a phone while leaving the processing backend replaceable.",[19,1015,1016],{},"For the most private deployment, self-host both APIs, keep their unencrypted ports on loopback, use trusted HTTPS, and retain separate credentials. The result is a voice memory workflow that remains searchable and useful without surrendering ownership of the archive it creates.",[1018,1019,1020],"style",{},"html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}",{"title":43,"searchDepth":117,"depth":117,"links":1022},[1023,1024,1031,1037,1038],{"id":31,"depth":117,"text":32},{"id":77,"depth":117,"text":78,"children":1025},[1026,1027,1028,1029,1030],{"id":82,"depth":125,"text":83},{"id":146,"depth":125,"text":147},{"id":177,"depth":125,"text":178},{"id":187,"depth":125,"text":188},{"id":194,"depth":125,"text":195},{"id":205,"depth":117,"text":206,"children":1032},[1033,1034,1035,1036],{"id":221,"depth":125,"text":222},{"id":393,"depth":125,"text":394},{"id":769,"depth":125,"text":770},{"id":837,"depth":125,"text":838},{"id":944,"depth":117,"text":945},{"id":1009,"depth":117,"text":1010},"\u002Farticles\u002Frecallwhisper-social-preview.webp","2026-08-09T00:00:00.000Z","Use RecallWhisper for private Android voice capture, local search, and summaries, then connect it to self-hosted OpenASR and llama.cpp APIs.","md",{"title":1044},{"Introducing RecallWhisper":1045},"Private Speech, Local Memory","page",{},"\u002Farticles\u002Fintroducing-recallwhisper",{"title":5,"description":1041},"articles\u002F8.introducing-recallwhisper","amj-OnbVQ8D4vV3UGYXE2kRxwnBM0-OJH1FwU1rgjLg",1786980373685]