codeboarding 0.15.1__tar.gz → 0.15.2__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.2}/PKG-INFO +1 -1
- {codeboarding-0.15.1 → codeboarding-0.15.2}/agents/llm_errors.py +66 -39
- {codeboarding-0.15.1 → codeboarding-0.15.2}/agents/tree_planner_agent.py +4 -2
- {codeboarding-0.15.1 → codeboarding-0.15.2}/codeboarding.egg-info/PKG-INFO +1 -1
- {codeboarding-0.15.1 → codeboarding-0.15.2}/codeboarding_cli/commands/full_analysis.py +3 -3
- {codeboarding-0.15.1 → codeboarding-0.15.2}/codeboarding_cli/commands/incremental_analysis.py +3 -3
- {codeboarding-0.15.1 → codeboarding-0.15.2}/codeboarding_cli/main.py +10 -15
- {codeboarding-0.15.1 → codeboarding-0.15.2}/diagram_analysis/diagram_generator.py +6 -4
- {codeboarding-0.15.1 → codeboarding-0.15.2}/pyproject.toml +1 -1
- {codeboarding-0.15.1 → codeboarding-0.15.2}/LICENSE +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/PYPI.md +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/README.md +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/agents/__init__.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/agents/agent_responses.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/agents/change_status.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/agents/component_ownership.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/agents/constants.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/agents/content_hash.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/agents/file_index_models.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/agents/incremental_results.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/agents/llm_config.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/agents/llm_renderers/__init__.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/agents/llm_renderers/call_graph.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/agents/llm_renderers/scope.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/agents/model_capabilities.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/agents/planner_agent.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/agents/prompts/__init__.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/agents/prompts/profiles.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/agents/prompts/shared.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/agents/relation_edges.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/agents/retry.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/agents/scope_analysis_agent.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/agents/scope_ids.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/agents/tools/__init__.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/agents/tools/base.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/agents/tools/get_method_calls.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/agents/tools/read_file.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/codeboarding.egg-info/SOURCES.txt +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/codeboarding.egg-info/dependency_links.txt +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/codeboarding.egg-info/entry_points.txt +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/codeboarding.egg-info/requires.txt +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/codeboarding.egg-info/top_level.txt +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/codeboarding_cli/__init__.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/codeboarding_cli/bootstrap.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/codeboarding_cli/commands/__init__.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/codeboarding_cli/commands/partial_analysis.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/codeboarding_cli/github_action.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/codeboarding_cli/render.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/codeboarding_cli/view_instructions.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/codeboarding_workflows/__init__.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/codeboarding_workflows/analysis.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/codeboarding_workflows/fingerprint_diff.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/codeboarding_workflows/orchestration.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/codeboarding_workflows/sources/__init__.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/codeboarding_workflows/sources/local.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/codeboarding_workflows/sources/remote.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/diagram_analysis/__init__.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/diagram_analysis/analysis_json.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/diagram_analysis/cluster_relations.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/diagram_analysis/exceptions.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/diagram_analysis/file_coverage.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/diagram_analysis/file_index.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/diagram_analysis/incremental_changes.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/diagram_analysis/incremental_update.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/diagram_analysis/io_utils.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/diagram_analysis/reference_resolver.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/diagram_analysis/run_context.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/diagram_analysis/run_mode.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/diagram_analysis/scope_assembly.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/diagram_analysis/scope_plan.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/diagram_analysis/tree_shape.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/health/__init__.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/health/checks/__init__.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/health/checks/circular_deps.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/health/checks/function_size.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/health/checks/unused_code_diagnostics.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/health/config.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/health/main.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/health/models.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/health/plugins/__init__.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/health/plugins/plugin_loader.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/health/plugins/protocols.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/health/plugins/registry.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/health/runner.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/infra/__init__.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/infra/clustering_ids.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/infra/constants.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/infra/install.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/infra/logging_config.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/infra/monitoring/__init__.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/infra/monitoring/callbacks.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/infra/monitoring/context.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/infra/monitoring/mixin.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/infra/monitoring/paths.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/infra/monitoring/stats.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/infra/monitoring/telemetry/__init__.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/infra/monitoring/telemetry/device_id.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/infra/monitoring/telemetry/events.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/infra/monitoring/telemetry/schemas.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/infra/monitoring/telemetry/service.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/infra/monitoring/writers.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/infra/repo_utils/__init__.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/infra/repo_utils/change_detector.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/infra/repo_utils/errors.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/infra/repo_utils/git_ops.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/infra/repo_utils/ignore.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/infra/repo_utils/path_utils.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/infra/tool_registry/__init__.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/infra/tool_registry/grammars.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/infra/tool_registry/installers.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/infra/tool_registry/java.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/infra/tool_registry/manifest.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/infra/tool_registry/paths.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/infra/tool_registry/registry.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/infra/user_config.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/infra/utils.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/infra/vscode_constants.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/output_generators/__init__.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/output_generators/html.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/output_generators/html_template.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/output_generators/markdown.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/output_generators/mdx.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/output_generators/rendering.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/output_generators/sphinx.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/setup.cfg +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/__init__.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/analysis_cache.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/analysis_result.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/cfg/__init__.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/cfg/call_graph.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/cfg/edge.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/cfg/location_key.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/clustering/__init__.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/clustering/exceptions.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/clustering/models.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/clustering/names/__init__.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/clustering/names/draft.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/clustering/names/frontier.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/clustering/names/inventory.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/clustering/names/replay.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/clustering/names/spec.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/clustering/names/tokens.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/clustering/service.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/config.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/csharp_config_scanner.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/dotnet_sdk.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/dotnet_solution.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/engine/__init__.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/engine/adapters/__init__.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/engine/adapters/csharp_adapter.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/engine/adapters/go_adapter.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/engine/adapters/java_adapter.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/engine/adapters/kotlin_adapter.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/engine/adapters/php_adapter.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/engine/adapters/python_adapter.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/engine/adapters/rust_adapter.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/engine/adapters/typescript_adapter.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/engine/call_graph_builder.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/engine/edge_build_context.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/engine/edge_builder.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/engine/hierarchy_builder.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/engine/language_adapter.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/engine/lsp_client.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/engine/lsp_constants.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/engine/lsp_recycler.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/engine/models.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/engine/process_memory.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/engine/progress.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/engine/protocols.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/engine/result_converter.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/engine/source_inspector.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/engine/symbol_table.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/engine/utils.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/exceptions.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/external_calls.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/graph_definitions.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/incremental_orchestrator.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/internal_references.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/java_config_scanner.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/java_utils.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/language_results.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/lsp_client/__init__.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/lsp_client/diagnostics.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/node.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/programming_language.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/scanner.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/typescript_config_scanner.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/typescript_plugin/node_modules/codeboarding-workspace-sources/index.js +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/typescript_plugin/node_modules/codeboarding-workspace-sources/package.json +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/typescript_workspace.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/workspace_dependencies.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/tests/test_persisted_analysis_artifacts.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/tests/test_pyproject_packages.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/tests/test_view_instructions.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/tests/test_windows_compatibility.py +0 -0
- {codeboarding-0.15.1 → codeboarding-0.15.2}/tests/test_windows_encoding.py +0 -0
|
@@ -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:
|
|
@@ -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.2}/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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/engine/adapters/csharp_adapter.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/engine/adapters/kotlin_adapter.py
RENAMED
|
File without changes
|
|
File without changes
|
{codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/engine/adapters/python_adapter.py
RENAMED
|
File without changes
|
|
File without changes
|
{codeboarding-0.15.1 → codeboarding-0.15.2}/static_analyzer/engine/adapters/typescript_adapter.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|