<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>bitHuman changelog</title>
    <link>https://docs.bithuman.ai/changelog</link>
    <atom:link href="https://docs.bithuman.ai/changelog.xml" rel="self" type="application/rss+xml" />
    <description>Release notes for every bitHuman artifact: the CLI, the Python SDK, the Swift package, the Android SDK, the Flutter plugin, the LiveKit plugin and the REST API.</description>
    <language>en</language>
    <lastBuildDate>Mon, 28 Sep 2026 12:00:00 GMT</lastBuildDate>
    <item>
      <title>Swift package 2.19.0 — 2026-09-28</title>
      <link>https://docs.bithuman.ai/changelog#swift-package-2190--2026-09-28</link>
      <guid isPermaLink="true">https://docs.bithuman.ai/changelog#swift-package-2190--2026-09-28</guid>
      <pubDate>Mon, 28 Sep 2026 12:00:00 GMT</pubDate>
      <category>Swift</category>
      <description><![CDATA[<p>Tag <code>v2.19.0</code>.</p>
<ul>
<li><strong>Changed:</strong> the Expression 2 engine moves to 2.19.0 and the Essence 2 engine to 1.15.0. On a Mac, both engines now take their licensing and metering core from a new <code>EngineCore</code> binary target. The <code>Expression2</code>, <code>Essence2</code> and <code>Essence2Kit</code> products link it for you, with <code>Security</code> and <code>curl</code>. iPhone and iPad builds link nothing new.</li>
<li><strong>Action:</strong> update to 2.19.0. A Mac app that links the engine archives outside SwiftPM must also link <code>EngineCore.xcframework</code> from the <a href="https://github.com/bithuman-product/homebrew-bithuman/releases/tag/essence2-v1.15.0">essence2-v1.15.0 release</a>, plus <code>Security</code> and <code>curl</code>.</li>
</ul>]]></description>
    </item>
    <item>
      <title>Flutter plugin 2.6.21 — 2026-09-28</title>
      <link>https://docs.bithuman.ai/changelog#flutter-plugin-2621--2026-09-28</link>
      <guid isPermaLink="true">https://docs.bithuman.ai/changelog#flutter-plugin-2621--2026-09-28</guid>
      <pubDate>Mon, 28 Sep 2026 12:00:00 GMT</pubDate>
      <category>Flutter</category>
      <description><![CDATA[<ul>
<li><strong>Changed:</strong> iOS and macOS link the Swift package 2.19.0 engines (Expression 2 2.19.0, Essence 2 1.15.0), and on macOS the pod also links <code>EngineCore</code>. Android is unchanged: <code>essence2-android</code> 0.8.1 and <code>expression2-android</code> 0.5.2.</li>
<li><strong>Action:</strong> pin <code>ref: flutter-plugin-v2.6.21</code> and run the plugin's <code>scripts/bootstrap.sh</code> again.</li>
</ul>]]></description>
    </item>
    <item>
      <title>CLI 2.8.3 — 2026-09-28</title>
      <link>https://docs.bithuman.ai/changelog#cli-283--2026-09-28</link>
      <guid isPermaLink="true">https://docs.bithuman.ai/changelog#cli-283--2026-09-28</guid>
      <pubDate>Mon, 28 Sep 2026 12:00:00 GMT</pubDate>
      <category>CLI</category>
      <description><![CDATA[<p>Tag <code>cli-v2.8.3</code>.</p>
<ul>
<li><strong>New:</strong> <code>bithuman pack redeem</code> installs a prepaid offline pack (Business and Enterprise) on the machine that runs it; <code>bithuman pack status</code> shows the render-seconds left. Afterwards <code>bithuman render</code> of an Essence 1 avatar the pack covers needs no network and no API secret until the pack is spent. The MCP server adds the <code>pack_redeem</code> tool. Offline packs open platform by platform; where the CLI's support has not opened yet, the redeem says to use <code>python -m bithuman pack redeem</code>, and nothing is spent.</li>
<li><strong>Changed:</strong> the removals announced for CLI 2.9 (the <code>./.env</code> read, the spellings retired in 2.7.3) ship no earlier than 2026-12-26; the notices say so.</li>
<li><strong>Action:</strong> <code>brew upgrade bithuman-cli</code> or <code>curl -fsSL https://install.bithuman.ai | sh</code>.</li>
</ul>]]></description>
    </item>
    <item>
      <title>bithuman 2.11.16 — 2026-09-28</title>
      <link>https://docs.bithuman.ai/changelog#bithuman-21116--2026-09-28</link>
      <guid isPermaLink="true">https://docs.bithuman.ai/changelog#bithuman-21116--2026-09-28</guid>
      <pubDate>Mon, 28 Sep 2026 12:00:00 GMT</pubDate>
      <category>Python</category>
      <description><![CDATA[<ul>
<li><strong>New:</strong> <code>python -m bithuman pack redeem</code> installs a prepaid offline pack (Business and Enterprise) on the machine that runs it: it binds the account's unredeemed pack to this machine and installs it. <code>python -m bithuman pack redeem PURCHASE_ID</code> redeems a named one; <code>--file PACK</code> installs a saved pack with no network. Afterwards <code>python -m bithuman render</code> of an avatar the pack covers needs no network and no API secret until the pack is spent.</li>
<li><strong>Changed:</strong> a refused redeem says in plain words what to do (the plan, the platform, a pack already installed) and that nothing was spent.</li>
<li><strong>Action:</strong> <code>pip install -U bithuman</code>.</li>
</ul>]]></description>
    </item>
    <item>
      <title>bithuman 2.11.15 — 2026-09-27</title>
      <link>https://docs.bithuman.ai/changelog#bithuman-21115--2026-09-27</link>
      <guid isPermaLink="true">https://docs.bithuman.ai/changelog#bithuman-21115--2026-09-27</guid>
      <pubDate>Sun, 27 Sep 2026 12:00:00 GMT</pubDate>
      <category>Python</category>
      <description><![CDATA[<ul>
<li><strong>New:</strong> <code>bithuman.open(path).render(audio, out_mp4=&quot;out.mp4&quot;)</code> writes the MP4 (H.264 with the speech) and returns the number of frames, for every model. It is the one offline route.</li>
<li><strong>Fixed:</strong> an Essence 1 file render (<code>bithuman.open(...).render(...)</code> or <code>python -m bithuman render</code>) billed every frame twice; a render of N seconds of video now bills N seconds. Live <code>AsyncBithuman</code> sessions were not affected.</li>
<li><strong>Deprecated</strong> (removed in bithuman 4.0, no earlier than 2026-12-26; each prints one warning naming the replacement): <code>bithuman.offline</code> (<code>render_offline</code>, <code>OfflineRenderer</code>), the deprecated alias <code>BITHUMAN_API_KEY</code>, <code>token=</code> on <code>AsyncBithuman.create</code>, and the name <code>bithuman.AsyncAvatar</code>. <code>python -m bithuman</code> stops reading the API secret from <code>./.env</code> in the next release.</li>
<li><strong>Action:</strong> <code>pip install -U bithuman</code>.</li>
</ul>]]></description>
    </item>
    <item>
      <title>CLI 2.8.2 — 2026-09-27</title>
      <link>https://docs.bithuman.ai/changelog#cli-282--2026-09-27</link>
      <guid isPermaLink="true">https://docs.bithuman.ai/changelog#cli-282--2026-09-27</guid>
      <pubDate>Sun, 27 Sep 2026 12:00:00 GMT</pubDate>
      <category>CLI</category>
      <description><![CDATA[<p>Tag <code>cli-v2.8.2</code>.</p>
<ul>
<li><strong>Changed:</strong> <code>bithuman run &lt;CODE&gt;</code> with a code that is not one of your agents plays the free gallery avatar with that code, the way <code>pull</code>, <code>render</code> and <code>open</code> already did.</li>
<li><strong>Changed:</strong> <code>bithuman open</code> names the model (for example Essence 2 or Expression 2). Asking <code>pull</code> for a model a gallery avatar does not have names the models it does have (<code>MODEL_NOT_GENERATED</code>).</li>
<li><strong>Changed:</strong> with <code>BITHUMAN_LOCAL=1</code>, <code>run</code> checks that the on-device voice packages are installed before the session starts, and prints the one command that installs them.</li>
<li><strong>Deprecated:</strong> reading the API secret from a <code>.env</code> file in the working directory prints a notice; CLI 2.9 stops reading it. Export <code>BITHUMAN_API_SECRET</code>, or run <code>bithuman login</code> once.</li>
<li><strong>Deprecated:</strong> the deprecated alias <code>BITHUMAN_API_KEY</code> is read until CLI 3.0 (no earlier than 2026-12-26). Rename it to <code>BITHUMAN_API_SECRET</code> (same value).</li>
<li><strong>Changed:</strong> <code>BITHUMAN_API_BASE</code> is no longer a documented setting; the CLI talks to <code>https://api.bithuman.ai</code>.</li>
<li><strong>Action:</strong> <code>brew upgrade bithuman-cli</code> or <code>curl -fsSL https://install.bithuman.ai | sh</code>.</li>
</ul>]]></description>
    </item>
    <item>
      <title>Flutter plugin 2.6.20 — 2026-09-27</title>
      <link>https://docs.bithuman.ai/changelog#flutter-plugin-2620--2026-09-27</link>
      <guid isPermaLink="true">https://docs.bithuman.ai/changelog#flutter-plugin-2620--2026-09-27</guid>
      <pubDate>Sun, 27 Sep 2026 12:00:00 GMT</pubDate>
      <category>Flutter</category>
      <description><![CDATA[<ul>
<li><strong>Changed:</strong> the realtime voice session takes your bitHuman API secret and connects through bitHuman's <a href="https://docs.bithuman.ai/api/realtime">realtime relay</a>; there is no <code>ek_…</code> token to mint. The conversation is billed to your account at 10 credits per minute, the avatar included. A refusal a retry cannot fix (a rejected secret, no credits, the time limit) stops the session once and is reported on <code>errorStream</code>.</li>
<li><strong>Fixed:</strong> iOS and macOS build from the published tag. They link the published Expression 2 (2.18.0) and Essence 2 (1.14.2) engines.</li>
<li><strong>Changed:</strong> Android uses <code>essence2-android</code> 0.8.1 (memory stays flat in long sessions) and <code>expression2-android</code> 0.5.2.</li>
<li><strong>Action:</strong> pin <code>ref: flutter-plugin-v2.6.20</code> and pass your API secret to <code>BithumanRealtimeSession(apiKey:)</code>.</li>
</ul>]]></description>
    </item>
    <item>
      <title>expression2-android 0.5.2 — 2026-09-27</title>
      <link>https://docs.bithuman.ai/changelog#expression2-android-052--2026-09-27</link>
      <guid isPermaLink="true">https://docs.bithuman.ai/changelog#expression2-android-052--2026-09-27</guid>
      <pubDate>Sun, 27 Sep 2026 12:00:00 GMT</pubDate>
      <category>Android</category>
      <description><![CDATA[<ul>
<li><strong>Changed:</strong> the Hexagon accelerator prepares the decoder once and keeps it. On a Galaxy S25+, <code>create()</code> took about 31 s on every launch through 0.5.1; with 0.5.2 the first launch takes about 15 s and later launches 1–2 s. Replies start as fast as before, and frames are unchanged.</li>
<li><strong>Added:</strong> read-only <code>Expression2Backend</code> fields report whether the prepared decoder was reused and how long it took.</li>
<li><strong>Action:</strong> <code>implementation(&quot;ai.bithuman:expression2-android:0.5.2&quot;)</code>.</li>
</ul>]]></description>
    </item>
    <item>
      <title>Swift package 2.18.0 — 2026-09-27</title>
      <link>https://docs.bithuman.ai/changelog#swift-package-2180--2026-09-27</link>
      <guid isPermaLink="true">https://docs.bithuman.ai/changelog#swift-package-2180--2026-09-27</guid>
      <pubDate>Sun, 27 Sep 2026 12:00:00 GMT</pubDate>
      <category>Swift</category>
      <description><![CDATA[<p>Essence 2 engine 1.14.2 · Expression 2 engine 2.18.0</p>
<ul>
<li><strong>New:</strong> Expression 2 hands out one stream of frames to show: <code>frames(audioClock:)</code> at 20 frames per second, idle motion between replies and each speech frame when your player has played its audio. Each frame says whether it is speech (<code>isSpeech</code>) and which one ends the reply (<code>endsReply</code>); <code>events()</code> reports <code>.replyStarted</code> and <code>.replyEnded</code> once per reply, and <code>interrupt()</code> cuts a reply. <code>pull()</code> is unchanged.</li>
<li><strong>Fixed:</strong> an Expression 2 session that only shows its idle animation is billed for its active time, like any other session.</li>
<li><strong>Action:</strong> set <code>from: &quot;2.18.0&quot;</code>, then <code>swift package update</code>.</li>
</ul>]]></description>
    </item>
    <item>
      <title>CLI 2.8.1 — 2026-09-27</title>
      <link>https://docs.bithuman.ai/changelog#cli-281--2026-09-27</link>
      <guid isPermaLink="true">https://docs.bithuman.ai/changelog#cli-281--2026-09-27</guid>
      <pubDate>Sun, 27 Sep 2026 12:00:00 GMT</pubDate>
      <category>CLI</category>
      <description><![CDATA[<p>Tag <code>cli-v2.8.1</code>.</p>
<ul>
<li><strong>Fixed:</strong> opening a <code>bithuman run</code> page link no longer starts a billed session in a room nobody joins (a link preview, a prefetch or a reload). A session starts when a person joins; a room nobody joins within 90 seconds ends without starting.</li>
<li><strong>Changed:</strong> with the bitHuman brain (no OpenAI key of your own), the voice connects through bitHuman's own service with your API secret, and says in plain words why it stopped (out of credits, the 60-minute session limit, a rejected secret).</li>
<li><strong>Fixed:</strong> a long Essence 2 session no longer grows in memory while the avatar talks.</li>
<li><strong>Changed:</strong> <code>--help</code> examples use the free <code>wise-pup</code> avatar; <code>bithuman list</code> says rendering needs <code>bithuman login</code>; with <code>--json</code>, a mistyped command prints one JSON error (<code>USAGE</code>, exit 2).</li>
<li><strong>Fixed:</strong> a long-running <code>bithuman run</code> uses a re-published avatar file for the next session without a restart.</li>
<li><strong>Action:</strong> <code>brew upgrade bithuman-cli</code> or <code>curl -fsSL https://install.bithuman.ai | sh</code>.</li>
</ul>]]></description>
    </item>
    <item>
      <title>Swift package 2.17.3 — 2026-09-27</title>
      <link>https://docs.bithuman.ai/changelog#swift-package-2173--2026-09-27</link>
      <guid isPermaLink="true">https://docs.bithuman.ai/changelog#swift-package-2173--2026-09-27</guid>
      <pubDate>Sun, 27 Sep 2026 12:00:00 GMT</pubDate>
      <category>Swift</category>
      <description><![CDATA[<p>Essence 2 engine 1.14.2 · Expression 2 engine 2.7.0</p>
<ul>
<li><strong>Fixed:</strong> memory stays flat in long Essence 2 sessions. Before this release, an app that fed audio without a pause grew by about 1 MB per second of speech. On an iPhone that could end a session after about 35 minutes.</li>
<li><strong>Action:</strong> set <code>from: &quot;2.17.3&quot;</code>, then <code>swift package update</code>.</li>
</ul>]]></description>
    </item>
    <item>
      <title>essence2-android 0.8.1 — 2026-09-27</title>
      <link>https://docs.bithuman.ai/changelog#essence2-android-081--2026-09-27</link>
      <guid isPermaLink="true">https://docs.bithuman.ai/changelog#essence2-android-081--2026-09-27</guid>
      <pubDate>Sun, 27 Sep 2026 12:00:00 GMT</pubDate>
      <category>Android</category>
      <description><![CDATA[<ul>
<li><strong>Fixed:</strong> memory no longer grows while an avatar speaks without pausing. Through 0.8.0 the audio frontend kept every frame of an utterance, about 1 MiB per second of speech, until <code>endOfAudio()</code>, <code>resetAudio()</code> or a 600 ms pause in <code>feed()</code>. Turn-by-turn conversation stayed bounded; an app that fed audio continuously grew for as long as it spoke. On a Galaxy S25+, ten minutes of one continuous utterance now holds at about 920 MiB, where 0.8.0 reached 1,473 MiB. Frames are unchanged.</li>
<li><strong>Action:</strong> <code>implementation(&quot;ai.bithuman:essence2-android:0.8.1&quot;)</code>, especially if your app streams audio without pauses.</li>
</ul>]]></description>
    </item>
    <item>
      <title>bithuman 2.11.14 — 2026-09-27</title>
      <link>https://docs.bithuman.ai/changelog#bithuman-21114--2026-09-27</link>
      <guid isPermaLink="true">https://docs.bithuman.ai/changelog#bithuman-21114--2026-09-27</guid>
      <pubDate>Sun, 27 Sep 2026 12:00:00 GMT</pubDate>
      <category>Python</category>
      <description><![CDATA[<ul>
<li><strong>Fixed:</strong> <code>bithuman.open()</code> with no API secret, offline licence or prepaid pack refuses at once, before it loads the model or downloads anything, and names <code>BITHUMAN_API_SECRET</code> and where to get one.</li>
<li><strong>Fixed:</strong> a first Essence 2 open on a fresh machine downloads 66 MB instead of 444 MB; the 377 MB audio encoder is fetched only when the avatar uses it. Rendered frames are identical.</li>
<li><strong>Fixed:</strong> memory stays flat when an Essence 2 avatar speaks without a pause; it grew about 1 MB per second of speech.</li>
<li><strong>Changed:</strong> a live avatar reports its whole active session, talking or idle, as the billing rule says; an idle stretch was billed for at most a few minutes of it.</li>
<li><strong>Changed:</strong> usage reports go only to bithuman.ai hosts.</li>
<li><strong>Changed:</strong> <code>AsyncBithuman.sync_to(sink)</code> shows each picture when its voice plays; with the LiveKit <code>AvatarRunner</code>, an Expression 2 mouth led its voice by about 120 ms at a browser viewer and now leads by about 60 ms.</li>
<li><strong>Changed:</strong> prepaid offline packs are debited for the whole active session; the CPU runtimes find a CPU quota set on the process's own cgroup; a load failure names the product.</li>
<li><strong>Action:</strong> <code>pip install -U bithuman</code>.</li>
</ul>]]></description>
    </item>
    <item>
      <title>Flutter plugin 2.6.19 — 2026-09-26</title>
      <link>https://docs.bithuman.ai/changelog#flutter-plugin-2619--2026-09-26</link>
      <guid isPermaLink="true">https://docs.bithuman.ai/changelog#flutter-plugin-2619--2026-09-26</guid>
      <pubDate>Sat, 26 Sep 2026 12:00:00 GMT</pubDate>
      <category>Flutter</category>
      <description><![CDATA[<ul>
<li><strong>Changed:</strong> on Android, Essence 2 frames reach the screen without a CPU copy. On a Galaxy S25+ this uses about 8% less CPU, and the frames are unchanged.</li>
<li><strong>Changed:</strong> Android uses <code>essence2-android</code> 0.8.0 and <code>expression2-android</code> 0.5.1, which bill correctly whatever the app sets and name each installation on the meter. iOS and macOS are unchanged.</li>
<li><strong>Action:</strong> set <code>ref: flutter-plugin-v2.6.19</code> in your <code>pubspec.yaml</code>.</li>
</ul>]]></description>
    </item>
    <item>
      <title>expression2-android 0.5.1 — 2026-09-26</title>
      <link>https://docs.bithuman.ai/changelog#expression2-android-051--2026-09-26</link>
      <guid isPermaLink="true">https://docs.bithuman.ai/changelog#expression2-android-051--2026-09-26</guid>
      <pubDate>Sat, 26 Sep 2026 12:00:00 GMT</pubDate>
      <category>Android</category>
      <description><![CDATA[<ul>
<li><strong>Fixed:</strong> billing can no longer be changed from app code: the meter's endpoint, whether from <code>Expression2Metering.apiBaseUrl</code> or the <code>BITHUMAN_API_URL</code> environment variables, is honoured only for an <code>https://</code> bitHuman host.</li>
<li><strong>Added:</strong> each installation names itself on the meter: a random id is kept in the app's storage. Set <code>Expression2Metering.installId</code> or <code>BITHUMAN_INSTALL_ID</code> to choose it yourself.</li>
<li><strong>Action:</strong> <code>implementation(&quot;ai.bithuman:expression2-android:0.5.1&quot;)</code>.</li>
</ul>]]></description>
    </item>
    <item>
      <title>essence2-android 0.8.0 — 2026-09-26</title>
      <link>https://docs.bithuman.ai/changelog#essence2-android-080--2026-09-26</link>
      <guid isPermaLink="true">https://docs.bithuman.ai/changelog#essence2-android-080--2026-09-26</guid>
      <pubDate>Sat, 26 Sep 2026 12:00:00 GMT</pubDate>
      <category>Android</category>
      <description><![CDATA[<ul>
<li><strong>Fixed:</strong> billing can no longer be changed from app code. <code>Essence2Metering.fps</code> is ignored (deprecated, still compiles), and the meter's endpoint, whether from <code>apiBaseUrl</code> or the <code>BITHUMAN_API_URL</code> environment variables, is honoured only for an <code>https://</code> bitHuman host.</li>
<li><strong>Added:</strong> each installation names itself on the meter: a random id is kept in the app's storage. Set <code>Essence2Metering.installId</code> or <code>BITHUMAN_INSTALL_ID</code> to choose it yourself.</li>
<li><strong>Added:</strong> <code>useHardwareBuffers(slots)</code> accepts up to 32 slots (was 16), for presenters that queue frames ahead.</li>
<li><strong>Added:</strong> <code>Essence2RenderFailed</code> and <code>Essence2RenderStatus</code> resolve from <code>ai.bithuman.essence2</code>, so <code>import ai.bithuman.essence2.*</code> covers every type an app uses.</li>
<li><strong>Changed:</strong> the GPU work per frame falls by about a third; frames are unchanged.</li>
<li><strong>Action:</strong> <code>implementation(&quot;ai.bithuman:essence2-android:0.8.0&quot;)</code>.</li>
</ul>]]></description>
    </item>
    <item>
      <title>CLI 2.8.0 — 2026-09-26</title>
      <link>https://docs.bithuman.ai/changelog#cli-280--2026-09-26</link>
      <guid isPermaLink="true">https://docs.bithuman.ai/changelog#cli-280--2026-09-26</guid>
      <pubDate>Sat, 26 Sep 2026 12:00:00 GMT</pubDate>
      <category>CLI</category>
      <description><![CDATA[<p>Tag <code>cli-v2.8.0</code>.</p>
<ul>
<li><strong>Changed:</strong> avatars download at about half the size. <code>pull</code>, <code>run</code> and <code>render</code> fetch only the parts this computer uses: an Essence 2 avatar is about 70–90 MB instead of 150 MB, and an Expression 2 avatar about 35 MB on a Mac or 65 MB on Linux instead of 200 MB. Every download is checked against its published digest, and the rendered video is the same.</li>
<li><strong>Changed:</strong> the bitHuman brain (the voice chat that needs no OpenAI key) and a prepaid offline pack count active session time, talking or idle, the same rule as every bitHuman surface.</li>
<li><strong>Changed:</strong> <code>BITHUMAN_API_BASE</code> and <code>--api-base</code> accept only <code>https://api.bithuman.ai</code> or another <code>https://*.bithuman.ai</code> address; any other value is ignored with a notice.</li>
<li><strong>Fixed:</strong> <code>bithuman logout</code> revokes only the secret <code>bithuman login</code> stored. A secret from the environment or a <code>./.env</code> file is never revoked.</li>
<li><strong>Fixed:</strong> the notice that a newer CLI is available always finds the newest CLI release.</li>
<li><strong>Action:</strong> <code>brew upgrade bithuman-cli</code> or <code>curl -fsSL https://install.bithuman.ai | sh</code>.</li>
</ul>]]></description>
    </item>
    <item>
      <title>bithuman 2.11.13 — 2026-09-26</title>
      <link>https://docs.bithuman.ai/changelog#bithuman-21113--2026-09-26</link>
      <guid isPermaLink="true">https://docs.bithuman.ai/changelog#bithuman-21113--2026-09-26</guid>
      <pubDate>Sat, 26 Sep 2026 12:00:00 GMT</pubDate>
      <category>Python</category>
      <description><![CDATA[<ul>
<li><strong>Fixed:</strong> an Expression 2 reply through <code>AsyncBithuman</code> (and the LiveKit plugin) plays through without the brief pause about a second in, where the face froze and the voice stopped. A reply that is already complete starts sooner, and a reply pushed in a single call starts once its first part is rendered instead of after all of it.</li>
<li><strong>Fixed:</strong> the Expression 2 and Essence 2 CPU runtimes size their thread pools to the CPUs a container allows instead of the machine's total core count, so Expression 2 in a CPU-limited container renders at full speed. <code>BITHUMAN_THREADS</code> still overrides.</li>
<li><strong>Fixed:</strong> a long idle no longer grows the process by dozens of threads.</li>
<li><strong>Fixed:</strong> a reply pushed to <code>AsyncBithuman</code> in a single call is metered in full; about 80% of it was before.</li>
<li><strong>Changed:</strong> a streamed Expression 2 reply renders exactly the frames <code>bithuman.open()</code> renders for the same audio.</li>
<li><strong>Changed:</strong> the offline renderer raises <code>FileNotFoundError</code> naming the path when the avatar file does not exist, and refuses another kind of avatar by its product name.</li>
<li><strong>Changed:</strong> usage reports name the installation with a random id kept in <code>~/.bithuman/install_id</code>, the same file the <code>bithuman</code> CLI uses. Set <code>BITHUMAN_INSTALL_ID</code> to choose your own.</li>
<li><strong>Action:</strong> <code>pip install -U bithuman</code>.</li>
</ul>]]></description>
    </item>
    <item>
      <title>LiveKit docs and examples — 2026-09-26</title>
      <link>https://docs.bithuman.ai/changelog#livekit-docs-and-examples--2026-09-26</link>
      <guid isPermaLink="true">https://docs.bithuman.ai/changelog#livekit-docs-and-examples--2026-09-26</guid>
      <pubDate>Sat, 26 Sep 2026 12:00:00 GMT</pubDate>
      <category>LiveKit</category>
      <description><![CDATA[<ul>
<li><strong>Changed:</strong> a LiveKit worker keeps your API secret as <code>BITHUMAN_MASTER_SECRET</code>, never <code>BITHUMAN_API_SECRET</code>. <code>livekit-plugins-bithuman</code> 1.8.4 and older reads <code>BITHUMAN_API_SECRET</code> by itself whenever <code>api_secret=</code> is omitted, and copies it into the avatar's participant attributes, which everyone in the room can read. The <a href="https://docs.bithuman.ai/platforms/livekit#authenticate">LiveKit page</a> and the LiveKit examples now use the new name and refuse to start while the old one is set.</li>
<li><strong>Action:</strong> rename the variable in your worker's environment and mint a room token from it. If a worker ran a cloud avatar with <code>BITHUMAN_API_SECRET</code> set and no <code>api_secret=</code>, create a new secret and delete the old one in the console.</li>
</ul>]]></description>
    </item>
    <item>
      <title>Billing — 2026-09-26</title>
      <link>https://docs.bithuman.ai/changelog#billing--2026-09-26</link>
      <guid isPermaLink="true">https://docs.bithuman.ai/changelog#billing--2026-09-26</guid>
      <pubDate>Sat, 26 Sep 2026 12:00:00 GMT</pubDate>
      <category>API</category>
      <description><![CDATA[<ul>
<li><strong>Changed:</strong> a managed conversational agent bills one all-inclusive rate (10 credits/min, or 30 with the camera on). It covers the avatar, whether it renders in the bitHuman cloud or in the viewer's browser; there is no separate avatar charge. An avatar-only session (your own agent through the plugin or the API) that renders in the browser bills the model's self-hosted rate. Rates are on <a href="https://docs.bithuman.ai/pricing">pricing</a>.</li>
<li><strong>Changed:</strong> realtime sessions bill active session time, talking or idle, by the exact second, with no per-session minimum. A session's fraction of a credit carries to your next session. This replaces the talking-only billing announced earlier the same day. Talking-video renders are unchanged: whole minutes of output, minimum one minute. Rates are on <a href="https://docs.bithuman.ai/pricing">pricing</a>.</li>
<li><strong>Changed:</strong> Expression 1 avatar sessions are now metered to your account at the standard cloud rate. Rates are on <a href="https://docs.bithuman.ai/pricing">pricing</a>.</li>
</ul>]]></description>
    </item>
    <item>
      <title>Swift package 2.17.2 — 2026-09-26</title>
      <link>https://docs.bithuman.ai/changelog#swift-package-2172--2026-09-26</link>
      <guid isPermaLink="true">https://docs.bithuman.ai/changelog#swift-package-2172--2026-09-26</guid>
      <pubDate>Sat, 26 Sep 2026 12:00:00 GMT</pubDate>
      <category>Swift</category>
      <description><![CDATA[<p>Essence 2 engine 1.14.1 · Expression 2 engine 2.7.0</p>
<ul>
<li><strong>Fixed:</strong> Essence 2 sessions are always billed to your API secret. Update from any earlier release.</li>
<li><strong>Action:</strong> set <code>from: &quot;2.17.2&quot;</code>, then <code>swift package update</code>.</li>
</ul>]]></description>
    </item>
    <item>
      <title>Swift package 2.17.1 — 2026-09-26</title>
      <link>https://docs.bithuman.ai/changelog#swift-package-2171--2026-09-26</link>
      <guid isPermaLink="true">https://docs.bithuman.ai/changelog#swift-package-2171--2026-09-26</guid>
      <pubDate>Sat, 26 Sep 2026 12:00:00 GMT</pubDate>
      <category>Swift</category>
      <description><![CDATA[<p>Essence 2 engine 1.14.0 · Expression 2 engine 2.7.0</p>
<ul>
<li><strong>Fixed:</strong> reading <code>width</code>, <code>height</code>, <code>isReady</code> or <code>runtimeFailure</code> after <code>shutdown()</code> no longer crashes the app.</li>
</ul>]]></description>
    </item>
    <item>
      <title>Swift package 2.17.0 — 2026-09-26</title>
      <link>https://docs.bithuman.ai/changelog#swift-package-2170--2026-09-26</link>
      <guid isPermaLink="true">https://docs.bithuman.ai/changelog#swift-package-2170--2026-09-26</guid>
      <pubDate>Sat, 26 Sep 2026 12:00:00 GMT</pubDate>
      <category>Swift</category>
      <description><![CDATA[<p>Essence 2 engine 1.14.0 · Expression 2 engine 2.7.0</p>
<ul>
<li><strong>New:</strong> <code>Essence2Engine.frames(following:)</code>, an AsyncSequence of frames paced to 25 per second. Each frame carries <code>isSpeech</code>, <code>endsReply</code> and <code>audioTime</code>, and <code>events()</code> reports <code>.replyStarted</code> / <code>.replyEnded</code> once per reply. <code>frames(following: player)</code> hands out a reply's frames as your <code>AVAudioPlayerNode</code> plays their audio, so lips stay on the voice for the whole reply; <code>frames(audioClock:)</code> takes your own clock.</li>
<li><strong>New:</strong> <code>flushTail()</code> ends a reply's audio at once instead of after 0.6 s of silence; <code>pacing = .unpaced</code> renders offline as fast as the device allows.</li>
<li><strong>Changed:</strong> <code>pull()</code> and <code>idle(into:)</code> hand out at most 25 frames a second. A tight loop no longer receives hundreds of idle frames a second; <code>nil</code> still means keep the current frame. The 40 ms loop from 2.16.0 keeps working.</li>
<li><strong>Changed:</strong> usage reports name the install with a random id kept in the app's Application Support directory (<code>BITHUMAN_INSTALL_ID</code> overrides it).</li>
<li><strong>Action:</strong> set <code>from: &quot;2.17.1&quot;</code>, then <code>swift package update</code>. Move a display loop to <code>frames(following:)</code>.</li>
</ul>]]></description>
    </item>
    <item>
      <title>Flutter plugin 2.6.18 — 2026-09-26</title>
      <link>https://docs.bithuman.ai/changelog#flutter-plugin-2618--2026-09-26</link>
      <guid isPermaLink="true">https://docs.bithuman.ai/changelog#flutter-plugin-2618--2026-09-26</guid>
      <pubDate>Sat, 26 Sep 2026 12:00:00 GMT</pubDate>
      <category>Flutter</category>
      <description><![CDATA[<ul>
<li><strong>Changed:</strong> iOS and macOS use Essence 2 engine 1.14.0, whose usage reports name the install. Android is unchanged.</li>
<li>iOS and macOS do not build from the published tag yet; use the plugin on Android.</li>
</ul>]]></description>
    </item>
    <item>
      <title>CLI 2.7.8 — 2026-09-26</title>
      <link>https://docs.bithuman.ai/changelog#cli-278--2026-09-26</link>
      <guid isPermaLink="true">https://docs.bithuman.ai/changelog#cli-278--2026-09-26</guid>
      <pubDate>Sat, 26 Sep 2026 12:00:00 GMT</pubDate>
      <category>CLI</category>
      <description><![CDATA[<p>Tag <code>cli-v2.7.8</code>.</p>
<ul>
<li><strong>Fixed:</strong> Expression 2 on Linux runs at full speed in a container limited to fewer CPUs than the machine has (for example <code>docker run --cpus=4</code>). It started one thread per machine CPU and ran several times slower than real time; it now sizes its threads to the CPUs it may use.</li>
<li><strong>Changed:</strong> each install sends its own stable, random install id with its usage, so two installs that share one API secret are no longer billed as one.</li>
<li><strong>Action:</strong> <code>brew upgrade bithuman-cli</code> or <code>curl -fsSL https://install.bithuman.ai | sh</code>.</li>
</ul>]]></description>
    </item>
    <item>
      <title>CLI 2.7.7 — 2026-09-26</title>
      <link>https://docs.bithuman.ai/changelog#cli-277--2026-09-26</link>
      <guid isPermaLink="true">https://docs.bithuman.ai/changelog#cli-277--2026-09-26</guid>
      <pubDate>Sat, 26 Sep 2026 12:00:00 GMT</pubDate>
      <category>CLI</category>
      <description><![CDATA[<p>Tag <code>cli-v2.7.7</code>.</p>
<ul>
<li><strong>Fixed:</strong> lip sync in live <code>bithuman run</code> sessions. The voice trailed the mouth by about 0.1–0.2 s on macOS and Linux; each frame is now released with its own audio.</li>
<li><strong>Changed:</strong> a self-hosted Essence 1 session is billed for the seconds the avatar talks, like Essence 2 and Expression 2. It was billed for every whole minute the session was open, idle included. Idle is free.</li>
<li><strong>Changed:</strong> a live Essence 2 reply is no longer billed for the short transition into and out of speech, which carries none of your audio.</li>
<li><strong>Changed:</strong> <code>bithuman list</code> and showcase names ask again when the service does not answer, and <code>bithuman list</code> exits 69 (service unavailable) when it cannot be reached.</li>
<li><strong>Action:</strong> <code>brew upgrade bithuman-cli</code> or <code>curl -fsSL https://install.bithuman.ai | sh</code>.</li>
</ul>]]></description>
    </item>
    <item>
      <title>Swift package 2.16.0 — 2026-09-25</title>
      <link>https://docs.bithuman.ai/changelog#swift-package-2160--2026-09-25</link>
      <guid isPermaLink="true">https://docs.bithuman.ai/changelog#swift-package-2160--2026-09-25</guid>
      <pubDate>Fri, 25 Sep 2026 12:00:00 GMT</pubDate>
      <category>Swift</category>
      <description><![CDATA[<p>Essence 2 engine 1.13.0 · Expression 2 engine 2.7.0</p>
<ul>
<li><strong>Fixed:</strong> an app that links its own <code>mlx-swift</code> now links beside Essence 2, also with <code>-ObjC</code> or <code>-all_load</code>. Essence 2 no longer contains MLX, and its download is 22 MB instead of 171 MB.</li>
<li><strong>Action:</strong> set <code>from: &quot;2.16.0&quot;</code>, then <code>swift package update</code>.</li>
</ul>]]></description>
    </item>
    <item>
      <title>Flutter plugin 2.6.17 — 2026-09-25</title>
      <link>https://docs.bithuman.ai/changelog#flutter-plugin-2617--2026-09-25</link>
      <guid isPermaLink="true">https://docs.bithuman.ai/changelog#flutter-plugin-2617--2026-09-25</guid>
      <pubDate>Fri, 25 Sep 2026 12:00:00 GMT</pubDate>
      <category>Flutter</category>
      <description><![CDATA[<ul>
<li><strong>Changed:</strong> iOS and macOS use Essence 2 engine 1.13.0, which contains no MLX.</li>
<li><strong>Action:</strong> pin <code>ref: flutter-plugin-v2.6.17</code>.</li>
<li>iOS and macOS do not build from the published tag yet; use the plugin on Android.</li>
</ul>]]></description>
    </item>
    <item>
      <title>Dashboard — 2026-09-25</title>
      <link>https://docs.bithuman.ai/changelog#dashboard--2026-09-25</link>
      <guid isPermaLink="true">https://docs.bithuman.ai/changelog#dashboard--2026-09-25</guid>
      <pubDate>Fri, 25 Sep 2026 12:00:00 GMT</pubDate>
      <category>bitHuman app</category>
      <description><![CDATA[<ul>
<li><strong>Changed:</strong> Explore opens the V2 gallery of Essence 2 and Expression 2 agents. Switch to V1 for the classic gallery; your choice is remembered.</li>
<li><strong>Changed:</strong> a new agent starts on Expression 2. Essence 2, Essence 1 and Expression 1 stay one click away in the model dialog.</li>
</ul>]]></description>
    </item>
    <item>
      <title>essence2-android 0.7.0 — 2026-09-25</title>
      <link>https://docs.bithuman.ai/changelog#essence2-android-070--2026-09-25</link>
      <guid isPermaLink="true">https://docs.bithuman.ai/changelog#essence2-android-070--2026-09-25</guid>
      <pubDate>Fri, 25 Sep 2026 12:00:00 GMT</pubDate>
      <category>Android</category>
      <description><![CDATA[<ul>
<li><strong>Changed:</strong> a long session holds a higher frame rate on the same handset. The held-for-10-minutes figure on a Galaxy S25+ is on <a href="https://docs.bithuman.ai/performance">Performance</a>. Frames are unchanged.</li>
<li><strong>Added:</strong> zero-copy frame delivery. After <code>useHardwareBuffers()</code>, <code>pullHardwareBuffer()</code> and <code>idleHardwareBuffer()</code> return an <code>Essence2HardwareFrame</code> whose RGBA <code>HardwareBuffer</code> your renderer samples directly; close each frame after presenting it. <code>pull(ByteBuffer)</code> is unchanged, and nothing changes unless you call <code>useHardwareBuffers()</code>.</li>
<li><strong>Action:</strong> <code>implementation(&quot;ai.bithuman:essence2-android:0.7.0&quot;)</code>.</li>
</ul>]]></description>
    </item>
    <item>
      <title>bithuman 2.11.12 — 2026-09-25</title>
      <link>https://docs.bithuman.ai/changelog#bithuman-21112--2026-09-25</link>
      <guid isPermaLink="true">https://docs.bithuman.ai/changelog#bithuman-21112--2026-09-25</guid>
      <pubDate>Fri, 25 Sep 2026 12:00:00 GMT</pubDate>
      <category>Python</category>
      <description><![CDATA[<ul>
<li><strong>Fixed:</strong> a moment of network no longer ends a render. When the service does not answer, or answers that it is busy, <code>python -m bithuman</code> asks again, up to three times over a few seconds. When it does give up, the message says what the service did, and the exit code is 69 (service unavailable), as with the <code>bithuman</code> CLI. In Python the refusal is still a <code>bithuman.Failed</code>.</li>
<li><strong>Changed:</strong> a live Essence 2 avatar (<code>AsyncBithuman</code>) no longer bills the short transition into and out of speech, which carries none of your audio.</li>
<li><strong>Action:</strong> <code>pip install -U bithuman</code>.</li>
</ul>]]></description>
    </item>
    <item>
      <title>bithuman 2.11.11 — 2026-09-25</title>
      <link>https://docs.bithuman.ai/changelog#bithuman-21111--2026-09-25</link>
      <guid isPermaLink="true">https://docs.bithuman.ai/changelog#bithuman-21111--2026-09-25</guid>
      <pubDate>Fri, 25 Sep 2026 12:00:00 GMT</pubDate>
      <category>Python</category>
      <description><![CDATA[<ul>
<li><strong>Changed:</strong> an offline render — <code>bithuman.open(...).render(audio)</code> and <code>python -m bithuman render</code> — is billed for the length of the video it produces (frames ÷ frame rate) at the self-hosted rate, the same as <code>bithuman render</code> in the CLI. It was billed for the time the render took. Live avatars (<code>AsyncBithuman</code>, the LiveKit plugin) are unchanged: they bill the seconds the avatar talks, and idle is free. Renders made before this release are not billed again.</li>
<li><strong>Action:</strong> <code>pip install -U bithuman</code>.</li>
</ul>]]></description>
    </item>
    <item>
      <title>CLI 2.7.6 — 2026-09-25</title>
      <link>https://docs.bithuman.ai/changelog#cli-276--2026-09-25</link>
      <guid isPermaLink="true">https://docs.bithuman.ai/changelog#cli-276--2026-09-25</guid>
      <pubDate>Fri, 25 Sep 2026 12:00:00 GMT</pubDate>
      <category>CLI</category>
      <description><![CDATA[<p>Tag <code>cli-v2.7.6</code>.</p>
<ul>
<li><strong>Changed:</strong> a live Essence 1 reply starts about 0.8 s sooner. The CLI measures how much audio the avatar needs before its first frame (about 0.2 s) instead of waiting a fixed second.</li>
<li><strong>Fixed:</strong> Essence 1 lip sync in a live session: the mouth moved about 0.1 s ahead of the voice; it is now within 30 ms, and the voice never runs ahead of the mouth.</li>
<li><strong>Fixed:</strong> an Expression 2 video rendered on Linux is billed for its length. A 15.0 s video was billed 15.5 s for silent frames past the end of the audio.</li>
<li><strong>Action:</strong> <code>curl -fsSL https://install.bithuman.ai | sh</code>, or <code>brew upgrade bithuman-cli</code>.</li>
</ul>]]></description>
    </item>
    <item>
      <title>CLI 2.7.5 — 2026-09-25</title>
      <link>https://docs.bithuman.ai/changelog#cli-275--2026-09-25</link>
      <guid isPermaLink="true">https://docs.bithuman.ai/changelog#cli-275--2026-09-25</guid>
      <pubDate>Fri, 25 Sep 2026 12:00:00 GMT</pubDate>
      <category>CLI</category>
      <description><![CDATA[<p>Tag <code>cli-v2.7.5</code>.</p>
<ul>
<li><strong>Fixed:</strong> <code>bithuman run</code> again refuses at once when no API secret is set (exit 77), and refuses <code>--host 0.0.0.0</code> without <code>BITHUMAN_ALLOW_PUBLIC_BIND=1</code> (exit 2), on a machine without ffmpeg too. 2.7.4 answered both with &quot;ffmpeg not found&quot; (exit 69) on such a machine.</li>
<li><strong>Action:</strong> <code>curl -fsSL https://install.bithuman.ai | sh</code>, or <code>brew upgrade bithuman-cli</code>.</li>
</ul>]]></description>
    </item>
    <item>
      <title>CLI 2.7.4 — 2026-09-25</title>
      <link>https://docs.bithuman.ai/changelog#cli-274--2026-09-25</link>
      <guid isPermaLink="true">https://docs.bithuman.ai/changelog#cli-274--2026-09-25</guid>
      <pubDate>Fri, 25 Sep 2026 12:00:00 GMT</pubDate>
      <category>CLI</category>
      <description><![CDATA[<p>Tag <code>cli-v2.7.4</code>.</p>
<ul>
<li><strong>Fixed:</strong> in a live Expression 2 <code>bithuman run</code>, the mouth now moves with the voice. Every audio chunk goes out with the frame rendered from it. On 2.7.3 the voice led the mouth by about 1.6 s on Apple Silicon and 0.55 s on Linux. A reply now starts about 0.5 s after its first audio arrives on an M4.</li>
<li><strong>Fixed:</strong> a live Expression 2 session on Linux bills only the frames you saw. Frames rendered and never shown are no longer billed: the rest of a reply you interrupt, the silent padding after each reply, and the warm-up.</li>
<li><strong>Fixed:</strong> <code>bithuman run --host &lt;address&gt;</code> now works with the built-in conversation. Before, the conversation looked for the server on <code>127.0.0.1</code> and every session failed.</li>
<li><strong>Fixed:</strong> a local Essence 2 or Expression 2 session without ffmpeg stops before it opens and says how to install ffmpeg. The resting clip between turns works with ffmpeg 9.</li>
<li><strong>Changed:</strong> the first frame of an Essence 2 <code>render</code> or <code>run</code> arrives about 1.3 s sooner.</li>
<li><strong>Action:</strong> <code>curl -fsSL https://install.bithuman.ai | sh</code>, or <code>brew upgrade bithuman-cli</code>.</li>
</ul>]]></description>
    </item>
    <item>
      <title>essence2-android 0.6.0 — 2026-09-24</title>
      <link>https://docs.bithuman.ai/changelog#essence2-android-060--2026-09-24</link>
      <guid isPermaLink="true">https://docs.bithuman.ai/changelog#essence2-android-060--2026-09-24</guid>
      <pubDate>Thu, 24 Sep 2026 12:00:00 GMT</pubDate>
      <category>Android</category>
      <description><![CDATA[<ul>
<li><strong>Changed:</strong> after a pause in the conversation, the first frame of the next reply arrives sooner (about 1,090 → 242 ms on a Galaxy S25+). The picture is otherwise unchanged: frames are identical to 0.5.15.</li>
<li><strong>Changed:</strong> a failed download is retried on one budget shared by the whole store, so a service outage is not met with a burst of retries.</li>
<li><strong>Changed:</strong> the <code>-sources.jar</code> and <code>-javadoc.jar</code> on Maven Central are placeholders; the API reference is <a href="https://docs.bithuman.ai/platforms/android/reference">Android API</a>.</li>
<li><strong>Deprecated (still works):</strong> <code>Essence2ModelStore.DEFAULT_MEMBERS</code>. No replacement is needed.</li>
<li><strong>Action:</strong> <code>implementation(&quot;ai.bithuman:essence2-android:0.6.0&quot;)</code>.</li>
</ul>]]></description>
    </item>
    <item>
      <title>expression2-android 0.5.0 — 2026-09-24</title>
      <link>https://docs.bithuman.ai/changelog#expression2-android-050--2026-09-24</link>
      <guid isPermaLink="true">https://docs.bithuman.ai/changelog#expression2-android-050--2026-09-24</guid>
      <pubDate>Thu, 24 Sep 2026 12:00:00 GMT</pubDate>
      <category>Android</category>
      <description><![CDATA[<ul>
<li><strong>Fixed:</strong> lip sync. The mouth moved ahead of the voice; it now lines up. The first frame of each stream is shown twice; a stream still carries the same number of frames.</li>
<li><strong>Changed:</strong> a failed download is retried on one budget shared by the whole store.</li>
<li><strong>Changed:</strong> the <code>-sources.jar</code> and <code>-javadoc.jar</code> on Maven Central are placeholders; the API reference is <a href="https://docs.bithuman.ai/platforms/android/reference">Android API</a>.</li>
<li><strong>Breaking (source only):</strong> <code>Expression2ModelStore.MODEL</code>, <code>CANON</code> and <code>IDLE</code> keep their values but are no longer compile-time constants.</li>
<li><strong>Action:</strong> <code>implementation(&quot;ai.bithuman:expression2-android:0.5.0&quot;)</code>.</li>
</ul>]]></description>
    </item>
    <item>
      <title>Flutter plugin 2.6.16 — 2026-09-24</title>
      <link>https://docs.bithuman.ai/changelog#flutter-plugin-2616--2026-09-24</link>
      <guid isPermaLink="true">https://docs.bithuman.ai/changelog#flutter-plugin-2616--2026-09-24</guid>
      <pubDate>Thu, 24 Sep 2026 12:00:00 GMT</pubDate>
      <category>Flutter</category>
      <description><![CDATA[<ul>
<li><strong>Changed:</strong> Android uses essence2-android 0.6.0 and expression2-android 0.5.0.</li>
<li><strong>Action:</strong> pin <code>ref: flutter-plugin-v2.6.16</code>.</li>
</ul>]]></description>
    </item>
    <item>
      <title>Swift package 2.15.0 — 2026-09-24</title>
      <link>https://docs.bithuman.ai/changelog#swift-package-2150--2026-09-24</link>
      <guid isPermaLink="true">https://docs.bithuman.ai/changelog#swift-package-2150--2026-09-24</guid>
      <pubDate>Thu, 24 Sep 2026 12:00:00 GMT</pubDate>
      <category>Swift</category>
      <description><![CDATA[<p>Essence 2 engine 1.12.1 · Expression 2 engine 2.7.0</p>
<ul>
<li><strong>Fixed:</strong> Expression 2 lip sync. The mouth moved about 65 ms ahead of the voice; it now lines up (about 15 ms). To do this, the first frame of each stream is shown twice; a stream still carries the same number of frames.</li>
<li><strong>New:</strong> <code>Expression2Download.avatar(agentCode:)</code> and <code>Essence2Download.identity(agentCode:)</code> download an avatar file from your app. They fetch the smaller Apple build of the file, check its sha256 and keep it in the app's Caches, so a second call downloads nothing. See <a href="https://docs.bithuman.ai/platforms/ios#download-an-avatar-in-the-app">Apple</a>.</li>
<li><strong>Action:</strong> set <code>from: &quot;2.15.0&quot;</code>, then <code>swift package update</code>.</li>
</ul>]]></description>
    </item>
    <item>
      <title>Flutter plugin 2.6.15 — 2026-09-24</title>
      <link>https://docs.bithuman.ai/changelog#flutter-plugin-2615--2026-09-24</link>
      <guid isPermaLink="true">https://docs.bithuman.ai/changelog#flutter-plugin-2615--2026-09-24</guid>
      <pubDate>Thu, 24 Sep 2026 12:00:00 GMT</pubDate>
      <category>Flutter</category>
      <description><![CDATA[<ul>
<li><strong>Changed:</strong> iOS and macOS use Expression 2 engine 2.7.0, which fixes lip sync.</li>
<li><strong>Action:</strong> pin <code>ref: flutter-plugin-v2.6.15</code>.</li>
<li>iOS and macOS do not build from the published tag yet; use the plugin on Android.</li>
</ul>]]></description>
    </item>
    <item>
      <title>bithuman 2.11.10 — 2026-09-24</title>
      <link>https://docs.bithuman.ai/changelog#bithuman-21110--2026-09-24</link>
      <guid isPermaLink="true">https://docs.bithuman.ai/changelog#bithuman-21110--2026-09-24</guid>
      <pubDate>Thu, 24 Sep 2026 12:00:00 GMT</pubDate>
      <category>Python</category>
      <description><![CDATA[<ul>
<li><strong>Fixed:</strong> Expression 2 lip sync on macOS. The bundled Apple renderer was out of sync by 40–70 ms; it now stays within 25 ms.</li>
<li><strong>Fixed:</strong> when a reply is interrupted, <code>AsyncBithuman</code> no longer bills the frames the interruption throws away. Before, an interrupted reply could add several seconds of talking time.</li>
<li><strong>Changed:</strong> <code>python -m bithuman render &lt;avatar&gt; &lt;audio&gt;</code> and <code>python -m bithuman list</code> use the same command line as the CLI.</li>
<li><strong>Changed:</strong> Expression 2 starts replying about half a second sooner.</li>
<li><strong>Action:</strong> <code>pip install -U bithuman</code>.</li>
</ul>]]></description>
    </item>
    <item>
      <title>bithuman 2.11.9 — 2026-09-24</title>
      <link>https://docs.bithuman.ai/changelog#bithuman-2119--2026-09-24</link>
      <guid isPermaLink="true">https://docs.bithuman.ai/changelog#bithuman-2119--2026-09-24</guid>
      <pubDate>Thu, 24 Sep 2026 12:00:00 GMT</pubDate>
      <category>Python</category>
      <description><![CDATA[<ul>
<li><strong>Fixed:</strong> a rendered MP4's sound starts on its first sample. <code>python -m bithuman</code> wrote the audio 64 ms late, so the mouth moved ahead of the voice on every render.</li>
<li><strong>Fixed:</strong> Expression 2 lip sync: the mouth no longer leads the voice.</li>
<li><strong>Changed:</strong> <code>AsyncBithuman</code> streams Expression 2 at a steady 20 frames a second, through replies and interruptions.</li>
<li><strong>Changed:</strong> a first render downloads less: the 8-second speech encoder is fetched only when a render needs it.</li>
<li><strong>Action:</strong> <code>pip install -U bithuman</code>.</li>
</ul>]]></description>
    </item>
    <item>
      <title>CLI 2.7.3 — 2026-09-24</title>
      <link>https://docs.bithuman.ai/changelog#cli-273--2026-09-24</link>
      <guid isPermaLink="true">https://docs.bithuman.ai/changelog#cli-273--2026-09-24</guid>
      <pubDate>Thu, 24 Sep 2026 12:00:00 GMT</pubDate>
      <category>CLI</category>
      <description><![CDATA[<p>Tag <code>cli-v2.7.3</code>.</p>
<ul>
<li><strong>Changed:</strong> one short command line. <code>bithuman --help</code> lists 13 commands and 10 flags; <code>run</code> takes <code>--host</code> and <code>--port</code>. <code>render &lt;avatar&gt; &lt;audio&gt;</code> takes the audio as its second argument, writes <code>&lt;avatar&gt;.mp4</code> unless you pass <code>-o</code>, and, like <code>run</code> and <code>open</code>, accepts an agent code or a sample avatar's name and downloads it on first use.</li>
<li><strong>Changed:</strong> every old spelling (<code>-a</code>, <code>--offscreen</code>, <code>--cloud</code>, <code>--allow-public-bind</code>, <code>chat</code>, <code>info</code>, <code>avatars</code>, …) still works until 2.9.0 and prints one line on stderr naming what to use instead; <code>--json</code> output is unchanged. The full list is in <a href="https://docs.bithuman.ai/platforms/cli/reference#renamed-in-273">Renamed in 2.7.3</a>.</li>
<li><strong>Action:</strong> <code>curl -fsSL https://install.bithuman.ai | sh</code>, or <code>brew upgrade bithuman-cli</code>.</li>
</ul>]]></description>
    </item>
    <item>
      <title>CLI 2.7.2 — 2026-09-23</title>
      <link>https://docs.bithuman.ai/changelog#cli-272--2026-09-23</link>
      <guid isPermaLink="true">https://docs.bithuman.ai/changelog#cli-272--2026-09-23</guid>
      <pubDate>Wed, 23 Sep 2026 12:00:00 GMT</pubDate>
      <category>CLI</category>
      <description><![CDATA[<p>Tag <code>cli-v2.7.2</code>.</p>
<ul>
<li><strong>Fixed:</strong> an Essence 2 or Expression 2 <code>bithuman render</code> no longer opens a second, billed Essence 1 session. Every such render since 2.6.4 was billed 1–2 extra credits.</li>
<li><strong>Changed:</strong> you are billed for talking, never for an open room: <code>bithuman run</code> no longer bills the silence between turns, and the managed voice bills the agent's speech, not the session's length.</li>
<li><strong>Changed:</strong> the reply starts about half a second after you stop talking, and Expression 2 on a Mac answers about 4 seconds sooner. The default voice model is <code>gpt-realtime-2.1-mini</code>.</li>
<li><strong>Fixed:</strong> <code>bithuman run</code> works on a fresh machine. Linux ships <code>livekit-server</code>; a missing Python or an old <code>livekit-server</code> is refused with the exact install line.</li>
<li><strong>Changed:</strong> Essence 2 renders faster on a Linux CPU, and <code>bithuman render</code> prints no internal diagnostics.</li>
<li><strong>Action:</strong> <code>curl -fsSL https://install.bithuman.ai | sh</code>, or <code>brew upgrade bithuman-cli</code>.</li>
</ul>]]></description>
    </item>
    <item>
      <title>Swift package 2.14.4 — 2026-09-23</title>
      <link>https://docs.bithuman.ai/changelog#swift-package-2144--2026-09-23</link>
      <guid isPermaLink="true">https://docs.bithuman.ai/changelog#swift-package-2144--2026-09-23</guid>
      <pubDate>Wed, 23 Sep 2026 12:00:00 GMT</pubDate>
      <category>Swift</category>
      <description><![CDATA[<p>Essence 2 engine 1.12.1 · Expression 2 engine 2.6.5</p>
<ul>
<li><strong>Fixed:</strong> building a Swift package or command-line tool that uses Essence 2 no longer prints <code>.pcm: No such file or directory</code> linker warnings. The engine itself is unchanged.</li>
<li><strong>Action:</strong> set <code>from: &quot;2.14.4&quot;</code>, then <code>swift package update</code>. See <a href="https://docs.bithuman.ai/platforms/ios">Apple</a>.</li>
</ul>]]></description>
    </item>
    <item>
      <title>Flutter plugin 2.6.14 — 2026-09-23</title>
      <link>https://docs.bithuman.ai/changelog#flutter-plugin-2614--2026-09-23</link>
      <guid isPermaLink="true">https://docs.bithuman.ai/changelog#flutter-plugin-2614--2026-09-23</guid>
      <pubDate>Wed, 23 Sep 2026 12:00:00 GMT</pubDate>
      <category>Flutter</category>
      <description><![CDATA[<ul>
<li><strong>Changed:</strong> iOS and macOS use Essence 2 engine 1.12.1.</li>
<li><strong>Action:</strong> pin <code>ref: flutter-plugin-v2.6.14</code>.</li>
<li>iOS and macOS do not build from the published tag yet; use the plugin on Android.</li>
</ul>]]></description>
    </item>
    <item>
      <title>bithuman 2.11.8 — 2026-09-23</title>
      <link>https://docs.bithuman.ai/changelog#bithuman-2118--2026-09-23</link>
      <guid isPermaLink="true">https://docs.bithuman.ai/changelog#bithuman-2118--2026-09-23</guid>
      <pubDate>Wed, 23 Sep 2026 12:00:00 GMT</pubDate>
      <category>Python</category>
      <description><![CDATA[<ul>
<li><strong>Fixed:</strong> <code>AsyncBithuman</code>, the class the LiveKit plugin uses, loads an Essence 2 avatar on macOS. On 2.11.6 and 2.11.7 it failed with &quot;No module named 'bithuman.bindings'&quot;, so a LiveKit agent with an Essence 2 avatar on a Mac could not start.</li>
<li><strong>Changed:</strong> Essence 2 on a Linux CPU renders faster.</li>
<li><strong>Action:</strong> <code>pip install -U bithuman</code>.</li>
</ul>]]></description>
    </item>
    <item>
      <title>LiveKit plugin 1.8.4 — 2026-09-23</title>
      <link>https://docs.bithuman.ai/changelog#livekit-plugin-184--2026-09-23</link>
      <guid isPermaLink="true">https://docs.bithuman.ai/changelog#livekit-plugin-184--2026-09-23</guid>
      <pubDate>Wed, 23 Sep 2026 12:00:00 GMT</pubDate>
      <category>LiveKit</category>
      <description><![CDATA[<ul>
<li><strong>Changed:</strong> <code>model</code> accepts <code>essence-2</code> and <code>expression-2</code>. A model you name is the model that renders, or the session is refused; leave it unset and the avatar's own default is used, as before.</li>
<li><strong>Fixed:</strong> the plugin no longer imports OpenCV, so it installs beside <code>opencv-python-headless</code> without a conflict.</li>
<li><strong>Action:</strong> <code>pip install -U livekit-plugins-bithuman</code>.</li>
</ul>]]></description>
    </item>
    <item>
      <title>Swift package 2.14.3 — 2026-09-23</title>
      <link>https://docs.bithuman.ai/changelog#swift-package-2143--2026-09-23</link>
      <guid isPermaLink="true">https://docs.bithuman.ai/changelog#swift-package-2143--2026-09-23</guid>
      <pubDate>Wed, 23 Sep 2026 12:00:00 GMT</pubDate>
      <category>Swift</category>
      <description><![CDATA[<p>Essence 2 engine 1.12.0 · Expression 2 engine 2.6.5</p>
<ul>
<li><strong>New:</strong> <code>Essence2Kit</code>, a Swift API for Essence 2 with the same shape as <code>Expression2Engine</code>: <code>create</code>, <code>feed</code>, <code>pull</code>, <code>idle(into:)</code>, <code>interrupt</code>, <code>shutdown</code>. It sets the API secret with <code>Essence2Credential.set(_:)</code> and fetches the engine's runtime files for you.</li>
<li><strong>Fixed:</strong> apps that link Essence 2 no longer get a <code>CoreAudioTypes</code> linker warning.</li>
<li><strong>Fixed:</strong> the C header now says what the engine delivers: frames are B, G, R.</li>
<li><strong>New:</strong> <code>be_essence2_last_refusal</code> returns the reason behind a <code>-3</code>.</li>
<li><strong>Action:</strong> set <code>from: &quot;2.14.3&quot;</code> and take the <code>Essence2Kit</code> product. See <a href="https://docs.bithuman.ai/platforms/ios">Apple</a>.</li>
</ul>]]></description>
    </item>
    <item>
      <title>Flutter plugin 2.6.13 — 2026-09-23</title>
      <link>https://docs.bithuman.ai/changelog#flutter-plugin-2613--2026-09-23</link>
      <guid isPermaLink="true">https://docs.bithuman.ai/changelog#flutter-plugin-2613--2026-09-23</guid>
      <pubDate>Wed, 23 Sep 2026 12:00:00 GMT</pubDate>
      <category>Flutter</category>
      <description><![CDATA[<ul>
<li><strong>Changed:</strong> Android uses <code>essence2-android</code> 0.5.15 and <code>expression2-android</code> 0.4.10. iOS and macOS use Essence 2 engine 1.12.0.</li>
<li><strong>Action:</strong> pin <code>ref: flutter-plugin-v2.6.13</code>.</li>
<li>iOS and macOS do not build from the published tag yet; use the plugin on Android.</li>
</ul>]]></description>
    </item>
    <item>
      <title>essence2-android 0.5.15 — 2026-09-23</title>
      <link>https://docs.bithuman.ai/changelog#essence2-android-0515--2026-09-23</link>
      <guid isPermaLink="true">https://docs.bithuman.ai/changelog#essence2-android-0515--2026-09-23</guid>
      <pubDate>Wed, 23 Sep 2026 12:00:00 GMT</pubDate>
      <category>Android</category>
      <description><![CDATA[<ul>
<li><strong>New:</strong> <code>Essence2Credential.set(secret)</code> sets your API secret once. It covers the avatar download and the session, so <code>Essence2ModelStore(context)</code> needs no resolver.</li>
<li><strong>New:</strong> every type an app uses is in <code>ai.bithuman.essence2</code>, including <code>Essence2Credential</code> and <code>Essence2MeteredDoorResolver</code>.</li>
<li><strong>Deprecated:</strong> <code>Essence2Metering.apiSecret</code>. It still works and sets the same value.</li>
<li><strong>Action:</strong> use <code>ai.bithuman:essence2-android:0.5.15</code>, and replace <code>Essence2Metering.apiSecret = …</code> with <code>Essence2Credential.set(…)</code>. See <a href="https://docs.bithuman.ai/platforms/android">Android</a>.</li>
</ul>]]></description>
    </item>
    <item>
      <title>expression2-android 0.4.10 — 2026-09-23</title>
      <link>https://docs.bithuman.ai/changelog#expression2-android-0410--2026-09-23</link>
      <guid isPermaLink="true">https://docs.bithuman.ai/changelog#expression2-android-0410--2026-09-23</guid>
      <pubDate>Wed, 23 Sep 2026 12:00:00 GMT</pubDate>
      <category>Android</category>
      <description><![CDATA[<ul>
<li><strong>New:</strong> <code>Expression2Credential.set(secret)</code> sets your API secret once. It covers the avatar download and the session.</li>
<li><strong>Deprecated:</strong> <code>Expression2Metering.apiSecret</code>. It still works and sets the same value.</li>
<li><strong>Action:</strong> use <code>ai.bithuman:expression2-android:0.4.10</code>, and replace <code>Expression2Metering.apiSecret = …</code> with <code>Expression2Credential.set(…)</code>. See <a href="https://docs.bithuman.ai/platforms/android">Android</a>.</li>
</ul>]]></description>
    </item>
    <item>
      <title>bithuman 2.11.7 — 2026-09-23</title>
      <link>https://docs.bithuman.ai/changelog#bithuman-2117--2026-09-23</link>
      <guid isPermaLink="true">https://docs.bithuman.ai/changelog#bithuman-2117--2026-09-23</guid>
      <pubDate>Wed, 23 Sep 2026 12:00:00 GMT</pubDate>
      <category>Python</category>
      <description><![CDATA[<ul>
<li><strong>Fixed:</strong> <code>AsyncBithuman</code>, the class the LiveKit plugin uses, renders an Essence 2 avatar with the avatar's own teeth, as <code>bithuman.open()</code> does. An avatar file without its teeth is refused when it is opened.</li>
<li><strong>Fixed:</strong> on a busy machine (a CI runner, a container with a CPU limit), <code>render()</code> no longer refuses with &quot;no frames came out of that render&quot; when the audio has speech in it.</li>
<li><strong>Changed:</strong> live sessions bill talking time only. Idle frames are free, an Expression 2 streaming session now reports its usage, and <code>shutdown()</code> sends the session's last report.</li>
<li><strong>Changed:</strong> Essence 2 on a Linux CPU renders faster and uses less memory.</li>
<li><strong>Action:</strong> <code>pip install -U bithuman</code>.</li>
</ul>]]></description>
    </item>
    <item>
      <title>Swift package 2.14.2 — 2026-09-23</title>
      <link>https://docs.bithuman.ai/changelog#swift-package-2142--2026-09-23</link>
      <guid isPermaLink="true">https://docs.bithuman.ai/changelog#swift-package-2142--2026-09-23</guid>
      <pubDate>Wed, 23 Sep 2026 12:00:00 GMT</pubDate>
      <category>Swift</category>
      <description><![CDATA[<p>Essence 2 engine 1.11.0 · Expression 2 engine 2.6.5</p>
<ul>
<li><strong>Changed:</strong> both engines bill talking time only; idle is free.</li>
<li><strong>Changed:</strong> Expression 2 now uses your API secret, like Essence 2 (<code>Expression2Credential.set(_:)</code> or <code>BITHUMAN_API_SECRET</code>).</li>
<li><strong>Changed:</strong> if the service cannot be reached when a session starts, <code>create</code> refuses with a retryable error. After the secret is accepted, a network loss is tolerated for 5 minutes of rendered video.</li>
<li><strong>New:</strong> <code>BITHUMAN_API_KEY</code> is read as a deprecated alias.</li>
<li><strong>Action:</strong> set <code>from: &quot;2.14.2&quot;</code>, then <code>swift package update</code>. See <a href="https://docs.bithuman.ai/platforms/ios">Apple</a>.</li>
</ul>]]></description>
    </item>
    <item>
      <title>expression2-android 0.4.9 — 2026-09-23</title>
      <link>https://docs.bithuman.ai/changelog#expression2-android-049--2026-09-23</link>
      <guid isPermaLink="true">https://docs.bithuman.ai/changelog#expression2-android-049--2026-09-23</guid>
      <pubDate>Wed, 23 Sep 2026 12:00:00 GMT</pubDate>
      <category>Android</category>
      <description><![CDATA[<ul>
<li><strong>Changed:</strong> on-device Expression 2 sessions use your API secret and bill talking time; idle is free. <code>Expression2Avatar.create</code> throws <code>Expression2Exception</code> without a secret.</li>
<li><strong>New:</strong> <code>Expression2Metering</code> (<code>apiSecret</code>, <code>apiBaseUrl</code>, <code>installId</code>, <code>stateDir</code>).</li>
<li><strong>New:</strong> after the secret is accepted, a network loss is tolerated for 5 minutes of rendered video; usage that could not be sent is kept and sent at the next start.</li>
<li><strong>Action:</strong> set <code>Expression2Metering.apiSecret</code> before <code>create</code>, then use <code>ai.bithuman:expression2-android:0.4.9</code>. See <a href="https://docs.bithuman.ai/platforms/android">Android</a>.</li>
</ul>]]></description>
    </item>
    <item>
      <title>essence2-android 0.5.14 — 2026-09-23</title>
      <link>https://docs.bithuman.ai/changelog#essence2-android-0514--2026-09-23</link>
      <guid isPermaLink="true">https://docs.bithuman.ai/changelog#essence2-android-0514--2026-09-23</guid>
      <pubDate>Wed, 23 Sep 2026 12:00:00 GMT</pubDate>
      <category>Android</category>
      <description><![CDATA[<ul>
<li><strong>Changed:</strong> talking time is billed; idle frames are free.</li>
<li><strong>New:</strong> after the secret is accepted, a network loss is tolerated for 5 minutes of rendered video, then render calls throw a retryable <code>MeteringRefused</code>.</li>
<li><strong>New:</strong> <code>Essence2Metering.stateDir</code>; usage that could not be sent is kept for the next session.</li>
<li><strong>Action:</strong> use <code>ai.bithuman:essence2-android:0.5.14</code>.</li>
</ul>]]></description>
    </item>
    <item>
      <title>API — 2026-09-23</title>
      <link>https://docs.bithuman.ai/changelog#api--2026-09-23</link>
      <guid isPermaLink="true">https://docs.bithuman.ai/changelog#api--2026-09-23</guid>
      <pubDate>Wed, 23 Sep 2026 12:00:00 GMT</pubDate>
      <category>API</category>
      <description><![CDATA[<ul>
<li><strong>Changed:</strong> revealing a stored API secret is console-only. <code>GET /v2/{user_id}/api-secrets/{alias}/get-value</code> with an <code>api-secret</code> returns <code>403 SECRET_REVEAL_CONSOLE_ONLY</code>. See <a href="https://docs.bithuman.ai/api/api-keys#reveal-an-api-secret">API secrets</a>.</li>
<li><strong>Changed:</strong> short legacy-format secrets work only if bitHuman has them on record; create a new secret if an old one returns <code>401</code>.</li>
<li><strong>New:</strong> <code>POST /v1/runtime-tokens/mint</code> takes <code>&quot;scope&quot;: &quot;livekit-cloud&quot;</code>: a one-hour token that starts one agent's avatar in one room. Pass it to the LiveKit plugin instead of your secret (<a href="https://docs.bithuman.ai/platforms/livekit#authenticate">LiveKit</a>).</li>
</ul>]]></description>
    </item>
    <item>
      <title>essence2-android 0.5.13 — 2026-09-23</title>
      <link>https://docs.bithuman.ai/changelog#essence2-android-0513--2026-09-23</link>
      <guid isPermaLink="true">https://docs.bithuman.ai/changelog#essence2-android-0513--2026-09-23</guid>
      <pubDate>Wed, 23 Sep 2026 12:00:00 GMT</pubDate>
      <category>Android</category>
      <description><![CDATA[<ul>
<li><strong>Fixed:</strong> the AAR ships its own keep rule for its native bridge, so a release build with <code>isMinifyEnabled = true</code> works whatever <code>proguardFiles(...)</code> you use.</li>
<li><strong>Action:</strong> use <code>ai.bithuman:essence2-android:0.5.13</code> or newer.</li>
</ul>]]></description>
    </item>
    <item>
      <title>CLI 2.7.1 — 2026-09-23</title>
      <link>https://docs.bithuman.ai/changelog#cli-271--2026-09-23</link>
      <guid isPermaLink="true">https://docs.bithuman.ai/changelog#cli-271--2026-09-23</guid>
      <pubDate>Wed, 23 Sep 2026 12:00:00 GMT</pubDate>
      <category>CLI</category>
      <description><![CDATA[<p>Tag <code>cli-v2.7.1</code>.</p>
<ul>
<li><strong>New:</strong> Linux arm64 binary (Graviton, Ampere, arm64 VMs and containers).</li>
<li><strong>Fixed:</strong> <code>login --with-token</code> checks the secret before storing it (exit 77 <code>TOKEN_REJECTED</code>, 69 <code>TOKEN_UNVERIFIED</code>).</li>
<li><strong>Fixed:</strong> a secret revoked during an Essence 1 session stops the session.</li>
<li><strong>Changed:</strong> <code>account --json</code> names the config file as the credential <code>source</code> when <code>login</code> stored it.</li>
<li><strong>Action:</strong> <code>curl -fsSL https://install.bithuman.ai | sh</code>.</li>
</ul>]]></description>
    </item>
    <item>
      <title>Swift package 2.14.1 — 2026-09-23</title>
      <link>https://docs.bithuman.ai/changelog#swift-package-2141--2026-09-23</link>
      <guid isPermaLink="true">https://docs.bithuman.ai/changelog#swift-package-2141--2026-09-23</guid>
      <pubDate>Wed, 23 Sep 2026 12:00:00 GMT</pubDate>
      <category>Swift</category>
      <description><![CDATA[<ul>
<li><strong>Fixed:</strong> a macOS app built in Xcode can embed the frameworks.</li>
<li><strong>Fixed:</strong> <code>Essence2</code> declares its own linker settings; no manual <code>c++</code>, <code>VideoToolbox</code>, <code>Accelerate</code> or <code>CoreML</code>.</li>
<li><strong>Fixed:</strong> release builds of <code>Expression2</code> no longer write files to <code>/tmp</code>.</li>
</ul>]]></description>
    </item>
  </channel>
</rss>
