Nanobot

Nanobot adds provider stream timing and Codex tracing

Nanobot proposes Langfuse tracing for its Codex provider and structured provider stream timing, while a Telegram report says rich messages disappear whenever streaming is enabled.

← Back to homeOriginal source ↗

HKUDS/nanobot PR #5520 is the inspected primary source: “Add Langfuse tracing to the Codex provider.” The related records below were inspected as supporting context rather than independent confirmation.

The facts

- HKUDS/nanobot PR #5520 was created 2026-08-24T19:04:22Z and was open at inspection; its title is “Add Langfuse tracing to the Codex provider.” - HKUDS/nanobot PR #5518 was created 2026-08-24T17:29:21Z and was open at inspection; its title is “fix(usage): record provider stream timing.” - HKUDS/nanobot issue #5516 was created 2026-08-24T16:29:12Z and was open at inspection; its title is “Telegram: rich messages never render when streaming is enabled; Bot API 10.1-10.3 drafts can fix this.” - The repository reported 47353 stars, 732 open issues, default branch main, and last push 2026-08-24T18:14:05Z. - The latest tagged-release baseline checked was v0.3.0 published 2026-07-25T08:08:47Z.

What changed

HKUDS/nanobot PR #5520 reports: Summary Codex had no Langfuse tracing (only the OpenAI-compatible provider did, via an SDK client-swap trick that doesn't apply to Codex's raw httpx + OAuth transport). Adds tracing through Langfuse's native SDK: one generation per real HTTP request (main and compaction separately), with model, input, output, usage, and error info. Fully fail-safe: any Langfuse issue degrades to a no-op, never affects the actual Codex response. Generation finalization is idempotent and cancellation-safe; a rejected compaction response traces as an error, not a false success. Testing 20 new/updated tests covering success, error, missing package, tracing failures, compaction, cancellation, and update failures. Full suite, ruff, and basedpyright pass. Verified end-to-end on a live deployment.

HKUDS/nanobot PR #5518 reports: Summary measure TTFT and generation time at each physical streaming provider attempt attach timing before the unified usage observer persists the call preserve retry/fallback granularity and existing provider-supplied timing Root cause The runner populated streaming timing only after chat_stream_with_retry() returned, while the usage observer records each physical attempt inside _safe_chat_stream(). As a result, SQLite rows had zero timing even though per-turn WebUI usage showed valid values. Verification 981 provider tests passed basedpyright: 0 errors, 0 warnings Ruff passed diff check passed

HKUDS/nanobot issue #5516 reports: Problem / Motivation rich_messages: true (opt-in since #4488 / #4539) and streaming: true (the default) are currently mutually exclusive: with streaming enabled, sendRichMessage is never called, and the final message is always delivered via legacy HTML editMessageText. There are two reasons. 1. The rich branch at stream end is unreachable (dead code)** In nanobot/channels/telegram/runtime.py, send_delta(..., stream_end=True): The rich branch is guarded by if not buf.message_id, but execution can only reach it when buf.message_id is already set (the earlier check returns otherwise). So the branch can never run, and in practice sendRichMessage fires only in the non-streaming send_message path. 2. The delete-and-resend shape was the real problem in #4470** The original design (PR #4423) sent a rich message at stream end and deleted the streaming preview. That caused flickering and lost line breaks (#4470), so rich at stream end was skipped whenever a preview exists — which, with streaming, is always. The issue is not "rich after streaming" itself, it's that delete-and-resend changes the message identity. Proposed Solution The Bot API has since grown the pieces needed to make rich and streaming work together natively: **Bot API 10.1** (June 11, 2026) sendRichMessageDraft — stream partial rich messages natively: https://core.telegram.org/bots/api#sendrichmessagedraft editMessageText gained a rich_message parameter — upgrade an existing message to rich **in place**, without delete-and-resend: https://core.telegram.org/bots/api#editmessagetext **Bot API 10.3** (Aug 24,

Why it matters

Observability is not decoration when streamed delivery and rich-message rendering disagree; operators need timing tied to the channel outcome users actually saw. The operator test is whether the system remains bounded and its receipts still describe the action after failure, retry or restart.

Current

The primary record was open when captured on 2026-08-25. The tagged-release baseline was v0.3.0 published 2026-07-25T08:08:47Z. Repository metadata, full source bodies, current pull requests and issues, releases, Google News, Hacker News, Lobsters, Metamesh and the rendered ClawCharts row were inspected. ClawCharts selected the subject; it did not prove the claim.

Evidence

The primary URL is https://github.com/HKUDS/nanobot/pull/5520. Supporting records are https://github.com/HKUDS/nanobot/pull/5518 and https://github.com/HKUDS/nanobot/issues/5516. Source bodies, timestamps and states are preserved in the daily evidence bundle. Test counts and reproductions remain attributed to their authors unless identified as independently rerun.

Source boundary

Open work is described as open, closed work as closed, and operator reports as reports. A pull request is evidence of proposed or reviewed direction, not proof of a shipped release. Search residue, package mirrors and historically published source spines were excluded.

Operator take

Correlate provider spans with channel delivery receipts, record first-token and completion timing, and test Telegram draft/rich-message fallback under streaming. Preserve a before-state receipt, make the smallest reversible change, and verify the original failure independently.

Caveat

Public project records are mutable. Status, scope and evidence can change after publication. This brief records the inspected state and does not authorize changes to a reader’s deployment.

Source inspected; source state, environment and release boundary remain explicit.