CowAgent's LLM protocol layer carries the highest activity risk — 2 functions to address first

CowAgent's agent_stream.py and google_gemini_bot.py dominate the fire quadrant with cyclomatic complexity above 120 and up to 11 levels of nesting, making them live regression risks under active development.

Stephen Collins ·
oss python refactoring code-health
Activity Risk20.26Low
Hottest Function_call_llm_stream

Antipatterns Detected

complex_branching10deeply_nested10exit_heavy10god_function10long_function9

Key Points

What is a god function and why does it matter in CowAgent?

A god function is a single function that has accumulated so many responsibilities — and so many callees — that it effectively controls a disproportionate share of the system's behavior. In structural terms, it typically shows up as a combination of high cyclomatic complexity, high fan-out, and long length. The problem is twofold: it is nearly impossible to test in isolation because it touches so many other parts of the system, and any change to it risks breaking behaviors that appear unrelated. In CowAgent, every one of the top four hotspots is flagged as a god function — including `send` in `channel/wechatmp/wechatmp_channel.py` with a fan-out of 53 and `_call_llm_stream` with a fan-out of 45 — meaning a significant portion of the system's critical complexity is concentrated in just a handful of functions.

How do I reduce cyclomatic complexity in Python?

The most direct technique is extract-method refactoring: identify a coherent cluster of branches or a deeply nested block and move it into a named private function with a clear single responsibility, replacing the original code with a call to that function. As a practical threshold, cyclomatic complexity above 15 warrants splitting, and above 30 it warrants immediate attention — the top functions in CowAgent are at 55, 91, 120, and 124, which are well into territory where full decomposition is the only realistic path. A concrete first step for `call_with_tools` in `models/gemini/google_gemini_bot.py` (CC 124, ND 11) is to identify the innermost nested blocks — the ones that push nesting to levels 9, 10, and 11 — and extract each into its own function; this alone can cut both CC and ND substantially without changing any external behavior. Pair each extraction with a test that pins the behavior of the new sub-function before touching the parent.

Is CowAgent actively maintained?

Yes — the data shows clear signs of active development. `_call_llm_stream` in `agent/protocol/agent_stream.py` was touched 5 times in the last 30 days and has 0 days since its last change, and `call_with_tools` in `models/gemini/google_gemini_bot.py` was touched twice in the last 30 days and last changed 19 days ago. At the same time, other critical functions like `send` in `channel/wechatmp/wechatmp_channel.py` and `call_with_tools` in `models/modelscope/modelscope_bot.py` have sat untouched for 36 days each, indicating that not all parts of the codebase receive equal attention. Active development and significant structural debt are not mutually exclusive — CowAgent shows both simultaneously, with 267 functions in the fire quadrant and 660 in the debt quadrant.

How do I reproduce this analysis?

The analysis was produced using the Hotspots CLI, available at github.com/hotspots-dev/hotspots, against commit `fb341b8` of `zhayujie/CowAgent`. After running `git checkout fb341b8` in a local clone of the repository, execute `hotspots analyze . --mode snapshot --explain-patterns --force` to reproduce the full results. The same command works on any local git repository without additional configuration.

What does activity-weighted risk mean?

Activity-weighted risk combines structural complexity — derived from cyclomatic complexity, nesting depth, and fan-out — with recent commit frequency, so that functions which are both hard to understand and actively changing score the highest. A function with cyclomatic complexity 80 that hasn't been touched in two years scores much lower than one with CC 20 that is committed to every week, because the dormant function poses lower near-term regression risk even though it looks more complex in isolation. This prioritization is intentional: it directs refactoring effort toward functions where a bug is most likely to be introduced right now, not just where the code happens to look complicated. In CowAgent, `_call_llm_stream` exemplifies this — CC 120 combined with 5 commits in 30 days gives it the highest activity-weighted risk score in the repository at 20.26.

CowAgent’s highest-priority risk sits in its LLM protocol and model-integration layer: _call_llm_stream in agent/protocol/agent_stream.py carries a cyclomatic complexity of 120 and was touched 5 times in the last 30 days, earning an activity-weighted risk score of 20.3 — making it a live regression risk, not a cleanup backlog item. CowAgent is a multi-channel AI agent platform with 1,724 analyzed functions, 451 of which rank as critical — a concentration that signals systemic structural pressure across the codebase. Of those, 267 fall in the “fire” quadrant, meaning they are simultaneously complex and under active change, compounding the regression surface right now.

The table below ranks functions by activity-weighted risk — a score that multiplies structural complexity by recent commit frequency. A function that is both hard to understand (high cyclomatic complexity) and actively changing is a higher priority than one that is complex but untouched. CC = cyclomatic complexity (independent execution paths); ND = max nesting depth; FO = fan-out (distinct callees).

Top 5 Hotspots

FunctionFileRiskCCNDFO
_call_llm_streamagent/protocol/agent_stream.py20.3120745
call_with_toolsmodels/gemini/google_gemini_bot.py19.91241123
on_handle_contextplugins/godcmd/godcmd.py19.3191751
_load_tools_from_initagent/tools/tool_manager.py18.935811
executeagent/tools/bash/bash.py18.871634

Hotspot Analysis

_call_llm_stream — agent/protocol/agent_stream.py

Based on its name and location in the agent protocol layer, this function almost certainly orchestrates streaming responses from a language model — managing incremental output chunks, likely handling multiple model backends and error conditions along the way. A cyclomatic complexity of 120 means there are at least 120 independent execution paths through it, each one a required test case and a potential regression surface. With a nesting depth of 7, a fan-out of 45 distinct callees, and 5 commits touching it in the last 30 days (days since last change: 0), this is CowAgent’s single highest-urgency function — complex, broadly coupled, and actively changing right now.

Recommendation: Before any refactoring, write characterization tests that capture current streaming behavior across representative input shapes; then extract the per-backend dispatch logic and the chunk-accumulation logic into dedicated private functions to bring CC below 20 and fan-out below 15.

call_with_tools — models/gemini/google_gemini_bot.py

This function, situated in the Gemini model integration, almost certainly manages the tool-calling protocol between CowAgent and Google’s Gemini API — routing tool invocations, handling responses, and likely managing retries or multi-turn cycles. Its cyclomatic complexity of 124 is the highest in the analyzed set, its nesting depth of 11 is an extreme outlier (strong refactoring signal is ND 8+), and it has been touched twice in the last 30 days with an activity-weighted risk score of 19.9. The combination of god-function coupling, exit-heavy branching, and ongoing active development makes this a live regression risk: every commit navigates 124 execution paths and 11 levels of nested logic.

Recommendation: Map the fan-out of 23 callees to identify which tool-dispatch branches can be extracted into a dedicated tool-response handler; target the deepest nesting levels first, as collapsing even two levels of nesting will make the remaining logic substantially easier to test and reason about.

Patterns Found

Antipatterns detected across the top functions in this snapshot:

PatternOccurrences
complex_branching10
deeply_nested10
exit_heavy10
god_function10
long_function9

These labels belong to two tiers — Tier 1 (structural): complex_branching, deeply_nested, exit_heavy, long_function, god_function. Tier 2 (relational/temporal): hub_function, cyclic_hub, middle_man, neighbor_risk, stale_complex, churn_magnet, shotgun_target, volatile_god.

Key Takeaways

  • _call_llm_stream in agent/protocol/agent_stream.py has CC 120, fan-out 45, and was touched 5 times in the last 30 days — write characterization tests covering its streaming paths before the next commit lands.
  • call_with_tools in models/gemini/google_gemini_bot.py has the deepest nesting in the dataset at ND 11; collapsing the innermost nesting levels first will yield the fastest improvement in readability and testability without requiring a full rewrite.

Reproduce This Analysis

git clone https://github.com/zhayujie/CowAgent
cd CowAgent
git checkout fb341b869b14339e92aa110d019ded7a90707817
hotspots analyze . --mode snapshot --explain-patterns --force

To run the same analysis on your own codebase, run hotspots analyze . --mode snapshot in any local git repo — no configuration required.

Hotspots highlights structural and activity risk — not “bad code.” Findings are a prioritization aid, not a bug predictor. Editorial policy →

Run this on your own codebase

Hotspots runs locally in under a minute — no account, no data leaves your machine.

macOS
$ brew install Stephen-Collins-tech/tap/hotspots
Linux / cargo
$ cargo install hotspots-cli
Run in any repo
$ hotspots analyze .
★ Star on GitHub

Related Analyses