Are we tiny?#
gptme is intended to be small and simple, and focus on doing the right thing in the right way, rather than all the things in all the ways.
The benefits of this approach are many:
It is easier to understand and maintain.
It is easier to contribute to.
It is easier to learn.
It is easier to extend.
It is more fun to work on.
Being aggressive about keeping things small and simple is a way to keep the project maintainable and fun to work on. The fastest way to kill a project is to make it too big and complex, and suffer burnout as a result.
Another major benefit of keeping things small and simple is that it makes it easier for AI to understand and work with the codebase. This is a major goal of the project, and it is important to keep in mind that the simpler the codebase is, the easier it will be for AI to work with it:
“The simpler your API is, the more effectively the AI can harness it when generating code.”
—Kenneth Reitz (and many others)
To that end, in this document we will present some statistics about the current state of the project, trying to be mindful to keep an eye on this page and make sure we are not growing too much.
Startup time#
$ make bench-import
make[2]: Entering directory '/home/runner/work/gptme/gptme'
Benchmarking import time for gptme
time poetry run python -X importtime -m gptme --model openai --non-interactive 2>&1 | grep "import time" | cut -d'|' -f 2- | sort -n | tail -n 10
273496 | gptme.mcp.client
273839 | gptme.tools.mcp_adapter
279904 | openai.types
351220 | openai
442286 | gptme.llm.llm_openai
696157 | gptme.llm
698172 | gptme.commands
799375 | gptme.chat
1235655 | gptme.cli
1289364 | gptme
real 0m2.154s
user 0m1.738s
sys 0m0.301s
make[2]: Leaving directory '/home/runner/work/gptme/gptme'
$ make bench-startup
make[2]: Entering directory '/home/runner/work/gptme/gptme'
Benchmarking startup time for gptme
hyperfine "poetry run gptme '/exit'" -M 5 || poetry run gptme '/exit' || exit 1
Benchmark 1: poetry run gptme '/exit'
Time (mean ± σ): 2.051 s ± 0.022 s [User: 1.797 s, System: 0.244 s]
Range (min … max): 2.029 s … 2.085 s 5 runs
make[2]: Leaving directory '/home/runner/work/gptme/gptme'
Lines of code#
LoC Core#
$ make cloc-core
make[2]: Entering directory '/home/runner/work/gptme/gptme'
cloc gptme/*.py gptme/llm/*.py gptme/util/*.py gptme/tools/base.py gptme/tools/__init__.py gptme/hooks/__init__.py gptme/plugins/__init__.py gptme/lessons/*.py --by-file --hide-rate --quiet | tail -n +2
----------------------------------------------------------------------------------------
File blank comment code
----------------------------------------------------------------------------------------
gptme/llm/llm_openai.py 166 134 715
gptme/llm/models.py 121 120 669
gptme/config.py 186 171 662
gptme/llm/llm_anthropic.py 132 142 618
gptme/logmanager.py 132 158 518
gptme/tools/base.py 129 137 511
gptme/util/cli.py 142 73 498
gptme/prompts.py 137 168 486
gptme/cli.py 74 65 482
gptme/setup.py 113 59 478
gptme/hooks/__init__.py 147 156 450
gptme/chat.py 69 85 382
gptme/util/_telemetry.py 105 121 360
gptme/telemetry.py 85 54 342
gptme/util/prompt.py 83 114 337
gptme/util/context.py 85 131 328
gptme/llm/__init__.py 76 74 307
gptme/util/gh.py 66 86 305
gptme/message.py 65 88 300
gptme/plugins/__init__.py 83 116 248
gptme/tools/__init__.py 67 50 230
gptme/lessons/commands.py 91 48 213
gptme/util/_sound_sounddevice.py 52 52 208
gptme/util/ask_execute.py 54 46 202
gptme/util/sound.py 65 72 200
gptme/util/auto_naming.py 59 70 199
gptme/lessons/parser.py 70 108 192
gptme/lessons/index.py 71 98 183
gptme/llm/validate.py 29 27 173
gptme/llm/llm_openai_models.py 2 11 169
gptme/codeblock.py 37 92 168
gptme/llm/utils.py 54 73 153
gptme/util/__init__.py 31 22 140
gptme/util/cost_display.py 39 31 137
gptme/lessons/hybrid_matcher.py 53 79 132
gptme/util/cost_tracker.py 44 62 112
gptme/lessons/matcher.py 35 47 102
gptme/init.py 23 19 100
gptme/util/tree.py 21 13 91
gptme/lessons/matcher_enhanced.py 26 40 88
gptme/util/export.py 17 25 86
gptme/lessons/auto_include.py 31 26 79
gptme/util/reduce.py 24 35 76
gptme/util/generate_name.py 5 6 69
gptme/util/master_context.py 28 38 66
gptme/session.py 39 63 65
gptme/__version__.py 15 11 64
gptme/util/_sound_cmd.py 22 17 64
gptme/util/uri.py 29 42 59
gptme/util/output_storage.py 26 36 58
gptme/dirs.py 27 14 55
gptme/util/tokens.py 22 16 44
gptme/util/cost.py 12 20 43
gptme/lessons/selector_config.py 18 20 40
gptme/util/file_storage.py 30 47 40
gptme/_keyword_matching.py 35 66 39
gptme/lessons/selector_integration.py 12 11 39
gptme/util/clipboard.py 8 2 35
gptme/util/terminal.py 23 21 34
gptme/util/install.py 13 24 31
gptme/wut.py 13 12 31
gptme/util/content.py 18 24 29
gptme/executor.py 17 26 24
gptme/lessons/__init__.py 7 15 24
gptme/util/useredit.py 12 13 21
gptme/util/interrupt.py 13 18 20
gptme/constants.py 12 16 18
gptme/__init__.py 1 1 8
gptme/__main__.py 1 0 3
----------------------------------------------------------------------------------------
SUM: 3649 3977 13452
----------------------------------------------------------------------------------------
make[2]: Leaving directory '/home/runner/work/gptme/gptme'
LoC LLM#
$ make cloc-llm
make[2]: Entering directory '/home/runner/work/gptme/gptme'
cloc gptme/llm/*.py --by-file --hide-rate --quiet | tail -n +2
---------------------------------------------------------------------------------
File blank comment code
---------------------------------------------------------------------------------
gptme/llm/llm_openai.py 166 134 715
gptme/llm/models.py 121 120 669
gptme/llm/llm_anthropic.py 132 142 618
gptme/llm/__init__.py 76 74 307
gptme/llm/validate.py 29 27 173
gptme/llm/llm_openai_models.py 2 11 169
gptme/llm/utils.py 54 73 153
---------------------------------------------------------------------------------
SUM: 580 581 2804
---------------------------------------------------------------------------------
make[2]: Leaving directory '/home/runner/work/gptme/gptme'
LoC Tools#
$ make cloc-tools
make[2]: Entering directory '/home/runner/work/gptme/gptme'
cloc gptme/tools/*.py gptme/hooks/*.py gptme/plugins/*.py --by-file --hide-rate --quiet | tail -n +2
-------------------------------------------------------------------------------------
File blank comment code
-------------------------------------------------------------------------------------
gptme/tools/shell.py 278 346 1146
gptme/tools/autocompact.py 181 250 590
gptme/tools/subagent.py 183 313 568
gptme/tools/mcp_adapter.py 159 166 519
gptme/tools/base.py 129 137 511
gptme/hooks/__init__.py 147 156 450
gptme/tools/computer.py 151 219 437
gptme/tools/gh.py 85 93 349
gptme/tools/tmux.py 95 159 333
gptme/tools/mcp.py 99 102 311
gptme/tools/_browser_playwright.py 87 33 287
gptme/tools/tts.py 119 132 284
gptme/tools/save.py 56 55 262
gptme/plugins/__init__.py 83 116 248
gptme/tools/patch.py 58 80 244
gptme/tools/lessons.py 92 105 243
gptme/tools/todo.py 95 106 237
gptme/tools/__init__.py 67 50 230
gptme/tools/precommit.py 64 87 189
gptme/tools/morph.py 43 42 178
gptme/tools/python.py 56 49 173
gptme/tools/restart.py 51 81 171
gptme/tools/_browser_thread.py 27 12 157
gptme/tools/form.py 38 43 147
gptme/tools/rag.py 62 74 145
gptme/tools/chats.py 43 49 142
gptme/hooks/token_awareness.py 44 51 141
gptme/hooks/cost_awareness.py 45 56 133
gptme/hooks/cache_awareness.py 95 138 128
gptme/tools/browser.py 59 114 127
gptme/hooks/form_autodetect.py 48 65 126
gptme/tools/complete.py 34 42 116
gptme/tools/choice.py 31 25 107
gptme/tools/parallel.py 28 36 88
gptme/tools/_browser_perplexity.py 25 22 85
gptme/hooks/time_awareness.py 29 31 83
gptme/tools/autocommit.py 37 59 75
gptme/hooks/active_context.py 21 22 61
gptme/tools/screenshot.py 22 28 59
gptme/tools/vision.py 19 12 53
gptme/hooks/cwd_tracking.py 18 25 51
gptme/hooks/markdown_validation.py 36 41 51
gptme/tools/_browser_lynx.py 13 18 40
gptme/hooks/test.py 12 5 33
gptme/tools/youtube.py 10 1 26
gptme/tools/read.py 6 8 13
-------------------------------------------------------------------------------------
SUM: 3180 3854 10147
-------------------------------------------------------------------------------------
make[2]: Leaving directory '/home/runner/work/gptme/gptme'
LoC Server#
$ make cloc-server
make[2]: Entering directory '/home/runner/work/gptme/gptme'
cloc gptme/server --by-file --hide-rate --quiet | tail -n +2
------------------------------------------------------------------------------------
File blank comment code
------------------------------------------------------------------------------------
gptme/server/api_v2_sessions.py 153 154 659
gptme/server/tasks_api.py 171 110 597
gptme/server/openapi_docs.py 177 140 458
gptme/server/api.py 99 97 400
gptme/server/api_v2.py 79 55 352
gptme/server/static/main.js 35 45 316
gptme/server/workspace_api.py 57 55 173
gptme/server/api_v2_agents.py 38 28 164
gptme/server/static/index.html 11 15 148
gptme/server/static/style.css 27 4 143
gptme/server/client.py 60 78 139
gptme/server/cli.py 26 17 137
gptme/server/auth.py 45 69 121
gptme/server/static/computer.html 1 1 90
gptme/server/api_v2_common.py 48 24 69
gptme/server/__init__.py 2 3 3
gptme/server/__main__.py 1 0 3
gptme/server/exceptions.py 5 8 2
gptme/server/constants.py 1 3 1
------------------------------------------------------------------------------------
SUM: 1036 906 3975
------------------------------------------------------------------------------------
make[2]: Leaving directory '/home/runner/work/gptme/gptme'
LoC Tests#
$ make cloc-tests
make[2]: Entering directory '/home/runner/work/gptme/gptme'
cloc tests --by-file --hide-rate --quiet | tail -n +2
-----------------------------------------------------------------------------------------------
File blank comment code
-----------------------------------------------------------------------------------------------
tests/test_tools_shell.py 235 375 680
tests/test_llm_openai.py 174 88 624
tests/test_util_gh_mocked.py 106 92 534
tests/test_tools_subagent.py 197 115 515
tests/test_lessons_commands.py 157 82 422
tests/test_config.py 109 212 413
tests/context/test_task_analyzer.py 119 58 389
tests/test_auto_compact.py 174 146 383
tests/test_util_cli_mcp.py 89 45 380
tests/test_mcp_discovery.py 128 37 351
tests/test_llm_anthropic.py 64 24 348
tests/test_codeblock.py 225 538 342
tests/test_lessons_parser.py 152 176 338
tests/test_integration_phase4.py 66 54 331
tests/test_cli.py 82 57 297
tests/test_lessons_matcher.py 89 80 288
tests/lessons/test_wildcard_matching.py 114 125 287
tests/test_context_selector.py 83 45 254
tests/conftest.py 79 70 250
tests/test_lessons_index.py 84 68 243
tests/test_lessons_integration.py 91 59 242
tests/test_complete.py 56 40 241
tests/test_server_v2.py 69 34 229
tests/test_mcp.py 58 45 207
tests/test_message.py 83 86 204
tests/test_plugins.py 82 70 203
tests/test_lessons_tool.py 55 26 194
tests/test_mcp_adapter.py 65 37 191
tests/test_auto_naming.py 54 41 186
tests/test_execenv.py 52 42 185
tests/test_hooks.py 90 24 184
tests/test_dspy_hybrid.py 65 45 179
tests/test_server_v2_hooks.py 71 52 175
tests/test_tools_time_awareness.py 52 34 155
tests/test_uri.py 54 30 155
tests/test_cost_tracker.py 21 24 154
tests/test_context.py 72 48 152
tests/test_master_context.py 39 24 147
tests/test_file_selector_integration.py 50 23 145
tests/test_tree.py 54 29 142
tests/test_tool_use.py 12 19 140
tests/test_dspy_integration.py 54 32 139
tests/test_tools_tmux.py 64 60 139
tests/test_lesson_selector_integration.py 45 25 138
tests/test_dspy_basic.py 49 31 132
tests/test_tools_patch.py 71 157 131
tests/benchmark_context_selector.py 32 26 130
tests/test_tools_token_awareness.py 59 47 126
tests/test_server.py 42 27 122
tests/test_prompt.py 36 36 120
tests/test_tools_save.py 29 23 119
tests/test_tools_todo.py 53 46 117
tests/test_lessons_status.py 67 96 113
tests/test_cost_awareness_delayed_warning.py 42 32 108
tests/test_server_v2_tool_confirmation.py 32 32 107
tests/test_util_cli.py 35 28 105
tests/test_tools_tts.py 50 58 101
tests/test_parallel.py 27 17 93
tests/test_session.py 40 21 93
tests/test_tools_computer.py 36 27 91
tests/test_util_gh.py 39 28 91
tests/test_llm_validate.py 25 19 90
tests/test_server_v2_auto_stepping.py 20 22 87
tests/test_server_auth.py 40 19 84
tests/context/test_adaptive_compressor.py 35 23 80
tests/test_prompt_tools.py 5 4 77
tests/test_tools.py 45 6 76
tests/test_llm_models.py 27 14 75
tests/test_markdown_validation.py 43 34 75
tests/test_prompts.py 34 31 75
tests/test_shell_issue729.py 50 52 75
tests/test_shell_issue772.py 48 47 73
tests/test_command_completion.py 23 14 71
tests/test_hooks_form_autodetect.py 22 34 68
tests/test_tools_form.py 22 19 67
tests/test_shell_output_mixing_issue408.py 25 29 60
tests/test_server_client.py 33 26 59
tests/test_browser.py 28 23 58
tests/test_chat_history.py 14 12 56
tests/test_server_v2_sse.py 15 13 50
tests/test_custom_providers.py 23 32 49
tests/test_eval.py 9 9 49
tests/test-integration.sh 22 36 43
tests/test_dspy_gepa.py 18 9 39
tests/test_prompt_skills_summary.py 24 22 39
tests/test_reduce.py 11 2 39
tests/test_tools_python.py 28 3 38
tests/test_utils.py 14 17 38
tests/test_util.py 28 51 37
tests/test_message_command.py 13 12 35
tests/test_tools_rag.py 15 8 34
tests/test_hybrid_lessons.py 14 8 33
tests/test_shell_for_loop_issue724.py 16 24 33
tests/test_chat.py 16 28 28
tests/test_telemetry.py 20 15 28
tests/test_xml_format.py 10 31 27
tests/test_chat_config.py 8 7 26
tests/data/example-patch-codeblock.txt 4 0 25
tests/data/example-interrupted.txt 8 0 24
tests/test_tool_loading_duplicate.py 16 15 24
tests/test_tools_shell_multiline.py 7 19 19
tests/test_logmanager.py 8 5 18
tests/test_screenshot.py 9 6 15
tests/test_tools_chats.py 2 0 15
tests/test_browser_lynx.py 7 4 12
-----------------------------------------------------------------------------------------------
SUM: 5577 4972 15917
-----------------------------------------------------------------------------------------------
make[2]: Leaving directory '/home/runner/work/gptme/gptme'
LoC Eval#
$ make cloc-eval
make[2]: Entering directory '/home/runner/work/gptme/gptme'
cloc gptme/eval/**.py --by-file --hide-rate --quiet | tail -n +2
-------------------------------------------------------------------------------------
File blank comment code
-------------------------------------------------------------------------------------
gptme/eval/main.py 72 45 461
gptme/eval/execenv.py 53 92 349
gptme/eval/run.py 58 47 346
gptme/eval/agents.py 22 11 121
gptme/eval/filestore.py 11 8 63
gptme/eval/types.py 15 12 40
gptme/eval/cost.py 12 24 6
gptme/eval/__init__.py 1 0 4
gptme/eval/__main__.py 1 0 3
-------------------------------------------------------------------------------------
SUM: 245 239 1393
-------------------------------------------------------------------------------------
make[2]: Leaving directory '/home/runner/work/gptme/gptme'
LoC Total#
$ make cloc-total
make[2]: Entering directory '/home/runner/work/gptme/gptme'
cloc gptme/eval/cost.py gptme/eval/types.py gptme/eval/suites/basic.py gptme/eval/suites/browser.py gptme/eval/suites/__init__.py gptme/eval/suites/init_projects.py gptme/eval/execenv.py gptme/eval/main.py gptme/eval/filestore.py gptme/eval/agents.py gptme/eval/dspy/metrics.py gptme/eval/dspy/prompt_optimizer.py gptme/eval/dspy/signatures.py gptme/eval/dspy/hybrid_optimizer.py gptme/eval/dspy/cli.py gptme/eval/dspy/tasks.py gptme/eval/dspy/experiments.py gptme/eval/dspy/__main__.py gptme/eval/dspy/__init__.py gptme/eval/__main__.py gptme/eval/__init__.py gptme/eval/run.py gptme/mcp/client.py gptme/mcp/registry.py gptme/mcp/__init__.py gptme/setup.py gptme/llm/utils.py gptme/llm/llm_openai.py gptme/llm/validate.py gptme/llm/llm_anthropic.py gptme/llm/llm_openai_models.py gptme/llm/__init__.py gptme/llm/models.py gptme/commands/export.py gptme/commands/meta.py gptme/commands/llm.py gptme/commands/session.py gptme/commands/__init__.py gptme/commands/base.py gptme/wut.py gptme/init.py gptme/server/api_v2_sessions.py gptme/server/auth.py gptme/server/workspace_api.py gptme/server/openapi_docs.py gptme/server/cli.py gptme/server/constants.py gptme/server/tasks_api.py gptme/server/api_v2_common.py gptme/server/exceptions.py gptme/server/client.py gptme/server/api_v2_agents.py gptme/server/api_v2.py gptme/server/api.py gptme/server/__main__.py gptme/server/__init__.py gptme/cli.py gptme/constants.py gptme/chat.py gptme/codeblock.py gptme/prompts.py gptme/lessons/selector_integration.py gptme/lessons/matcher_enhanced.py gptme/lessons/commands.py gptme/lessons/selector_config.py gptme/lessons/matcher.py gptme/lessons/auto_include.py gptme/lessons/hybrid_matcher.py gptme/lessons/parser.py gptme/lessons/__init__.py gptme/lessons/skills/python-repl/python_helpers.py gptme/lessons/index.py gptme/context/task_analyzer.py gptme/context/adaptive_compressor.py gptme/context/selector/hybrid.py gptme/context/selector/file_selector.py gptme/context/selector/llm_based.py gptme/context/selector/file_config.py gptme/context/selector/file_integration.py gptme/context/selector/config.py gptme/context/selector/rule_based.py gptme/context/selector/__init__.py gptme/context/selector/base.py gptme/context/compress.py gptme/context/config.py gptme/context/__init__.py gptme/tools/subagent.py gptme/tools/save.py gptme/tools/_browser_playwright.py gptme/tools/parallel.py gptme/tools/patch.py gptme/tools/_browser_thread.py gptme/tools/todo.py gptme/tools/autocompact.py gptme/tools/_browser_perplexity.py gptme/tools/tts.py gptme/tools/youtube.py gptme/tools/morph.py gptme/tools/tmux.py gptme/tools/chats.py gptme/tools/rag.py gptme/tools/python.py gptme/tools/computer.py gptme/tools/mcp_adapter.py gptme/tools/restart.py gptme/tools/complete.py gptme/tools/choice.py gptme/tools/gh.py gptme/tools/autocommit.py gptme/tools/mcp.py gptme/tools/vision.py gptme/tools/shell.py gptme/tools/browser.py gptme/tools/read.py gptme/tools/_browser_lynx.py gptme/tools/form.py gptme/tools/__init__.py gptme/tools/lessons.py gptme/tools/precommit.py gptme/tools/screenshot.py gptme/tools/base.py gptme/hooks/cache_awareness.py gptme/hooks/test.py gptme/hooks/markdown_validation.py gptme/hooks/time_awareness.py gptme/hooks/cwd_tracking.py gptme/hooks/cost_awareness.py gptme/hooks/token_awareness.py gptme/hooks/form_autodetect.py gptme/hooks/tests/test_cache_awareness.py gptme/hooks/active_context.py gptme/hooks/__init__.py gptme/__version__.py gptme/message.py gptme/telemetry.py gptme/plugins/__init__.py gptme/acp/agent.py gptme/acp/types.py gptme/acp/adapter.py gptme/acp/__main__.py gptme/acp/__init__.py gptme/executor.py gptme/session.py gptme/__main__.py gptme/logmanager.py gptme/config.py gptme/dirs.py gptme/__init__.py gptme/util/context.py gptme/util/terminal.py gptme/util/interrupt.py gptme/util/cost.py gptme/util/export.py gptme/util/master_context.py gptme/util/cost_tracker.py gptme/util/ask_execute.py gptme/util/output_storage.py gptme/util/_telemetry.py gptme/util/uri.py gptme/util/cli.py gptme/util/generate_name.py gptme/util/useredit.py gptme/util/reduce.py gptme/util/tokens.py gptme/util/_sound_cmd.py gptme/util/prompt.py gptme/util/auto_naming.py gptme/util/tree.py gptme/util/cost_display.py gptme/util/sound.py gptme/util/clipboard.py gptme/util/file_storage.py gptme/util/install.py gptme/util/gh.py gptme/util/_sound_sounddevice.py gptme/util/content.py gptme/util/__init__.py gptme/_keyword_matching.py tests/test_tools_rag.py tests/test_command_completion.py tests/test_shell_issue729.py tests/test_tools.py tests/test_tool_loading_duplicate.py tests/test_uri.py tests/test_lessons_index.py tests/test_dspy_gepa.py tests/test_shell_issue772.py tests/test_eval.py tests/test_llm_models.py tests/test_cli.py tests/test_lessons_tool.py tests/test_xml_format.py tests/test_master_context.py tests/test_browser_lynx.py tests/test_lesson_selector_integration.py tests/test_auto_compact.py tests/test_cost_tracker.py tests/test_tool_use.py tests/test_complete.py tests/test_server_v2_tool_confirmation.py tests/test_llm_anthropic.py tests/test_shell_for_loop_issue724.py tests/test_util_gh_mocked.py tests/test_lessons_status.py tests/test_mcp_adapter.py tests/test_file_selector_integration.py tests/test_context_selector.py tests/test_util_cli_mcp.py tests/test_cost_awareness_delayed_warning.py tests/test_chat_config.py tests/test_tools_computer.py tests/test_prompt.py tests/lessons/test_wildcard_matching.py tests/benchmark_context_selector.py tests/context/test_adaptive_compressor.py tests/context/test_task_analyzer.py tests/test_server_v2_auto_stepping.py tests/test_server_v2_sse.py tests/test_server.py tests/test_telemetry.py tests/test_server_auth.py tests/test_markdown_validation.py tests/test_prompt_skills_summary.py tests/test_util_cli.py tests/test_lessons_commands.py tests/test_auto_naming.py tests/test_codeblock.py tests/test_mcp_discovery.py tests/test_browser.py tests/test_hooks_form_autodetect.py tests/test_screenshot.py tests/test_logmanager.py tests/test_plugins.py tests/test_tools_form.py tests/test_tools_token_awareness.py tests/test_util_gh.py tests/test_tools_chats.py tests/test_server_client.py tests/test_config.py tests/test_lessons_integration.py tests/test_tools_shell_multiline.py tests/test_lessons_parser.py tests/test_integration_phase4.py tests/test_prompts.py tests/test_llm_validate.py tests/test_reduce.py tests/test_tools_shell.py tests/test_llm_openai.py tests/test_lessons_matcher.py tests/test_dspy_hybrid.py tests/test_tools_save.py tests/test_tools_tts.py tests/test_tools_subagent.py tests/test_tools_python.py tests/test_hybrid_lessons.py tests/test_shell_output_mixing_issue408.py tests/test_parallel.py tests/test_message_command.py tests/test_dspy_integration.py tests/test_server_v2_hooks.py tests/test_tools_tmux.py tests/test_hooks.py tests/test_context.py tests/test_execenv.py tests/test_tools_todo.py tests/test_tree.py tests/test_mcp.py tests/test_server_v2.py tests/conftest.py tests/test_message.py tests/test_chat.py tests/test_session.py tests/test_custom_providers.py tests/test_prompt_tools.py tests/test_utils.py tests/test_tools_time_awareness.py tests/test_util.py tests/test_dspy_basic.py tests/test_chat_history.py tests/test_tools_patch.py scripts/convert_convo.py scripts/auto_rename_logs.py scripts/analyze_compression.py scripts/list_user_messages.py scripts/check_rst_formatting.py scripts/gh-pr-view-with-pr-comments.py scripts/train/collect.py scripts/treeofthoughts.py scripts/gpt_todoer.py scripts/summarize_project.py scripts/reduce_context.py scripts/describe_api.py scripts/shorten_details.py scripts/github_bot.py --by-file --hide-rate --quiet | tail -n +2
-----------------------------------------------------------------------------------------------------
File blank comment code
-----------------------------------------------------------------------------------------------------
gptme/tools/shell.py 278 346 1146
gptme/llm/llm_openai.py 166 134 715
tests/test_tools_shell.py 235 375 680
gptme/llm/models.py 121 120 669
gptme/config.py 186 171 662
gptme/server/api_v2_sessions.py 153 154 659
gptme/eval/dspy/tasks.py 170 374 639
tests/test_llm_openai.py 174 88 624
gptme/llm/llm_anthropic.py 132 142 618
gptme/server/tasks_api.py 171 110 597
gptme/tools/autocompact.py 181 250 590
gptme/tools/subagent.py 183 313 568
tests/test_util_gh_mocked.py 106 92 534
gptme/tools/mcp_adapter.py 159 166 519
gptme/logmanager.py 132 158 518
tests/test_tools_subagent.py 197 115 515
gptme/tools/base.py 129 137 511
gptme/util/cli.py 142 73 498
gptme/prompts.py 137 168 486
gptme/cli.py 74 65 482
gptme/setup.py 113 59 478
gptme/eval/main.py 72 45 461
gptme/server/openapi_docs.py 177 140 458
gptme/hooks/__init__.py 147 156 450
scripts/analyze_compression.py 103 68 446
gptme/tools/computer.py 151 219 437
tests/test_lessons_commands.py 157 82 422
tests/test_config.py 109 212 413
scripts/github_bot.py 84 79 409
gptme/eval/dspy/prompt_optimizer.py 106 86 401
gptme/server/api.py 99 97 400
gptme/acp/agent.py 88 125 399
tests/context/test_task_analyzer.py 119 58 389
tests/test_auto_compact.py 174 146 383
gptme/chat.py 69 85 382
tests/test_util_cli_mcp.py 89 45 380
gptme/util/_telemetry.py 105 121 360
gptme/eval/dspy/cli.py 73 57 355
gptme/eval/dspy/experiments.py 94 60 352
gptme/server/api_v2.py 79 55 352
tests/test_mcp_discovery.py 128 37 351
gptme/eval/execenv.py 53 92 349
gptme/tools/gh.py 85 93 349
tests/test_llm_anthropic.py 64 24 348
gptme/eval/run.py 58 47 346
gptme/eval/dspy/metrics.py 97 98 344
gptme/telemetry.py 85 54 342
tests/test_codeblock.py 225 538 342
tests/test_lessons_parser.py 152 176 338
gptme/util/prompt.py 83 114 337
gptme/tools/tmux.py 95 159 333
tests/test_integration_phase4.py 66 54 331
gptme/util/context.py 85 131 328
gptme/tools/mcp.py 99 102 311
gptme/llm/__init__.py 76 74 307
gptme/util/gh.py 66 86 305
gptme/message.py 65 88 300
scripts/gh-pr-view-with-pr-comments.py 55 36 298
tests/test_cli.py 82 57 297
tests/test_lessons_matcher.py 89 80 288
gptme/tools/_browser_playwright.py 87 33 287
tests/lessons/test_wildcard_matching.py 114 125 287
gptme/eval/dspy/hybrid_optimizer.py 141 344 286
gptme/tools/tts.py 119 132 284
gptme/mcp/client.py 87 89 274
gptme/tools/save.py 56 55 262
tests/test_context_selector.py 83 45 254
tests/conftest.py 79 70 250
gptme/plugins/__init__.py 83 116 248
gptme/tools/patch.py 58 80 244
gptme/tools/lessons.py 92 105 243
tests/test_lessons_index.py 84 68 243
tests/test_lessons_integration.py 91 59 242
tests/test_complete.py 56 40 241
gptme/context/task_analyzer.py 100 124 237
gptme/tools/todo.py 95 106 237
gptme/context/adaptive_compressor.py 76 130 232
gptme/tools/__init__.py 67 50 230
gptme/commands/meta.py 52 19 229
tests/test_server_v2.py 69 34 229
gptme/mcp/registry.py 59 70 216
gptme/lessons/commands.py 91 48 213
gptme/util/_sound_sounddevice.py 52 52 208
tests/test_mcp.py 58 45 207
tests/test_message.py 83 86 204
tests/test_plugins.py 82 70 203
gptme/util/ask_execute.py 54 46 202
gptme/util/sound.py 65 72 200
gptme/util/auto_naming.py 59 70 199
tests/test_lessons_tool.py 55 26 194
gptme/lessons/parser.py 70 108 192
tests/test_mcp_adapter.py 65 37 191
gptme/tools/precommit.py 64 87 189
tests/test_auto_naming.py 54 41 186
tests/test_execenv.py 52 42 185
gptme/context/selector/file_selector.py 51 71 184
tests/test_hooks.py 90 24 184
gptme/lessons/index.py 71 98 183
tests/test_dspy_hybrid.py 65 45 179
gptme/tools/morph.py 43 42 178
scripts/reduce_context.py 59 72 177
tests/test_server_v2_hooks.py 71 52 175
gptme/llm/validate.py 29 27 173
gptme/server/workspace_api.py 57 55 173
gptme/tools/python.py 56 49 173
gptme/tools/restart.py 51 81 171
gptme/llm/llm_openai_models.py 2 11 169
gptme/codeblock.py 37 92 168
gptme/commands/session.py 60 47 164
gptme/server/api_v2_agents.py 38 28 164
gptme/tools/_browser_thread.py 27 12 157
tests/test_tools_time_awareness.py 52 34 155
tests/test_uri.py 54 30 155
tests/test_cost_tracker.py 21 24 154
gptme/llm/utils.py 54 73 153
tests/test_context.py 72 48 152
gptme/tools/form.py 38 43 147
scripts/check_rst_formatting.py 41 52 147
tests/test_master_context.py 39 24 147
gptme/tools/rag.py 62 74 145
tests/test_file_selector_integration.py 50 23 145
gptme/tools/chats.py 43 49 142
tests/test_tree.py 54 29 142
gptme/hooks/token_awareness.py 44 51 141
gptme/util/__init__.py 31 22 140
tests/test_tool_use.py 12 19 140
gptme/server/client.py 60 78 139
tests/test_dspy_integration.py 54 32 139
tests/test_tools_tmux.py 64 60 139
tests/test_lesson_selector_integration.py 45 25 138
gptme/server/cli.py 26 17 137
gptme/util/cost_display.py 39 31 137
gptme/hooks/cost_awareness.py 45 56 133
gptme/lessons/hybrid_matcher.py 53 79 132
tests/test_dspy_basic.py 49 31 132
tests/test_tools_patch.py 71 157 131
tests/benchmark_context_selector.py 32 26 130
gptme/commands/llm.py 39 35 128
gptme/hooks/cache_awareness.py 95 138 128
gptme/tools/browser.py 59 114 127
gptme/hooks/form_autodetect.py 48 65 126
tests/test_tools_token_awareness.py 59 47 126
gptme/hooks/tests/test_cache_awareness.py 47 34 125
gptme/commands/export.py 32 21 124
tests/test_server.py 42 27 122
gptme/eval/agents.py 22 11 121
gptme/server/auth.py 45 69 121
tests/test_prompt.py 36 36 120
tests/test_tools_save.py 29 23 119
tests/test_tools_todo.py 53 46 117
gptme/tools/complete.py 34 42 116
scripts/auto_rename_logs.py 34 23 115
tests/test_lessons_status.py 67 96 113
gptme/util/cost_tracker.py 44 62 112
tests/test_cost_awareness_delayed_warning.py 42 32 108
gptme/tools/choice.py 31 25 107
scripts/gpt_todoer.py 47 25 107
scripts/train/collect.py 35 52 107
tests/test_server_v2_tool_confirmation.py 32 32 107
gptme/commands/base.py 45 47 105
tests/test_util_cli.py 35 28 105
gptme/lessons/matcher.py 35 47 102
tests/test_tools_tts.py 50 58 101
gptme/init.py 23 19 100
tests/test_parallel.py 27 17 93
tests/test_session.py 40 21 93
gptme/acp/types.py 25 13 91
gptme/util/tree.py 21 13 91
tests/test_tools_computer.py 36 27 91
tests/test_util_gh.py 39 28 91
tests/test_llm_validate.py 25 19 90
gptme/lessons/matcher_enhanced.py 26 40 88
gptme/tools/parallel.py 28 36 88
tests/test_server_v2_auto_stepping.py 20 22 87
gptme/util/export.py 17 25 86
gptme/tools/_browser_perplexity.py 25 22 85
scripts/treeofthoughts.py 28 28 85
tests/test_server_auth.py 40 19 84
gptme/hooks/time_awareness.py 29 31 83
scripts/convert_convo.py 34 54 82
tests/context/test_adaptive_compressor.py 35 23 80
gptme/lessons/auto_include.py 31 26 79
gptme/commands/__init__.py 14 21 77
tests/test_prompt_tools.py 5 4 77
gptme/context/compress.py 63 131 76
gptme/util/reduce.py 24 35 76
tests/test_tools.py 45 6 76
gptme/tools/autocommit.py 37 59 75
tests/test_llm_models.py 27 14 75
tests/test_markdown_validation.py 43 34 75
tests/test_prompts.py 34 31 75
tests/test_shell_issue729.py 50 52 75
tests/test_shell_issue772.py 48 47 73
tests/test_command_completion.py 23 14 71
gptme/context/selector/llm_based.py 32 38 69
gptme/eval/suites/basic.py 17 0 69
gptme/server/api_v2_common.py 48 24 69
gptme/util/generate_name.py 5 6 69
tests/test_hooks_form_autodetect.py 22 34 68
tests/test_tools_form.py 22 19 67
gptme/util/master_context.py 28 38 66
gptme/session.py 39 63 65
gptme/__version__.py 15 11 64
gptme/util/_sound_cmd.py 22 17 64
gptme/eval/filestore.py 11 8 63
gptme/lessons/skills/python-repl/python_helpers.py 28 26 63
gptme/eval/suites/init_projects.py 21 1 62
gptme/hooks/active_context.py 21 22 61
tests/test_shell_output_mixing_issue408.py 25 29 60
gptme/context/selector/rule_based.py 20 13 59
gptme/tools/screenshot.py 22 28 59
gptme/util/uri.py 29 42 59
tests/test_server_client.py 33 26 59
gptme/util/output_storage.py 26 36 58
tests/test_browser.py 28 23 58
gptme/eval/dspy/signatures.py 19 21 56
tests/test_chat_history.py 14 12 56
gptme/context/selector/file_integration.py 13 10 55
gptme/dirs.py 27 14 55
scripts/describe_api.py 28 25 54
gptme/tools/vision.py 19 12 53
gptme/hooks/cwd_tracking.py 18 25 51
gptme/hooks/markdown_validation.py 36 41 51
tests/test_server_v2_sse.py 15 13 50
tests/test_custom_providers.py 23 32 49
tests/test_eval.py 9 9 49
gptme/acp/adapter.py 30 36 44
gptme/util/tokens.py 22 16 44
gptme/util/cost.py 12 20 43
gptme/context/selector/file_config.py 13 11 42
gptme/eval/types.py 15 12 40
gptme/lessons/selector_config.py 18 20 40
gptme/tools/_browser_lynx.py 13 18 40
gptme/util/file_storage.py 30 47 40
gptme/_keyword_matching.py 35 66 39
gptme/context/selector/hybrid.py 14 16 39
gptme/lessons/selector_integration.py 12 11 39
tests/test_dspy_gepa.py 18 9 39
tests/test_prompt_skills_summary.py 24 22 39
tests/test_reduce.py 11 2 39
tests/test_tools_python.py 28 3 38
tests/test_utils.py 14 17 38
tests/test_util.py 28 51 37
gptme/util/clipboard.py 8 2 35
tests/test_message_command.py 13 12 35
gptme/util/terminal.py 23 21 34
tests/test_tools_rag.py 15 8 34
gptme/hooks/test.py 12 5 33
scripts/shorten_details.py 11 6 33
tests/test_hybrid_lessons.py 14 8 33
tests/test_shell_for_loop_issue724.py 16 24 33
gptme/acp/__main__.py 14 9 32
scripts/list_user_messages.py 10 9 32
gptme/util/install.py 13 24 31
gptme/wut.py 13 12 31
gptme/util/content.py 18 24 29
tests/test_chat.py 16 28 28
tests/test_telemetry.py 20 15 28
gptme/context/selector/base.py 14 23 27
tests/test_xml_format.py 10 31 27
gptme/tools/youtube.py 10 1 26
scripts/summarize_project.py 12 1 26
tests/test_chat_config.py 8 7 26
gptme/executor.py 17 26 24
gptme/lessons/__init__.py 7 15 24
tests/test_tool_loading_duplicate.py 16 15 24
gptme/context/__init__.py 3 8 21
gptme/context/config.py 12 26 21
gptme/context/selector/config.py 8 8 21
gptme/util/useredit.py 12 13 21
gptme/util/interrupt.py 13 18 20
gptme/context/selector/__init__.py 6 13 19
gptme/eval/suites/__init__.py 3 0 19
tests/test_tools_shell_multiline.py 7 19 19
gptme/acp/__init__.py 5 8 18
gptme/constants.py 12 16 18
tests/test_logmanager.py 8 5 18
gptme/eval/suites/browser.py 5 0 17
tests/test_screenshot.py 9 6 15
tests/test_tools_chats.py 2 0 15
gptme/mcp/__init__.py 1 0 14
gptme/tools/read.py 6 8 13
tests/test_browser_lynx.py 7 4 12
gptme/__init__.py 1 1 8
gptme/eval/dspy/__init__.py 6 6 7
gptme/eval/cost.py 12 24 6
gptme/eval/__init__.py 1 0 4
gptme/__main__.py 1 0 3
gptme/eval/__main__.py 1 0 3
gptme/eval/dspy/__main__.py 3 5 3
gptme/server/__init__.py 2 3 3
gptme/server/__main__.py 1 0 3
gptme/server/exceptions.py 5 8 2
gptme/server/constants.py 1 3 1
-----------------------------------------------------------------------------------------------------
SUM: 15540 16192 50589
-----------------------------------------------------------------------------------------------------
make[2]: Leaving directory '/home/runner/work/gptme/gptme'
Code Metrics#
$ make metrics
make[2]: Entering directory '/home/runner/work/gptme/gptme'
=== Code Metrics Summary ===
Project Overview:
Files: 298
Total blocks: 3134
Average complexity: 4.388321633694958
Most Complex Functions (D+):
gptme/eval/main.py
F 326:0 main - D
gptme/eval/dspy/hybrid_optimizer.py
C 239:0 TaskComplexity - D
M 283:4 TaskComplexity.analyze - D
gptme/llm/llm_openai.py
F 145:0 init - D
F 508:0 stream - D
gptme/llm/llm_anthropic.py
gptme/llm/__init__.py
F 209:0 _reply_stream - D
gptme/llm/models.py
F 514:0 get_model - D
gptme/commands/meta.py
F 128:0 cmd_plugin - E
gptme/server/api_v2_sessions.py
F 243:0 step - E
gptme/server/openapi_docs.py
F 525:0 _convert_to_openapi_nullable - D
gptme/server/tasks_api.py
F 358:0 get_git_status - D
gptme/server/api_v2_agents.py
F 59:0 api_agents_put - D
gptme/cli.py
gptme/codeblock.py
F 87:0 _extract_codeblocks - E
gptme/prompts.py
F 422:0 prompt_workspace - E
F 595:0 prompt_chat_history - E
F 50:0 get_prompt - D
gptme/context/selector/file_selector.py
gptme/context/selector/rule_based.py
M 27:4 RuleBasedSelector.select - D
gptme/tools/save.py
F 98:0 execute_save_impl - D
gptme/tools/autocompact.py
gptme/tools/tmux.py
F 366:0 execute_tmux - D
gptme/tools/computer.py
F 434:0 computer - D
gptme/tools/gh.py
F 57:0 _wait_for_checks - D
gptme/tools/mcp.py
F 77:0 execute_mcp - E
gptme/tools/shell.py
F 1555:0 _shorten_stdout - D
F 1411:0 execute_shell - D
gptme/tools/lessons.py
F 189:0 auto_include_lessons_hook - D
gptme/hooks/token_awareness.py
F 88:0 add_token_usage_warning - D
gptme/telemetry.py
F 286:0 record_llm_request - E
gptme/plugins/__init__.py
F 141:0 _load_plugin - D
gptme/config.py
F 894:0 setup_config_from_cli - E
M 766:4 Config.mcp - D
gptme/util/context.py
F 440:0 _resource_to_codeblock - D
gptme/util/ask_execute.py
F 87:0 ask_execute - D
F 206:0 execute_with_confirmation - D
gptme/util/prompt.py
M 296:4 GptmeCompleter.get_completions - D
gptme/util/gh.py
tests/test_server_v2_auto_stepping.py
F 16:0 test_auto_stepping - E
tests/test_config.py
F 532:0 test_project_config_loaded_from_toml - D
F 560:0 test_project_config_loaded_from_json - D
scripts/auto_rename_logs.py
F 32:0 auto_rename_logs - D
scripts/check_rst_formatting.py
F 26:0 check_file - E
scripts/gh-pr-view-with-pr-comments.py
M 175:4 PRViewer.get_comments - D
Largest Files (>300 SLOC):
1226 gptme/tools/shell.py
947 gptme/eval/dspy/tasks.py
888 tests/test_tools_shell.py
716 gptme/llm/llm_openai.py
681 gptme/llm/models.py
664 gptme/config.py
659 gptme/server/api_v2_sessions.py
657 tests/test_codeblock.py
633 gptme/tools/subagent.py
626 tests/test_llm_openai.py
620 gptme/llm/llm_anthropic.py
597 gptme/server/tasks_api.py
595 gptme/tools/autocompact.py
589 tests/test_config.py
541 tests/test_util_gh_mocked.py
534 gptme/prompts.py
521 gptme/logmanager.py
519 gptme/tools/mcp_adapter.py
517 gptme/tools/base.py
515 tests/test_tools_subagent.py
500 gptme/util/cli.py
493 gptme/tools/computer.py
488 gptme/cli.py
487 gptme/setup.py
482 gptme/server/openapi_docs.py
463 gptme/eval/main.py
451 gptme/hooks/__init__.py
448 tests/test_lessons_parser.py
445 scripts/analyze_compression.py
422 tests/test_lessons_commands.py
418 scripts/github_bot.py
410 gptme/tools/gh.py
408 gptme/tools/tmux.py
402 gptme/eval/dspy/prompt_optimizer.py
401 gptme/server/api.py
399 gptme/acp/agent.py
398 tests/test_auto_compact.py
389 tests/context/test_task_analyzer.py
382 gptme/chat.py
380 tests/test_util_cli_mcp.py
361 gptme/eval/execenv.py
360 gptme/util/_telemetry.py
357 gptme/util/prompt.py
357 gptme/eval/dspy/experiments.py
355 gptme/eval/dspy/cli.py
352 gptme/server/api_v2.py
351 tests/test_mcp_discovery.py
349 gptme/eval/dspy/metrics.py
348 tests/test_llm_anthropic.py
347 gptme/eval/run.py
346 tests/lessons/test_wildcard_matching.py
343 gptme/util/context.py
342 gptme/telemetry.py
331 tests/test_integration_phase4.py
327 gptme/tools/mcp.py
322 gptme/util/gh.py
308 tests/test_lessons_matcher.py
307 gptme/llm/__init__.py
306 tests/test_cli.py
306 gptme/message.py
make[3]: Entering directory '/home/runner/work/gptme/gptme'
Most Duplicated Files:
npm warn exec The following package was not found and will be installed: jscpd@4.0.7
Clone found (python):
- gptme/util/_sound_sounddevice.py [95:5 - 106:67] (11 lines, 101 tokens)
gptme/util/_sound_sounddevice.py [55:5 - 66:27]
Clone found (python):
- gptme/tools/patch.py [283:5 - 297:4] (14 lines, 93 tokens)
gptme/tools/save.py [108:5 - 122:41]
Clone found (python):
- gptme/tools/gh.py [368:9 - 379:30] (11 lines, 92 tokens)
gptme/tools/gh.py [229:9 - 240:12]
Clone found (python):
- gptme/server/tasks_api.py [482:5 - 493:42] (11 lines, 79 tokens)
gptme/server/tasks_api.py [469:26 - 479:5]
Clone found (python):
- gptme/server/api.py [201:5 - 211:43] (10 lines, 83 tokens)
gptme/server/api_v2.py [184:5 - 194:12]
Clone found (python):
- gptme/server/api.py [212:5 - 228:2] (16 lines, 157 tokens)
gptme/server/api_v2.py [194:5 - 210:2]
Clone found (python):
- gptme/server/api.py [265:5 - 285:4] (20 lines, 172 tokens)
gptme/server/api_v2.py [251:5 - 274:4]
Clone found (python):
- gptme/plugins/__init__.py [399:5 - 424:25] (25 lines, 183 tokens)
gptme/util/install.py [14:5 - 39:28]
Clone found (python):
- gptme/mcp/client.py [173:13 - 180:3] (7 lines, 75 tokens)
gptme/mcp/client.py [137:13 - 142:21]
Clone found (python):
- gptme/llm/validate.py [199:37 - 214:14] (15 lines, 103 tokens)
gptme/llm/validate.py [181:40 - 196:19]
Clone found (python):
- gptme/llm/validate.py [217:29 - 229:45] (12 lines, 97 tokens)
gptme/llm/validate.py [181:40 - 193:45]
Clone found (python):
- gptme/llm/llm_anthropic.py [455:5 - 488:54] (33 lines, 248 tokens)
gptme/llm/llm_anthropic.py [365:5 - 398:20]
Clone found (python):
- gptme/llm/llm_anthropic.py [499:7 - 512:2] (13 lines, 110 tokens)
gptme/llm/llm_anthropic.py [408:7 - 421:69]
Clone found (python):
- gptme/eval/dspy/cli.py [310:31 - 325:49] (15 lines, 104 tokens)
gptme/eval/dspy/cli.py [78:1 - 93:7]
Clone found (python):
- gptme/eval/dspy/cli.py [417:12 - 433:46] (16 lines, 93 tokens)
gptme/eval/dspy/cli.py [160:9 - 176:41]
Clone found (python):
- gptme/eval/dspy/cli.py [444:13 - 450:15] (6 lines, 84 tokens)
gptme/eval/dspy/cli.py [187:13 - 192:17]
Clone found (python):
- gptme/eval/execenv.py [167:9 - 189:50] (22 lines, 229 tokens)
gptme/eval/execenv.py [58:8 - 79:6]
Clone found (python):
- gptme/eval/execenv.py [209:13 - 218:64] (9 lines, 109 tokens)
gptme/eval/filestore.py [62:13 - 71:6]
Clone found (python):
- gptme/eval/execenv.py [353:4 - 367:10] (14 lines, 115 tokens)
gptme/eval/execenv.py [124:2 - 138:4]
Clone found (python):
- gptme/eval/execenv.py [430:9 - 454:6] (24 lines, 180 tokens)
gptme/eval/execenv.py [152:9 - 66:3]
Clone found (python):
- gptme/commands/meta.py [202:9 - 211:7] (9 lines, 90 tokens)
gptme/commands/meta.py [153:9 - 162:6]
Clone found (python):
- scripts/generate_sounds.py [165:2 - 173:13] (8 lines, 81 tokens)
scripts/generate_sounds.py [91:2 - 99:11]
Clone found (python):
- scripts/analyze_compression.py [152:43 - 164:2] (12 lines, 97 tokens)
scripts/analyze_compression.py [55:71 - 67:3]
Clone found (python):
- scripts/analyze_compression.py [220:9 - 231:24] (11 lines, 97 tokens)
scripts/analyze_compression.py [116:9 - 127:20]
Clone found (python):
- gptme/telemetry.py [57:2 - 80:4] (23 lines, 106 tokens)
gptme/util/_telemetry.py [310:5 - 333:7]
Clone found (python):
- gptme/telemetry.py [445:5 - 456:11] (11 lines, 90 tokens)
gptme/telemetry.py [110:9 - 121:10]
┌────────────┬────────────────┬─────────────┬──────────────┬──────────────┬──────────────────┬───────────────────┐
│ Format │ Files analyzed │ Total lines │ Total tokens │ Clones found │ Duplicated lines │ Duplicated tokens │
├────────────┼────────────────┼─────────────┼──────────────┼──────────────┼──────────────────┼───────────────────┤
│ python │ 189 │ 50064 │ 318087 │ 26 │ 378 (0.76%) │ 3068 (0.96%) │
├────────────┼────────────────┼─────────────┼──────────────┼──────────────┼──────────────────┼───────────────────┤
│ css │ 1 │ 173 │ 1045 │ 0 │ 0 (0%) │ 0 (0%) │
├────────────┼────────────────┼─────────────┼──────────────┼──────────────┼──────────────────┼───────────────────┤
│ javascript │ 1 │ 395 │ 3314 │ 0 │ 0 (0%) │ 0 (0%) │
├────────────┼────────────────┼─────────────┼──────────────┼──────────────┼──────────────────┼───────────────────┤
│ markup │ 2 │ 264 │ 2183 │ 0 │ 0 (0%) │ 0 (0%) │
├────────────┼────────────────┼─────────────┼──────────────┼──────────────┼──────────────────┼───────────────────┤
│ markdown │ 7 │ 1231 │ 8776 │ 0 │ 0 (0%) │ 0 (0%) │
├────────────┼────────────────┼─────────────┼──────────────┼──────────────┼──────────────────┼───────────────────┤
│ bash │ 9 │ 335 │ 1587 │ 0 │ 0 (0%) │ 0 (0%) │
├────────────┼────────────────┼─────────────┼──────────────┼──────────────┼──────────────────┼───────────────────┤
│ url │ 1 │ 2 │ 16 │ 0 │ 0 (0%) │ 0 (0%) │
├────────────┼────────────────┼─────────────┼──────────────┼──────────────┼──────────────────┼───────────────────┤
│ Total: │ 210 │ 52464 │ 335008 │ 26 │ 378 (0.72%) │ 3068 (0.92%) │
└────────────┴────────────────┴─────────────┴──────────────┴──────────────┴──────────────────┴───────────────────┘
Found 26 clones.
Detection time:: 3.280s
make[3]: Leaving directory '/home/runner/work/gptme/gptme'
make[2]: Leaving directory '/home/runner/work/gptme/gptme'
The metrics above show:
Project Overview: Basic stats about the codebase size and complexity
Complex Functions: Functions rated D+ (high complexity, should be refactored)
Large Files: Files over 300 SLOC (should be split into smaller modules)
Duplicated Files: Using jscpd to find duplicated code
We should aim to:
Keep average complexity below 4.0
Have no E-rated functions (extremely complex)
Have few D-rated functions (very complex)
Keep files under 300 SLOC where possible