Skip to content

refactor(llm): migrate iMessage + Telegram call_llm onto codec_llm (A-12 bridges)#71

Merged
AVADSA25 merged 1 commit into
mainfrom
fix/pr3-a12-bridges
May 22, 2026
Merged

refactor(llm): migrate iMessage + Telegram call_llm onto codec_llm (A-12 bridges)#71
AVADSA25 merged 1 commit into
mainfrom
fix/pr3-a12-bridges

Conversation

@AVADSA25
Copy link
Copy Markdown
Owner

Summary

PR-3E-bridges. The two outbound bridges hand-rolled the same OpenAI chat/completions text call — both call_llm text sites now route through codec_llm.call. Design-first → docs/PR3E-BRIDGES-DESIGN.md. The simplest tranche: never-raise is the default, so this is a near-mechanical swap.

Migrated

  • codec_telegram.call_llm (text site :482)
  • codec_imessage.call_llm (text site :343)

Bridges want graceful degradation, so the default never-raise is exactly right: codec_llm.call returns "" on error/no-choices/timeout/empty, mapped back to the bridge's None-on-failure contract via content if content else None. Preserved: enable_thinking=False (by passing llm_cfg["kwargs"] minus chat_template_kwargs), Bearer-iff-api_key auth, the 1500/0.7 tuning. <think> stripping moves into codec_llm. Removed a now-dead import re in codec_imessage.

The vision sites in both bridges (llm_cfg["vision_url"]) are A-11 / codec_vision, not this tranche — left untouched.

Test plan

  • tests/test_llm_bridges.py — 8 tests: each bridge returns content on success; returns None on empty/failure (graceful-degradation contract); passes base_url/model/api_key through and filters chat_template_kwargs out of extra_kwargs; source invariants (each calls codec_llm.call(, /chat/completions count down to 1 = only the vision site remains).
  • Full suite: 1431 passed, 23 known-baseline failures, zero new, 74 skipped.
  • Ruff: per-file F-delta vs origin/main = 0 (removed the dead re import that the migration orphaned).
  • No skills/ touched → no manifest regen.
  • Manual (Mac Studio): a Telegram + an iMessage round-trip reply; confirm graceful no-reply when the LLM is down.

🤖 Generated with Claude Code

…-12 bridges)

PR-3E-bridges. The two outbound bridges hand-rolled the same OpenAI
chat/completions text call; both now route through codec_llm.call.

Bridges WANT graceful degradation, so the default never-raise behavior is
exactly right: codec_llm.call returns "" on error/no-choices/timeout/empty,
which maps back to the bridge's None-on-failure contract via
`content if content else None`. enable_thinking=False is preserved by passing
llm_cfg["kwargs"] minus chat_template_kwargs; <think> stripping moves into
codec_llm. Auth parity (Bearer iff api_key) and the 1500/0.7 tuning are kept.

The vision sites in both bridges (llm_cfg["vision_url"]) are A-11 / codec_vision,
not this tranche — left untouched. Removed a now-dead `import re` in
codec_imessage (its only use was the inline <think> strip).

Tests: tests/test_llm_bridges.py (8 — each bridge returns content on success,
returns None on empty/failure (graceful-degradation contract), passes
base_url/model/api_key through and filters chat_template_kwargs out of
extra_kwargs; source invariants confirm codec_llm.call + only the vision
/chat/completions site remains). Full suite 1431 passing, 23 known-baseline
failures, zero new. Net -50 LOC. Zero net-new ruff. No skills/ touched.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@AVADSA25 AVADSA25 merged commit cb26108 into main May 22, 2026
1 check passed
AVADSA25 added a commit that referenced this pull request May 23, 2026
…omplete) (#79)

PR-3F, Option 1 (scoped). The audit's full BridgeRouter (unifying process_message)
was high-risk/low-value: the headline call_llm dup was already fixed in #71, and
the two process_message flows have intentionally drifted (telegram audio/Gemini/
briefing; imessage goals/intent) — forcing them into one pipeline would risk
regressing a working channel. So this extracts ONLY the genuinely-identical
helpers and leaves process_message per-bridge.

New codec_bridges.py:
- load_dispatch() / try_skill(text) — the lazy codec_dispatch loader + skill
  match (+ the _SKIP_SKILLS terminal/GUI set), one copy.
- call_llm(channel, text, llm_cfg, ...) — the canonical bridge LLM call: persona
  selected by channel, routed through codec_llm.call, None-contract preserved,
  chat_template_kwargs filtered.
- save_to_memory(channel, conv_id, user, assistant) — the memory.db write under
  session_id "<channel>-<conv_id>".

codec_telegram + codec_imessage now `from codec_bridges import try_skill` and keep
thin channel-injecting wrappers for call_llm / save_to_memory, so every
process_message call site is unchanged (telegram audio + imessage goal-tracking
untouched). Removed telegram's now-dead sqlite3 import. codec_bridges.py is the
documented "add a channel" seed (CLAUDE.md §1: future WhatsApp/Discord).

Updated 2 stale #71 source-invariants (the bridges now delegate via codec_bridges
rather than calling codec_llm.call directly).

Tests: tests/test_bridges.py (10 — call_llm persona/None/kwargs-filter/history+
override, try_skill skip-set/run/no-match, save_to_memory channel-prefixed
session_id, source invariants). Full suite 1502 passing, 23 known-baseline
failures, zero new. Net -148 LOC in the bridges. Zero net-new ruff.

**Audit-A (Wave 3, code quality) is complete** — A-1..A-22 all closed or verified.

Co-authored-by: Mickael Farina <farina.mickael@gmail.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants