codeboarding 0.15.1__tar.gz → 0.15.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {codeboarding-0.15.1 → codeboarding-0.15.3}/PKG-INFO +2 -2
- {codeboarding-0.15.1 → codeboarding-0.15.3}/PYPI.md +1 -1
- {codeboarding-0.15.1 → codeboarding-0.15.3}/README.md +3 -2
- {codeboarding-0.15.1 → codeboarding-0.15.3}/agents/llm_config.py +13 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/agents/llm_errors.py +66 -39
- {codeboarding-0.15.1 → codeboarding-0.15.3}/agents/tree_planner_agent.py +4 -2
- {codeboarding-0.15.1 → codeboarding-0.15.3}/codeboarding.egg-info/PKG-INFO +2 -2
- {codeboarding-0.15.1 → codeboarding-0.15.3}/codeboarding.egg-info/SOURCES.txt +1 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/codeboarding_cli/bootstrap.py +4 -2
- {codeboarding-0.15.1 → codeboarding-0.15.3}/codeboarding_cli/commands/full_analysis.py +3 -3
- {codeboarding-0.15.1 → codeboarding-0.15.3}/codeboarding_cli/commands/incremental_analysis.py +3 -3
- {codeboarding-0.15.1 → codeboarding-0.15.3}/codeboarding_cli/main.py +10 -15
- {codeboarding-0.15.1 → codeboarding-0.15.3}/diagram_analysis/diagram_generator.py +6 -4
- {codeboarding-0.15.1 → codeboarding-0.15.3}/infra/install.py +192 -141
- {codeboarding-0.15.1 → codeboarding-0.15.3}/infra/tool_registry/__init__.py +4 -2
- {codeboarding-0.15.1 → codeboarding-0.15.3}/infra/tool_registry/manifest.py +50 -57
- {codeboarding-0.15.1 → codeboarding-0.15.3}/infra/tool_registry/registry.py +8 -3
- {codeboarding-0.15.1 → codeboarding-0.15.3}/infra/user_config.py +4 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/pyproject.toml +1 -1
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/__init__.py +2 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/analysis_cache.py +2 -2
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/engine/adapters/csharp_adapter.py +76 -2
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/engine/edge_builder.py +23 -4
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/engine/language_adapter.py +5 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/engine/lsp_constants.py +3 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/engine/protocols.py +3 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/engine/source_inspector.py +113 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/engine/symbol_table.py +9 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/graph_definitions.py +23 -10
- codeboarding-0.15.3/tests/test_devcontainer.py +251 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/LICENSE +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/agents/__init__.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/agents/agent_responses.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/agents/change_status.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/agents/component_ownership.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/agents/constants.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/agents/content_hash.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/agents/file_index_models.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/agents/incremental_results.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/agents/llm_renderers/__init__.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/agents/llm_renderers/call_graph.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/agents/llm_renderers/scope.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/agents/model_capabilities.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/agents/planner_agent.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/agents/prompts/__init__.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/agents/prompts/profiles.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/agents/prompts/shared.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/agents/relation_edges.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/agents/retry.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/agents/scope_analysis_agent.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/agents/scope_ids.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/agents/tools/__init__.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/agents/tools/base.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/agents/tools/get_method_calls.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/agents/tools/read_file.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/codeboarding.egg-info/dependency_links.txt +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/codeboarding.egg-info/entry_points.txt +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/codeboarding.egg-info/requires.txt +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/codeboarding.egg-info/top_level.txt +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/codeboarding_cli/__init__.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/codeboarding_cli/commands/__init__.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/codeboarding_cli/commands/partial_analysis.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/codeboarding_cli/github_action.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/codeboarding_cli/render.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/codeboarding_cli/view_instructions.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/codeboarding_workflows/__init__.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/codeboarding_workflows/analysis.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/codeboarding_workflows/fingerprint_diff.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/codeboarding_workflows/orchestration.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/codeboarding_workflows/sources/__init__.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/codeboarding_workflows/sources/local.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/codeboarding_workflows/sources/remote.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/diagram_analysis/__init__.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/diagram_analysis/analysis_json.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/diagram_analysis/cluster_relations.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/diagram_analysis/exceptions.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/diagram_analysis/file_coverage.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/diagram_analysis/file_index.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/diagram_analysis/incremental_changes.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/diagram_analysis/incremental_update.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/diagram_analysis/io_utils.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/diagram_analysis/reference_resolver.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/diagram_analysis/run_context.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/diagram_analysis/run_mode.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/diagram_analysis/scope_assembly.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/diagram_analysis/scope_plan.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/diagram_analysis/tree_shape.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/health/__init__.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/health/checks/__init__.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/health/checks/circular_deps.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/health/checks/function_size.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/health/checks/unused_code_diagnostics.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/health/config.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/health/main.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/health/models.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/health/plugins/__init__.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/health/plugins/plugin_loader.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/health/plugins/protocols.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/health/plugins/registry.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/health/runner.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/infra/__init__.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/infra/clustering_ids.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/infra/constants.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/infra/logging_config.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/infra/monitoring/__init__.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/infra/monitoring/callbacks.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/infra/monitoring/context.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/infra/monitoring/mixin.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/infra/monitoring/paths.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/infra/monitoring/stats.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/infra/monitoring/telemetry/__init__.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/infra/monitoring/telemetry/device_id.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/infra/monitoring/telemetry/events.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/infra/monitoring/telemetry/schemas.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/infra/monitoring/telemetry/service.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/infra/monitoring/writers.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/infra/repo_utils/__init__.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/infra/repo_utils/change_detector.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/infra/repo_utils/errors.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/infra/repo_utils/git_ops.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/infra/repo_utils/ignore.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/infra/repo_utils/path_utils.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/infra/tool_registry/grammars.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/infra/tool_registry/installers.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/infra/tool_registry/java.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/infra/tool_registry/paths.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/infra/utils.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/infra/vscode_constants.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/output_generators/__init__.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/output_generators/html.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/output_generators/html_template.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/output_generators/markdown.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/output_generators/mdx.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/output_generators/rendering.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/output_generators/sphinx.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/setup.cfg +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/analysis_result.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/cfg/__init__.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/cfg/call_graph.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/cfg/edge.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/cfg/location_key.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/clustering/__init__.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/clustering/exceptions.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/clustering/models.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/clustering/names/__init__.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/clustering/names/draft.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/clustering/names/frontier.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/clustering/names/inventory.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/clustering/names/replay.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/clustering/names/spec.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/clustering/names/tokens.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/clustering/service.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/config.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/csharp_config_scanner.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/dotnet_sdk.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/dotnet_solution.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/engine/__init__.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/engine/adapters/__init__.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/engine/adapters/go_adapter.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/engine/adapters/java_adapter.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/engine/adapters/kotlin_adapter.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/engine/adapters/php_adapter.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/engine/adapters/python_adapter.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/engine/adapters/rust_adapter.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/engine/adapters/typescript_adapter.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/engine/call_graph_builder.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/engine/edge_build_context.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/engine/hierarchy_builder.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/engine/lsp_client.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/engine/lsp_recycler.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/engine/models.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/engine/process_memory.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/engine/progress.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/engine/result_converter.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/engine/utils.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/exceptions.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/external_calls.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/incremental_orchestrator.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/internal_references.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/java_config_scanner.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/java_utils.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/language_results.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/lsp_client/__init__.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/lsp_client/diagnostics.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/node.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/programming_language.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/scanner.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/typescript_config_scanner.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/typescript_plugin/node_modules/codeboarding-workspace-sources/index.js +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/typescript_plugin/node_modules/codeboarding-workspace-sources/package.json +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/typescript_workspace.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/static_analyzer/workspace_dependencies.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/tests/test_persisted_analysis_artifacts.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/tests/test_pyproject_packages.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/tests/test_view_instructions.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/tests/test_windows_compatibility.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.3}/tests/test_windows_encoding.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codeboarding
|
|
3
|
-
Version: 0.15.
|
|
3
|
+
Version: 0.15.3
|
|
4
4
|
Summary: Interactive Diagrams for Code
|
|
5
5
|
Author: CodeBoarding Team
|
|
6
6
|
License-Expression: MIT
|
|
@@ -112,7 +112,7 @@ pip install codeboarding --extra-index-url https://pip.codeboarding.org/simple/
|
|
|
112
112
|
|
|
113
113
|
> Installing into the global Python environment with `pip` is not recommended — it can cause dependency conflicts and will fail if the system Python is not 3.12 or 3.13.
|
|
114
114
|
|
|
115
|
-
|
|
115
|
+
Each analysis downloads the language servers its repository's languages need, on first use. To pre-install all of them (useful in CI or restricted environments):
|
|
116
116
|
|
|
117
117
|
```bash
|
|
118
118
|
codeboarding-setup
|
|
@@ -38,7 +38,7 @@ pip install codeboarding --extra-index-url https://pip.codeboarding.org/simple/
|
|
|
38
38
|
|
|
39
39
|
> Installing into the global Python environment with `pip` is not recommended — it can cause dependency conflicts and will fail if the system Python is not 3.12 or 3.13.
|
|
40
40
|
|
|
41
|
-
|
|
41
|
+
Each analysis downloads the language servers its repository's languages need, on first use. To pre-install all of them (useful in CI or restricted environments):
|
|
42
42
|
|
|
43
43
|
```bash
|
|
44
44
|
codeboarding-setup
|
|
@@ -153,7 +153,7 @@ codeboarding-render /path/to/analysis.json --format mdx --output-dir /path/to/do
|
|
|
153
153
|
python codeboarding_cli/render.py ../../demo/markitdown/.codeboarding/analysis.json --format md
|
|
154
154
|
```
|
|
155
155
|
|
|
156
|
-
`python -m infra.install` and `codeboarding-setup` download
|
|
156
|
+
An analysis downloads the language servers its repository's languages need into `~/.codeboarding/servers/` the first time it needs them, shared across projects; `python -m infra.install` and `codeboarding-setup` download all of them up front. Node.js (and its bundled `npm`) is required for the Python, TypeScript, JavaScript, and PHP language servers; if neither `node` nor `CODEBOARDING_NODE_PATH` is set, setup downloads a pinned Node.js runtime into `~/.codeboarding/servers/nodeenv/` automatically.
|
|
157
157
|
|
|
158
158
|
## Configuration
|
|
159
159
|
|
|
@@ -172,6 +172,7 @@ On first run, CodeBoarding creates `~/.codeboarding/config.toml`. Set one provid
|
|
|
172
172
|
# openrouter_api_key = "sk-..."
|
|
173
173
|
# orcarouter_api_key = "sk-orca-..." # model routing gateway (https://www.orcarouter.ai)
|
|
174
174
|
# requesty_api_key = "rqsty-..." # LLM gateway (https://www.requesty.ai)
|
|
175
|
+
# opper_api_key = "..." # EU-hosted AI gateway (https://opper.ai)
|
|
175
176
|
# litellm_base_url = "http://localhost:4000" # LiteLLM proxy server URL (required)
|
|
176
177
|
# litellm_api_key = "sk-..." # LiteLLM proxy server key (optional)
|
|
177
178
|
|
|
@@ -249,7 +250,7 @@ for the actual depth. Existing baseline loading behavior is unchanged: prefer
|
|
|
249
250
|
- Languages: Python, TypeScript, JavaScript, Java, Kotlin, Go, PHP, Rust, C#.
|
|
250
251
|
- Java needs a JDK (21 recommended).
|
|
251
252
|
- Kotlin is analysed with JetBrains' [kotlin-lsp](https://github.com/Kotlin/kotlin-lsp) (about 360 MB with its own Java runtime, under the [JetBrains Free Plugin License](https://github.com/Kotlin/kotlin-lsp/blob/main/kotlin-vscode/LICENSE.txt)) and needs glibc 2.34 or newer on Linux. Kotlin calls into Java are not drawn yet.
|
|
252
|
-
- LLM providers: OpenAI, Anthropic, Google, Vercel AI Gateway, AWS Bedrock, Ollama, OpenRouter, OrcaRouter, Requesty, LiteLLM proxy, and more.
|
|
253
|
+
- LLM providers: OpenAI, Anthropic, Google, Vercel AI Gateway, AWS Bedrock, Ollama, OpenRouter, OrcaRouter, Requesty, Opper, LiteLLM proxy, and more.
|
|
253
254
|
|
|
254
255
|
## Examples
|
|
255
256
|
|
|
@@ -302,6 +302,19 @@ LLM_PROVIDERS = {
|
|
|
302
302
|
"max_retries": 0,
|
|
303
303
|
},
|
|
304
304
|
),
|
|
305
|
+
"opper": LLMConfig(
|
|
306
|
+
chat_class=ChatOpenAI,
|
|
307
|
+
selection_envs=["OPPER_API_KEY"],
|
|
308
|
+
api_key_env="OPPER_API_KEY",
|
|
309
|
+
agent_model="gemini-3.8-flash",
|
|
310
|
+
base_url_env="OPPER_BASE_URL",
|
|
311
|
+
default_base_url="https://api.opper.ai/v3/compat",
|
|
312
|
+
extra_args={
|
|
313
|
+
"max_tokens": None,
|
|
314
|
+
"timeout": LLMDefaults.REQUEST_TIMEOUT_SECONDS,
|
|
315
|
+
"max_retries": 0,
|
|
316
|
+
},
|
|
317
|
+
),
|
|
305
318
|
"litellm": LLMConfig(
|
|
306
319
|
chat_class=ChatOpenAI,
|
|
307
320
|
# Base URL only: a key alone must not select litellm, since there is no
|
|
@@ -1,17 +1,4 @@
|
|
|
1
|
-
"""Provider-agnostic
|
|
2
|
-
|
|
3
|
-
A rejected API key (HTTP 401, or a provider's equivalent auth/permission
|
|
4
|
-
error) is *permanent* for the run: retrying it wastes minutes of backoff and
|
|
5
|
-
floods telemetry with identical ``$exception`` events. The agent retry loop and
|
|
6
|
-
the CLI both need to recognize one when they see it, regardless of which SDK
|
|
7
|
-
raised it.
|
|
8
|
-
|
|
9
|
-
``detect_auth_error`` maps a raw provider exception to an :class:`LLMAuthError`
|
|
10
|
-
(or ``None`` when it isn't an auth failure). The typed error carries the
|
|
11
|
-
provider, a masked key tail, and the provider's own message, and forwards them
|
|
12
|
-
as ``telemetry_properties`` so the PostHog ``$exception`` event — and the
|
|
13
|
-
dashboard's structured ``error`` columns — populate instead of staying null.
|
|
14
|
-
"""
|
|
1
|
+
"""Provider-agnostic LLM failure classification, exceptions, and retry helpers."""
|
|
15
2
|
|
|
16
3
|
from __future__ import annotations
|
|
17
4
|
|
|
@@ -33,6 +20,11 @@ EXIT_AUTH_ERROR = 2
|
|
|
33
20
|
# Process exit code for an exhausted token or credit quota: the key is fine, the account is not.
|
|
34
21
|
EXIT_QUOTA_EXHAUSTED = 3
|
|
35
22
|
|
|
23
|
+
CODEBOARDING_QUOTA_CODE = "free_credits_exhausted"
|
|
24
|
+
# Response contract: licensing-aws/gha_proxy/handler.py.
|
|
25
|
+
PROXY_ERROR_TYPE = "gha_proxy"
|
|
26
|
+
PROXY_QUOTA_MESSAGE = "Resource exhausted: token limit reached"
|
|
27
|
+
|
|
36
28
|
# Class names, across SDKs, that always mean "credentials were rejected".
|
|
37
29
|
# openai/anthropic/cerebras raise ``AuthenticationError``; google raises
|
|
38
30
|
# ``Unauthenticated``/``PermissionDenied``; Bedrock (botocore) surfaces
|
|
@@ -114,6 +106,65 @@ class LLMAuthError(RuntimeError):
|
|
|
114
106
|
self.telemetry_properties = telemetry_properties
|
|
115
107
|
|
|
116
108
|
|
|
109
|
+
class LLMQuotaError(RuntimeError):
|
|
110
|
+
"""An LLM quota is exhausted, with recovery guidance and failure telemetry."""
|
|
111
|
+
|
|
112
|
+
def __init__(self, error: BaseException):
|
|
113
|
+
self.telemetry_properties = llm_failure_properties(error)
|
|
114
|
+
self.is_codeboarding_quota = _is_codeboarding_quota(error)
|
|
115
|
+
_, key_tail = current_provider_key_context()
|
|
116
|
+
if self.is_codeboarding_quota:
|
|
117
|
+
message = (
|
|
118
|
+
"Your CodeBoarding quota is exhausted. "
|
|
119
|
+
"Buy a CodeBoarding license at https://codeboarding.org/pricing, "
|
|
120
|
+
"or wait for your weekly reset."
|
|
121
|
+
)
|
|
122
|
+
elif key_tail == CODEBOARDING_KEY_TAIL:
|
|
123
|
+
message = (
|
|
124
|
+
"The hosted LLM provider's quota is exhausted. "
|
|
125
|
+
"This is a CodeBoarding service issue. Please try again later or contact CodeBoarding support."
|
|
126
|
+
)
|
|
127
|
+
else:
|
|
128
|
+
message = (
|
|
129
|
+
"The LLM provider's token or credit quota is exhausted. "
|
|
130
|
+
"Add credits or raise the quota for this provider, then re-run."
|
|
131
|
+
)
|
|
132
|
+
super().__init__(message)
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def llm_failure_properties(exc: BaseException) -> dict:
|
|
136
|
+
"""Classify a failed LLM call for exception telemetry."""
|
|
137
|
+
quota = is_quota_exhausted(exc)
|
|
138
|
+
context = isinstance(exc, ScopeContextTooLargeError) or any(p.search(str(exc)) for p in _CONTEXT_OVERFLOW_PATTERNS)
|
|
139
|
+
provider, _key_tail = current_provider_key_context()
|
|
140
|
+
properties = {
|
|
141
|
+
"error_type": "quota" if quota else "context" if context else "llm",
|
|
142
|
+
"error_provider": provider,
|
|
143
|
+
"error_status_code": _status_code(exc),
|
|
144
|
+
"error_message": str(exc)[:500],
|
|
145
|
+
}
|
|
146
|
+
if _is_codeboarding_quota(exc):
|
|
147
|
+
properties["error_code"] = CODEBOARDING_QUOTA_CODE
|
|
148
|
+
return properties
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def is_quota_exhausted(exc: BaseException) -> bool:
|
|
152
|
+
status = _status_code(exc)
|
|
153
|
+
quota_code = getattr(exc, "code", None) == "insufficient_quota" or "insufficient_quota" in str(exc)
|
|
154
|
+
return status == 402 or (status == 429 and quota_code)
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def _is_codeboarding_quota(exc: BaseException) -> bool:
|
|
158
|
+
body = getattr(exc, "body", {})
|
|
159
|
+
error = body.get("error", body) if isinstance(body, dict) else {}
|
|
160
|
+
return (
|
|
161
|
+
_status_code(exc) == 402
|
|
162
|
+
and isinstance(error, dict)
|
|
163
|
+
and error.get("type") == PROXY_ERROR_TYPE
|
|
164
|
+
and error.get("message") == PROXY_QUOTA_MESSAGE
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
|
|
117
168
|
def _status_code(exc: BaseException) -> int | None:
|
|
118
169
|
code = getattr(exc, "status_code", None)
|
|
119
170
|
if code is None:
|
|
@@ -183,30 +234,6 @@ def detect_auth_error(exc: BaseException, *, provider: str, key_tail: str) -> LL
|
|
|
183
234
|
)
|
|
184
235
|
|
|
185
236
|
|
|
186
|
-
def _is_quota_exhausted(exc: BaseException) -> bool:
|
|
187
|
-
status = _status_code(exc)
|
|
188
|
-
quota_code = getattr(exc, "code", None) == "insufficient_quota" or "insufficient_quota" in str(exc)
|
|
189
|
-
return status == 402 or (status == 429 and quota_code)
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
def llm_failure_properties(exc: BaseException) -> dict:
|
|
193
|
-
"""``$exception`` properties for a failed LLM call, telling an exhausted quota or an oversized prompt
|
|
194
|
-
apart from other failures.
|
|
195
|
-
|
|
196
|
-
Why: the hosted proxy's paywall is a 402, and OpenAI reports an empty balance as a 429 ``insufficient_quota``.
|
|
197
|
-
An oversized prompt is ours to fix, not the provider's, so it gets its own type on the dashboard.
|
|
198
|
-
"""
|
|
199
|
-
quota = _is_quota_exhausted(exc)
|
|
200
|
-
context = isinstance(exc, ScopeContextTooLargeError) or any(p.search(str(exc)) for p in _CONTEXT_OVERFLOW_PATTERNS)
|
|
201
|
-
provider, _key_tail = current_provider_key_context()
|
|
202
|
-
return {
|
|
203
|
-
"error_type": "quota" if quota else "context" if context else "llm",
|
|
204
|
-
"error_provider": provider,
|
|
205
|
-
"error_status_code": _status_code(exc),
|
|
206
|
-
"error_message": str(exc)[:500],
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
|
|
210
237
|
def is_transient_llm_error(exc: BaseException) -> bool:
|
|
211
238
|
"""Whether the same request may succeed if sent again: throttled, a server error, or no answer at all.
|
|
212
239
|
|
|
@@ -216,7 +243,7 @@ def is_transient_llm_error(exc: BaseException) -> bool:
|
|
|
216
243
|
"""
|
|
217
244
|
status = _status_code(exc)
|
|
218
245
|
if status is not None:
|
|
219
|
-
return status in (408, 429) and not
|
|
246
|
+
return status in (408, 429) and not is_quota_exhausted(exc) or status >= 500
|
|
220
247
|
return any(cls.__name__ in _TRANSIENT_TYPE_NAMES for cls in type(exc).__mro__)
|
|
221
248
|
|
|
222
249
|
|
|
@@ -16,7 +16,7 @@ from langchain_core.prompts import PromptTemplate
|
|
|
16
16
|
from agents.agent_responses import PlannedGroup, TreePlanInsights
|
|
17
17
|
from agents.llm_config import get_current_prompt_profile, supports_json_mode
|
|
18
18
|
from infra.monitoring.callbacks import MONITORING_CALLBACK
|
|
19
|
-
from agents.llm_errors import LLMAuthError, raise_if_auth_error
|
|
19
|
+
from agents.llm_errors import LLMAuthError, LLMQuotaError, is_quota_exhausted, raise_if_auth_error
|
|
20
20
|
from agents.prompts import get_tree_plan_prompts
|
|
21
21
|
from agents.retry import LLM_MAX_ATTEMPTS, RetryAction, RetryDecision, classify_llm_error, with_retries
|
|
22
22
|
from infra.monitoring import trace
|
|
@@ -103,7 +103,7 @@ class TreePlannerAgent(MonitoringMixin):
|
|
|
103
103
|
return folded
|
|
104
104
|
|
|
105
105
|
def _draw(self, prompt: str, labelled: dict[str, CandidateGroup]) -> list[TreePlanInsights]:
|
|
106
|
-
"""
|
|
106
|
+
"""Draw concurrently, dropping failed draws unless credentials or quota prevent further work."""
|
|
107
107
|
# Not ``with``: its ``__exit__`` waits for a stalled draw; a copied context carries the
|
|
108
108
|
# monitoring step into each worker.
|
|
109
109
|
pool = ThreadPoolExecutor(max_workers=self.draws)
|
|
@@ -117,6 +117,8 @@ class TreePlannerAgent(MonitoringMixin):
|
|
|
117
117
|
except LLMAuthError:
|
|
118
118
|
raise
|
|
119
119
|
except Exception as exc:
|
|
120
|
+
if is_quota_exhausted(exc):
|
|
121
|
+
raise LLMQuotaError(exc) from exc
|
|
120
122
|
failures.append(exc)
|
|
121
123
|
logger.warning("[Planner] draw failed: %s", exc)
|
|
122
124
|
finally:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codeboarding
|
|
3
|
-
Version: 0.15.
|
|
3
|
+
Version: 0.15.3
|
|
4
4
|
Summary: Interactive Diagrams for Code
|
|
5
5
|
Author: CodeBoarding Team
|
|
6
6
|
License-Expression: MIT
|
|
@@ -112,7 +112,7 @@ pip install codeboarding --extra-index-url https://pip.codeboarding.org/simple/
|
|
|
112
112
|
|
|
113
113
|
> Installing into the global Python environment with `pip` is not recommended — it can cause dependency conflicts and will fail if the system Python is not 3.12 or 3.13.
|
|
114
114
|
|
|
115
|
-
|
|
115
|
+
Each analysis downloads the language servers its repository's languages need, on first use. To pre-install all of them (useful in CI or restricted environments):
|
|
116
116
|
|
|
117
117
|
```bash
|
|
118
118
|
codeboarding-setup
|
|
@@ -187,6 +187,7 @@ static_analyzer/lsp_client/__init__.py
|
|
|
187
187
|
static_analyzer/lsp_client/diagnostics.py
|
|
188
188
|
static_analyzer/typescript_plugin/node_modules/codeboarding-workspace-sources/index.js
|
|
189
189
|
static_analyzer/typescript_plugin/node_modules/codeboarding-workspace-sources/package.json
|
|
190
|
+
tests/test_devcontainer.py
|
|
190
191
|
tests/test_persisted_analysis_artifacts.py
|
|
191
192
|
tests/test_pyproject_packages.py
|
|
192
193
|
tests/test_view_instructions.py
|
|
@@ -5,7 +5,7 @@ from pathlib import Path
|
|
|
5
5
|
from agents.llm_config import configure_models, validate_api_key_provided
|
|
6
6
|
from health.plugins import get_registries, load_plugins
|
|
7
7
|
from diagram_analysis.run_context import RunPaths
|
|
8
|
-
from infra.install import ensure_tools
|
|
8
|
+
from infra.install import enable_on_demand_install, ensure_tools
|
|
9
9
|
from infra.logging_config import setup_logging
|
|
10
10
|
from infra.user_config import ensure_config_template, load_user_config
|
|
11
11
|
from infra.utils import CODEBOARDING_DIR_NAME
|
|
@@ -41,4 +41,6 @@ def bootstrap_environment(output_dir: Path, binary_location: Path | None) -> Non
|
|
|
41
41
|
# repairs a deleted ~/.codeboarding/servers/nodeenv/ independently of the
|
|
42
42
|
# fingerprint check. Pre-gating with needs_install() here would skip that
|
|
43
43
|
# repair when binaries look current but the runtime directory was deleted.
|
|
44
|
-
|
|
44
|
+
# Only the base tools here: the analysis installs its languages' servers once it has found them.
|
|
45
|
+
ensure_tools(auto_install_npm=True, auto_install_vcpp=True, languages=())
|
|
46
|
+
enable_on_demand_install(auto_install_npm=True, auto_install_vcpp=True)
|
|
@@ -5,7 +5,8 @@ from pathlib import Path
|
|
|
5
5
|
from tqdm import tqdm
|
|
6
6
|
|
|
7
7
|
from agents.llm_config import LLMConfigError
|
|
8
|
-
from agents.llm_errors import LLMAuthError
|
|
8
|
+
from agents.llm_errors import LLMAuthError, LLMQuotaError
|
|
9
|
+
from diagram_analysis.exceptions import ScopeSemanticsError
|
|
9
10
|
from codeboarding_cli.bootstrap import bootstrap_environment, resolve_local_run_paths
|
|
10
11
|
from codeboarding_cli.view_instructions import print_view_instructions
|
|
11
12
|
from codeboarding_workflows.analysis import run_full
|
|
@@ -13,7 +14,6 @@ from codeboarding_workflows.orchestration import run_analysis_pipeline
|
|
|
13
14
|
from codeboarding_workflows.sources import SourceContext, local_source, remote_source
|
|
14
15
|
from infra.constants import CLI_ROOT_DOCUMENT_NAME
|
|
15
16
|
from diagram_analysis import DEFAULT_DEPTH_CAP, RunContext, RunPaths
|
|
16
|
-
from diagram_analysis.exceptions import ScopeSemanticsError
|
|
17
17
|
from infra.monitoring import monitor_execution
|
|
18
18
|
from infra.monitoring.paths import get_monitoring_run_dir
|
|
19
19
|
from output_generators.rendering import render_docs
|
|
@@ -161,7 +161,7 @@ def _run_remote(args: argparse.Namespace) -> None:
|
|
|
161
161
|
upload=args.upload,
|
|
162
162
|
should_monitor=should_monitor,
|
|
163
163
|
)
|
|
164
|
-
except (LLMAuthError, ScopeSemanticsError):
|
|
164
|
+
except (LLMAuthError, LLMQuotaError, ScopeSemanticsError):
|
|
165
165
|
# The next repository would fail the same way, so stop the run.
|
|
166
166
|
raise
|
|
167
167
|
except Exception:
|
{codeboarding-0.15.1 → codeboarding-0.15.3}/codeboarding_cli/commands/incremental_analysis.py
RENAMED
|
@@ -5,12 +5,12 @@ import sys
|
|
|
5
5
|
from typing import Any
|
|
6
6
|
|
|
7
7
|
from agents.llm_config import LLMConfigError
|
|
8
|
-
from agents.llm_errors import LLMAuthError
|
|
8
|
+
from agents.llm_errors import LLMAuthError, LLMQuotaError
|
|
9
|
+
from diagram_analysis.exceptions import ScopeSemanticsError
|
|
9
10
|
from codeboarding_cli.bootstrap import bootstrap_environment, resolve_local_run_paths
|
|
10
11
|
from codeboarding_cli.view_instructions import print_view_instructions
|
|
11
12
|
from codeboarding_workflows.analysis import BaselineUnavailableError, run_incremental
|
|
12
13
|
from diagram_analysis import RunContext
|
|
13
|
-
from diagram_analysis.exceptions import ScopeSemanticsError
|
|
14
14
|
from diagram_analysis.run_mode import RunMode
|
|
15
15
|
from infra.utils import monitoring_enabled
|
|
16
16
|
|
|
@@ -61,7 +61,7 @@ def run_from_args(args: argparse.Namespace, parser: argparse.ArgumentParser) ->
|
|
|
61
61
|
# to prompt for a full run; no stack trace needed.
|
|
62
62
|
logger.info("Incremental unavailable: %s", exc)
|
|
63
63
|
_emit_error(str(exc))
|
|
64
|
-
except (LLMAuthError, ScopeSemanticsError):
|
|
64
|
+
except (LLMAuthError, LLMQuotaError, ScopeSemanticsError):
|
|
65
65
|
# A full run would fail the same way, so don't ask for one.
|
|
66
66
|
raise
|
|
67
67
|
except Exception as exc:
|
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
import argparse
|
|
2
|
+
import logging
|
|
2
3
|
import os
|
|
3
4
|
import sys
|
|
4
|
-
import traceback
|
|
5
5
|
from pathlib import Path
|
|
6
6
|
|
|
7
7
|
from agents.llm_config import CODEBOARDING_KEY_TAIL
|
|
8
|
-
from agents.llm_errors import EXIT_AUTH_ERROR, EXIT_QUOTA_EXHAUSTED, LLMAuthError
|
|
8
|
+
from agents.llm_errors import EXIT_AUTH_ERROR, EXIT_QUOTA_EXHAUSTED, LLMAuthError, LLMQuotaError
|
|
9
9
|
from codeboarding_cli.bootstrap import resolve_local_run_paths
|
|
10
10
|
from codeboarding_cli.commands import full_analysis, incremental_analysis, partial_analysis
|
|
11
|
-
from diagram_analysis.exceptions import ScopeSemanticsError
|
|
12
11
|
from output_generators import SUPPORTED_FORMATS, render as render_output
|
|
13
12
|
from infra.utils import ANALYSIS_FILENAME
|
|
14
13
|
|
|
15
14
|
_SUBCOMMANDS = {"full", "incremental", "partial"}
|
|
15
|
+
# CodeBoarding-action/scripts/analyze_repository.py parses this prefix; keep it stable.
|
|
16
|
+
_ERROR_PREFIX = "CodeBoarding: "
|
|
17
|
+
logger = logging.getLogger(__name__)
|
|
16
18
|
|
|
17
19
|
|
|
18
20
|
def _build_shared_parser() -> argparse.ArgumentParser:
|
|
@@ -108,22 +110,15 @@ def _dispatch(args: argparse.Namespace, parser: argparse.ArgumentParser) -> None
|
|
|
108
110
|
output_dir=run_paths.output_dir,
|
|
109
111
|
)
|
|
110
112
|
except LLMAuthError as exc:
|
|
111
|
-
|
|
112
|
-
# actionable line (no traceback) and exit with a distinct code.
|
|
113
|
-
print(f"\nCodeBoarding: {exc}", file=sys.stderr)
|
|
113
|
+
logger.error("%s%s", _ERROR_PREFIX, exc)
|
|
114
114
|
if exc.key_tail != CODEBOARDING_KEY_TAIL:
|
|
115
|
-
|
|
115
|
+
logger.error(
|
|
116
116
|
"Check your LLM provider API key (shell env or ~/.codeboarding/config.toml) and re-run.",
|
|
117
|
-
file=sys.stderr,
|
|
118
117
|
)
|
|
119
118
|
raise SystemExit(EXIT_AUTH_ERROR) from exc
|
|
120
|
-
except
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
# Same exit as any failure, but with a code callers (the GitHub Action) can name.
|
|
124
|
-
traceback.print_exception(exc)
|
|
125
|
-
print("\nCodeBoarding: the LLM provider's token or credit quota is exhausted.", file=sys.stderr)
|
|
126
|
-
print("Add credits or raise the quota for this provider, then re-run.", file=sys.stderr)
|
|
119
|
+
except LLMQuotaError as exc:
|
|
120
|
+
logger.exception("LLM quota failure")
|
|
121
|
+
logger.error("%s%s", _ERROR_PREFIX, exc)
|
|
127
122
|
raise SystemExit(EXIT_QUOTA_EXHAUSTED) from exc
|
|
128
123
|
|
|
129
124
|
|
|
@@ -30,7 +30,7 @@ from diagram_analysis.incremental_update import (
|
|
|
30
30
|
from agents.incremental_results import RecursiveScopeUpdateResult
|
|
31
31
|
from agents.file_index_models import FileEntry, FileMethodGroup, MethodEntry
|
|
32
32
|
from agents.llm_config import initialize_agent_llm
|
|
33
|
-
from agents.llm_errors import LLMAuthError, llm_failure_properties
|
|
33
|
+
from agents.llm_errors import LLMAuthError, LLMQuotaError, is_quota_exhausted, llm_failure_properties
|
|
34
34
|
from agents.relation_edges import (
|
|
35
35
|
drop_misattributed_edges,
|
|
36
36
|
index_relation_endpoints,
|
|
@@ -818,9 +818,11 @@ class DiagramGenerator:
|
|
|
818
818
|
incremental,
|
|
819
819
|
enclosing_names=enclosing_names,
|
|
820
820
|
)
|
|
821
|
-
except LLMAuthError:
|
|
821
|
+
except (LLMAuthError, LLMQuotaError, ScopeSemanticsError):
|
|
822
822
|
raise
|
|
823
823
|
except Exception as error:
|
|
824
|
+
if is_quota_exhausted(error):
|
|
825
|
+
raise LLMQuotaError(error) from error
|
|
824
826
|
raise ScopeSemanticsError(scope.scope_id, telemetry_properties=llm_failure_properties(error)) from error
|
|
825
827
|
if semantics is None:
|
|
826
828
|
with self._naming_counts_lock:
|
|
@@ -1120,7 +1122,7 @@ class DiagramGenerator:
|
|
|
1120
1122
|
new_components = [child for child in analysis.components if child.component_id in preclustered_scopes]
|
|
1121
1123
|
|
|
1122
1124
|
return component.component_id, analysis, new_components
|
|
1123
|
-
except (LLMAuthError, ScopeSemanticsError):
|
|
1125
|
+
except (LLMAuthError, LLMQuotaError, ScopeSemanticsError):
|
|
1124
1126
|
# An LLM failure aborts the whole run rather than shipping this component with deterministic names.
|
|
1125
1127
|
raise
|
|
1126
1128
|
except Exception:
|
|
@@ -1335,7 +1337,7 @@ class DiagramGenerator:
|
|
|
1335
1337
|
stats["completed"] += 1
|
|
1336
1338
|
try:
|
|
1337
1339
|
outcomes.append((component, level, future.result()))
|
|
1338
|
-
except (LLMAuthError, ScopeSemanticsError):
|
|
1340
|
+
except (LLMAuthError, LLMQuotaError, ScopeSemanticsError):
|
|
1339
1341
|
for pending in future_to_task:
|
|
1340
1342
|
pending.cancel()
|
|
1341
1343
|
raise
|