codeboarding 0.14.5__tar.gz → 0.15.1__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.14.5/codeboarding.egg-info → codeboarding-0.15.1}/PKG-INFO +4 -2
- {codeboarding-0.14.5 → codeboarding-0.15.1}/PYPI.md +2 -1
- {codeboarding-0.14.5 → codeboarding-0.15.1}/README.md +16 -12
- {codeboarding-0.14.5 → codeboarding-0.15.1}/agents/agent_responses.py +1 -1
- {codeboarding-0.14.5 → codeboarding-0.15.1}/agents/content_hash.py +1 -1
- {codeboarding-0.14.5 → codeboarding-0.15.1}/agents/llm_config.py +1 -6
- {codeboarding-0.14.5 → codeboarding-0.15.1}/agents/llm_errors.py +59 -4
- {codeboarding-0.14.5 → codeboarding-0.15.1}/agents/llm_renderers/scope.py +1 -1
- {codeboarding-0.14.5 → codeboarding-0.15.1}/agents/model_capabilities.py +2 -2
- {codeboarding-0.14.5 → codeboarding-0.15.1}/agents/relation_edges.py +2 -2
- {codeboarding-0.14.5 → codeboarding-0.15.1}/agents/retry.py +26 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/agents/scope_analysis_agent.py +23 -2
- codeboarding-0.15.1/agents/scope_ids.py +3 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/agents/tools/read_file.py +1 -1
- {codeboarding-0.14.5 → codeboarding-0.15.1}/agents/tree_planner_agent.py +18 -10
- {codeboarding-0.14.5 → codeboarding-0.15.1/codeboarding.egg-info}/PKG-INFO +4 -2
- {codeboarding-0.14.5 → codeboarding-0.15.1}/codeboarding.egg-info/SOURCES.txt +49 -51
- codeboarding-0.15.1/codeboarding.egg-info/entry_points.txt +4 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/codeboarding.egg-info/requires.txt +1 -0
- codeboarding-0.15.1/codeboarding.egg-info/top_level.txt +8 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/codeboarding_cli/bootstrap.py +6 -6
- {codeboarding-0.14.5 → codeboarding-0.15.1}/codeboarding_cli/commands/full_analysis.py +7 -7
- {codeboarding-0.14.5 → codeboarding-0.15.1}/codeboarding_cli/commands/incremental_analysis.py +1 -1
- {codeboarding-0.14.5 → codeboarding-0.15.1}/codeboarding_cli/commands/partial_analysis.py +2 -2
- {codeboarding-0.14.5 → codeboarding-0.15.1/codeboarding_cli}/github_action.py +2 -2
- {codeboarding-0.14.5 → codeboarding-0.15.1/codeboarding_cli}/main.py +1 -1
- {codeboarding-0.14.5 → codeboarding-0.15.1}/codeboarding_cli/render.py +1 -1
- {codeboarding-0.14.5 → codeboarding-0.15.1}/codeboarding_workflows/analysis.py +3 -3
- {codeboarding-0.14.5/repo_utils → codeboarding-0.15.1/codeboarding_workflows}/fingerprint_diff.py +1 -1
- {codeboarding-0.14.5 → codeboarding-0.15.1}/codeboarding_workflows/sources/remote.py +2 -2
- {codeboarding-0.14.5 → codeboarding-0.15.1}/diagram_analysis/analysis_json.py +1 -1
- {codeboarding-0.14.5/static_analyzer → codeboarding-0.15.1/diagram_analysis}/cluster_relations.py +2 -2
- {codeboarding-0.14.5 → codeboarding-0.15.1}/diagram_analysis/diagram_generator.py +13 -13
- {codeboarding-0.14.5 → codeboarding-0.15.1}/diagram_analysis/file_coverage.py +3 -3
- {codeboarding-0.14.5 → codeboarding-0.15.1}/diagram_analysis/file_index.py +2 -2
- {codeboarding-0.14.5 → codeboarding-0.15.1}/diagram_analysis/incremental_changes.py +2 -2
- {codeboarding-0.14.5 → codeboarding-0.15.1}/diagram_analysis/incremental_update.py +3 -3
- {codeboarding-0.14.5 → codeboarding-0.15.1}/diagram_analysis/io_utils.py +1 -1
- {codeboarding-0.14.5 → codeboarding-0.15.1}/diagram_analysis/run_context.py +2 -2
- {codeboarding-0.14.5 → codeboarding-0.15.1}/diagram_analysis/scope_assembly.py +4 -4
- {codeboarding-0.14.5 → codeboarding-0.15.1}/diagram_analysis/scope_plan.py +1 -1
- {codeboarding-0.14.5 → codeboarding-0.15.1}/health/checks/function_size.py +1 -1
- {codeboarding-0.14.5 → codeboarding-0.15.1}/health/config.py +2 -2
- codeboarding-0.15.1/health/main.py +152 -0
- {codeboarding-0.14.5/core → codeboarding-0.15.1/health/plugins}/__init__.py +7 -7
- {codeboarding-0.14.5/core → codeboarding-0.15.1/health/plugins}/plugin_loader.py +1 -1
- {codeboarding-0.14.5 → codeboarding-0.15.1}/health/runner.py +2 -2
- codeboarding-0.15.1/infra/__init__.py +1 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1/infra}/install.py +28 -11
- {codeboarding-0.14.5 → codeboarding-0.15.1/infra}/monitoring/__init__.py +2 -2
- {codeboarding-0.14.5 → codeboarding-0.15.1/infra}/monitoring/callbacks.py +6 -2
- {codeboarding-0.14.5 → codeboarding-0.15.1/infra}/monitoring/context.py +1 -1
- {codeboarding-0.14.5 → codeboarding-0.15.1/infra}/monitoring/mixin.py +2 -2
- {codeboarding-0.14.5 → codeboarding-0.15.1/infra}/monitoring/paths.py +1 -1
- {codeboarding-0.14.5 → codeboarding-0.15.1/infra/monitoring}/telemetry/__init__.py +1 -1
- {codeboarding-0.14.5 → codeboarding-0.15.1/infra/monitoring}/telemetry/events.py +3 -3
- {codeboarding-0.14.5 → codeboarding-0.15.1/infra/monitoring}/telemetry/service.py +1 -1
- {codeboarding-0.14.5 → codeboarding-0.15.1/infra}/monitoring/writers.py +1 -1
- {codeboarding-0.14.5 → codeboarding-0.15.1/infra}/repo_utils/__init__.py +4 -4
- {codeboarding-0.14.5 → codeboarding-0.15.1/infra}/repo_utils/change_detector.py +1 -1
- {codeboarding-0.14.5 → codeboarding-0.15.1/infra}/repo_utils/ignore.py +1 -3
- {codeboarding-0.14.5 → codeboarding-0.15.1/infra}/tool_registry/__init__.py +6 -0
- codeboarding-0.15.1/infra/tool_registry/grammars.py +47 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1/infra}/tool_registry/installers.py +97 -11
- codeboarding-0.14.5/static_analyzer/java_utils.py → codeboarding-0.15.1/infra/tool_registry/java.py +6 -109
- {codeboarding-0.14.5 → codeboarding-0.15.1/infra}/tool_registry/manifest.py +24 -10
- {codeboarding-0.14.5 → codeboarding-0.15.1/infra}/tool_registry/paths.py +1 -1
- {codeboarding-0.14.5 → codeboarding-0.15.1/infra}/tool_registry/registry.py +48 -7
- {codeboarding-0.14.5 → codeboarding-0.15.1/infra}/user_config.py +1 -1
- {codeboarding-0.14.5 → codeboarding-0.15.1/infra}/utils.py +4 -4
- {codeboarding-0.14.5 → codeboarding-0.15.1/infra}/vscode_constants.py +12 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/output_generators/html.py +1 -1
- {codeboarding-0.14.5 → codeboarding-0.15.1}/output_generators/markdown.py +1 -1
- {codeboarding-0.14.5 → codeboarding-0.15.1}/output_generators/mdx.py +1 -1
- {codeboarding-0.14.5 → codeboarding-0.15.1}/output_generators/rendering.py +2 -2
- {codeboarding-0.14.5 → codeboarding-0.15.1}/output_generators/sphinx.py +1 -1
- {codeboarding-0.14.5 → codeboarding-0.15.1}/pyproject.toml +14 -19
- {codeboarding-0.14.5 → codeboarding-0.15.1}/static_analyzer/__init__.py +232 -162
- {codeboarding-0.14.5 → codeboarding-0.15.1}/static_analyzer/analysis_cache.py +6 -3
- {codeboarding-0.14.5 → codeboarding-0.15.1}/static_analyzer/cfg/call_graph.py +10 -10
- {codeboarding-0.14.5 → codeboarding-0.15.1}/static_analyzer/clustering/models.py +1 -1
- {codeboarding-0.14.5 → codeboarding-0.15.1}/static_analyzer/clustering/names/draft.py +1 -1
- {codeboarding-0.14.5 → codeboarding-0.15.1}/static_analyzer/clustering/names/inventory.py +1 -1
- {codeboarding-0.14.5 → codeboarding-0.15.1}/static_analyzer/clustering/names/spec.py +1 -1
- {codeboarding-0.14.5 → codeboarding-0.15.1}/static_analyzer/clustering/service.py +2 -2
- {codeboarding-0.14.5 → codeboarding-0.15.1}/static_analyzer/config.py +5 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/static_analyzer/csharp_config_scanner.py +1 -1
- {codeboarding-0.14.5 → codeboarding-0.15.1}/static_analyzer/dotnet_sdk.py +1 -1
- {codeboarding-0.14.5 → codeboarding-0.15.1}/static_analyzer/engine/adapters/__init__.py +2 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/static_analyzer/engine/adapters/csharp_adapter.py +4 -3
- {codeboarding-0.14.5 → codeboarding-0.15.1}/static_analyzer/engine/adapters/go_adapter.py +2 -2
- {codeboarding-0.14.5 → codeboarding-0.15.1}/static_analyzer/engine/adapters/java_adapter.py +1 -1
- codeboarding-0.15.1/static_analyzer/engine/adapters/kotlin_adapter.py +348 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/static_analyzer/engine/adapters/php_adapter.py +1 -1
- {codeboarding-0.14.5 → codeboarding-0.15.1}/static_analyzer/engine/adapters/python_adapter.py +1 -1
- {codeboarding-0.14.5 → codeboarding-0.15.1}/static_analyzer/engine/adapters/rust_adapter.py +1 -1
- codeboarding-0.15.1/static_analyzer/engine/adapters/typescript_adapter.py +96 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/static_analyzer/engine/call_graph_builder.py +20 -4
- {codeboarding-0.14.5 → codeboarding-0.15.1}/static_analyzer/engine/edge_builder.py +69 -11
- {codeboarding-0.14.5 → codeboarding-0.15.1}/static_analyzer/engine/hierarchy_builder.py +83 -3
- {codeboarding-0.14.5 → codeboarding-0.15.1}/static_analyzer/engine/language_adapter.py +93 -5
- {codeboarding-0.14.5 → codeboarding-0.15.1}/static_analyzer/engine/lsp_client.py +130 -11
- {codeboarding-0.14.5 → codeboarding-0.15.1}/static_analyzer/engine/lsp_constants.py +6 -3
- {codeboarding-0.14.5 → codeboarding-0.15.1}/static_analyzer/engine/lsp_recycler.py +12 -5
- {codeboarding-0.14.5 → codeboarding-0.15.1}/static_analyzer/engine/process_memory.py +0 -8
- {codeboarding-0.14.5 → codeboarding-0.15.1}/static_analyzer/engine/protocols.py +11 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/static_analyzer/engine/result_converter.py +31 -22
- {codeboarding-0.14.5 → codeboarding-0.15.1}/static_analyzer/engine/source_inspector.py +279 -27
- codeboarding-0.15.1/static_analyzer/exceptions.py +13 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/static_analyzer/external_calls.py +38 -5
- {codeboarding-0.14.5 → codeboarding-0.15.1}/static_analyzer/graph_definitions.py +14 -3
- {codeboarding-0.14.5 → codeboarding-0.15.1}/static_analyzer/incremental_orchestrator.py +3 -1
- {codeboarding-0.14.5 → codeboarding-0.15.1}/static_analyzer/java_config_scanner.py +1 -1
- codeboarding-0.15.1/static_analyzer/java_utils.py +112 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/static_analyzer/language_results.py +19 -3
- {codeboarding-0.14.5 → codeboarding-0.15.1}/static_analyzer/scanner.py +3 -3
- {codeboarding-0.14.5 → codeboarding-0.15.1}/static_analyzer/typescript_config_scanner.py +75 -25
- codeboarding-0.15.1/static_analyzer/typescript_plugin/node_modules/codeboarding-workspace-sources/index.js +132 -0
- codeboarding-0.15.1/static_analyzer/typescript_plugin/node_modules/codeboarding-workspace-sources/package.json +6 -0
- codeboarding-0.15.1/static_analyzer/typescript_workspace.py +81 -0
- codeboarding-0.15.1/static_analyzer/workspace_dependencies.py +93 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/tests/test_persisted_analysis_artifacts.py +3 -3
- {codeboarding-0.14.5 → codeboarding-0.15.1}/tests/test_pyproject_packages.py +2 -9
- {codeboarding-0.14.5 → codeboarding-0.15.1}/tests/test_windows_compatibility.py +13 -13
- codeboarding-0.14.5/agents/scope_ids.py +0 -3
- codeboarding-0.14.5/codeboarding.egg-info/entry_points.txt +0 -4
- codeboarding-0.14.5/codeboarding.egg-info/top_level.txt +0 -21
- codeboarding-0.14.5/static_analyzer/engine/adapters/typescript_adapter.py +0 -62
- codeboarding-0.14.5/static_analyzer/exceptions.py +0 -5
- codeboarding-0.14.5/tests/test_cli_parser.py +0 -265
- codeboarding-0.14.5/tests/test_github_action.py +0 -477
- codeboarding-0.14.5/tests/test_install.py +0 -303
- codeboarding-0.14.5/tests/test_logging_config.py +0 -267
- codeboarding-0.14.5/tests/test_main.py +0 -725
- codeboarding-0.14.5/tests/test_registry_coverage.py +0 -396
- codeboarding-0.14.5/tests/test_telemetry_events.py +0 -199
- codeboarding-0.14.5/tests/test_telemetry_service.py +0 -216
- codeboarding-0.14.5/tests/test_tool_registry.py +0 -1740
- codeboarding-0.14.5/tests/test_user_config.py +0 -313
- codeboarding-0.14.5/tests/test_vscode_constants.py +0 -239
- {codeboarding-0.14.5 → codeboarding-0.15.1}/LICENSE +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/agents/__init__.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/agents/change_status.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/agents/component_ownership.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/agents/constants.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/agents/file_index_models.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/agents/incremental_results.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/agents/llm_renderers/__init__.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/agents/llm_renderers/call_graph.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/agents/planner_agent.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/agents/prompts/__init__.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/agents/prompts/profiles.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/agents/prompts/shared.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/agents/tools/__init__.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/agents/tools/base.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/agents/tools/get_method_calls.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/codeboarding.egg-info/dependency_links.txt +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/codeboarding_cli/__init__.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/codeboarding_cli/commands/__init__.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/codeboarding_cli/view_instructions.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/codeboarding_workflows/__init__.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/codeboarding_workflows/orchestration.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/codeboarding_workflows/sources/__init__.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/codeboarding_workflows/sources/local.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/diagram_analysis/__init__.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/diagram_analysis/exceptions.py +0 -0
- {codeboarding-0.14.5/static_analyzer → codeboarding-0.15.1/diagram_analysis}/reference_resolver.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/diagram_analysis/run_mode.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/diagram_analysis/tree_shape.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/health/__init__.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/health/checks/__init__.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/health/checks/circular_deps.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/health/checks/unused_code_diagnostics.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/health/models.py +0 -0
- {codeboarding-0.14.5/core → codeboarding-0.15.1/health/plugins}/protocols.py +0 -0
- {codeboarding-0.14.5/core → codeboarding-0.15.1/health/plugins}/registry.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1/infra}/clustering_ids.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1/infra}/constants.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1/infra}/logging_config.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1/infra}/monitoring/stats.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1/infra/monitoring}/telemetry/device_id.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1/infra/monitoring}/telemetry/schemas.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1/infra}/repo_utils/errors.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1/infra}/repo_utils/git_ops.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1/infra}/repo_utils/path_utils.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/output_generators/__init__.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/output_generators/html_template.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/setup.cfg +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/static_analyzer/analysis_result.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/static_analyzer/cfg/__init__.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/static_analyzer/cfg/edge.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/static_analyzer/cfg/location_key.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/static_analyzer/clustering/__init__.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/static_analyzer/clustering/exceptions.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/static_analyzer/clustering/names/__init__.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/static_analyzer/clustering/names/frontier.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/static_analyzer/clustering/names/replay.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/static_analyzer/clustering/names/tokens.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/static_analyzer/dotnet_solution.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/static_analyzer/engine/__init__.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/static_analyzer/engine/edge_build_context.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/static_analyzer/engine/models.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/static_analyzer/engine/progress.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/static_analyzer/engine/symbol_table.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/static_analyzer/engine/utils.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/static_analyzer/internal_references.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/static_analyzer/lsp_client/__init__.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/static_analyzer/lsp_client/diagnostics.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/static_analyzer/node.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/static_analyzer/programming_language.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/tests/test_view_instructions.py +0 -0
- {codeboarding-0.14.5 → codeboarding-0.15.1}/tests/test_windows_encoding.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codeboarding
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.15.1
|
|
4
4
|
Summary: Interactive Diagrams for Code
|
|
5
5
|
Author: CodeBoarding Team
|
|
6
6
|
License-Expression: MIT
|
|
@@ -52,6 +52,7 @@ Requires-Dist: tree-sitter-c-sharp==0.23.5
|
|
|
52
52
|
Requires-Dist: tree-sitter-go==0.25.0
|
|
53
53
|
Requires-Dist: tree-sitter-java==0.23.5
|
|
54
54
|
Requires-Dist: tree-sitter-javascript==0.25.0
|
|
55
|
+
Requires-Dist: tree-sitter-language-pack==1.21.0
|
|
55
56
|
Requires-Dist: tree-sitter-php==0.24.1
|
|
56
57
|
Requires-Dist: tree-sitter-python==0.25.0
|
|
57
58
|
Requires-Dist: tree-sitter-rust==0.24.2
|
|
@@ -84,13 +85,14 @@ Dynamic: license-file
|
|
|
84
85
|
- Builds layered abstractions with an LLM agent (OpenAI, Anthropic, Google Gemini, Ollama, and more)
|
|
85
86
|
- Outputs Mermaid.js diagrams ready for docs, IDEs, and CI/CD pipelines
|
|
86
87
|
|
|
87
|
-
**Supported languages:** Python · TypeScript · JavaScript · Java · Go · PHP
|
|
88
|
+
**Supported languages:** Python · TypeScript · JavaScript · Java · Kotlin · Go · PHP
|
|
88
89
|
|
|
89
90
|
---
|
|
90
91
|
|
|
91
92
|
## Requirements
|
|
92
93
|
|
|
93
94
|
- **Python 3.12 or 3.13** — other versions are currently not supported.
|
|
95
|
+
- **Linux:** glibc 2.34 or newer (Ubuntu 22.04, Debian 12, RHEL 9 or later), for the Kotlin parser.
|
|
94
96
|
|
|
95
97
|
## Installation
|
|
96
98
|
|
|
@@ -11,13 +11,14 @@
|
|
|
11
11
|
- Builds layered abstractions with an LLM agent (OpenAI, Anthropic, Google Gemini, Ollama, and more)
|
|
12
12
|
- Outputs Mermaid.js diagrams ready for docs, IDEs, and CI/CD pipelines
|
|
13
13
|
|
|
14
|
-
**Supported languages:** Python · TypeScript · JavaScript · Java · Go · PHP
|
|
14
|
+
**Supported languages:** Python · TypeScript · JavaScript · Java · Kotlin · Go · PHP
|
|
15
15
|
|
|
16
16
|
---
|
|
17
17
|
|
|
18
18
|
## Requirements
|
|
19
19
|
|
|
20
20
|
- **Python 3.12 or 3.13** — other versions are currently not supported.
|
|
21
|
+
- **Linux:** glibc 2.34 or newer (Ubuntu 22.04, Debian 12, RHEL 9 or later), for the Kotlin parser.
|
|
21
22
|
|
|
22
23
|
## Installation
|
|
23
24
|
|
|
@@ -17,6 +17,7 @@ The example starts with a large pull-request diff, then shows the six components
|
|
|
17
17
|
[](https://developer.mozilla.org/en-US/docs/Web/JavaScript)
|
|
18
18
|
[](https://www.typescriptlang.org/)
|
|
19
19
|
[](https://www.java.com/)
|
|
20
|
+
[](https://kotlinlang.org/)
|
|
20
21
|
[](https://www.python.org/)
|
|
21
22
|
[](https://go.dev/)
|
|
22
23
|
[](https://www.php.net/)
|
|
@@ -103,8 +104,8 @@ git clone https://github.com/CodeBoarding/CodeBoarding.git
|
|
|
103
104
|
cd CodeBoarding
|
|
104
105
|
uv sync --frozen
|
|
105
106
|
source .venv/bin/activate # On Windows: .venv\Scripts\activate
|
|
106
|
-
python install
|
|
107
|
-
python main
|
|
107
|
+
python -m infra.install
|
|
108
|
+
python -m codeboarding_cli.main full --local /path/to/repo
|
|
108
109
|
```
|
|
109
110
|
|
|
110
111
|
### Use the packaged CLI
|
|
@@ -152,7 +153,7 @@ codeboarding-render /path/to/analysis.json --format mdx --output-dir /path/to/do
|
|
|
152
153
|
python codeboarding_cli/render.py ../../demo/markitdown/.codeboarding/analysis.json --format md
|
|
153
154
|
```
|
|
154
155
|
|
|
155
|
-
`python install
|
|
156
|
+
`python -m infra.install` and `codeboarding-setup` download language server binaries to `~/.codeboarding/servers/`, shared across projects. 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.
|
|
156
157
|
|
|
157
158
|
## Configuration
|
|
158
159
|
|
|
@@ -184,32 +185,33 @@ On first run, CodeBoarding creates `~/.codeboarding/config.toml`. Set one provid
|
|
|
184
185
|
|
|
185
186
|
Shell environment variables such as `OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, `GOOGLE_API_KEY`, and `OLLAMA_BASE_URL` take precedence over the config file. For private repositories, set `GITHUB_TOKEN` in your environment.
|
|
186
187
|
|
|
187
|
-
|
|
188
|
+
Three environment variables tune the static analysis itself:
|
|
188
189
|
|
|
189
190
|
| Variable | Effect |
|
|
190
191
|
| --- | --- |
|
|
191
|
-
| `CODEBOARDING_LSP_REQUEST_TIMEOUT` | Seconds a language-server request may block *when it uses the per-language default* (120s for C
|
|
192
|
-
| `CODEBOARDING_MAX_CONCURRENT_ENGINES` | How many language servers
|
|
192
|
+
| `CODEBOARDING_LSP_REQUEST_TIMEOUT` | Seconds a language-server request may block *when it uses the per-language default* (120s for C# and Kotlin, 60s elsewhere). Not a hard cap on every request: `initialize` has its own startup budget (the request default), Kotlin's build import is awaited separately (up to 1800s), and the indexing and didOpen-drain probes pass their own scaled budget (60s plus 2s per file, capped at 1800s); neither is affected. Applies to every language in the run. Unset or empty leaves the defaults alone; any other unusable value fails the run rather than falling back. |
|
|
193
|
+
| `CODEBOARDING_MAX_CONCURRENT_ENGINES` | How many language servers an analysis runs at once. Unset or `0`, the CLI and the GitHub Action run one at a time, each stopped when its language is done, and the editor keeps one per project running. Set, the editor's servers also start only for an analysis, so its file queries are unavailable. |
|
|
194
|
+
| `CODEBOARDING_LSP_MEMORY_BUDGET_MB` | Megabytes the language servers running at once share; tsserver's heap is its share less 512. Unset, it is three quarters of the machine's memory (or of a cgroup v2 container's limit, when lower), at most 12 GB. |
|
|
193
195
|
|
|
194
196
|
## Common commands
|
|
195
197
|
|
|
196
198
|
```bash
|
|
197
199
|
# Analyze a local repository
|
|
198
|
-
python main
|
|
200
|
+
python -m codeboarding_cli.main full --local ./my-project
|
|
199
201
|
|
|
200
202
|
# Raise the depth ceiling to auto-expand deeper (rarely needed — a component that
|
|
201
203
|
# outgrows the leaf ceiling is flagged expandable at whatever depth the run stops
|
|
202
204
|
# and can be expanded on demand; --depth-cap is a safety-valve cap, default 3)
|
|
203
|
-
python main
|
|
205
|
+
python -m codeboarding_cli.main full --local ./my-project --depth-cap 5
|
|
204
206
|
|
|
205
207
|
# Re-analyze only changed parts when possible
|
|
206
|
-
python main
|
|
208
|
+
python -m codeboarding_cli.main incremental --local ./my-project
|
|
207
209
|
|
|
208
210
|
# Update a single component by ID
|
|
209
|
-
python main
|
|
211
|
+
python -m codeboarding_cli.main partial --local ./my-project --component-id "1.2"
|
|
210
212
|
|
|
211
213
|
# Analyze a remote GitHub repository
|
|
212
|
-
python main
|
|
214
|
+
python -m codeboarding_cli.main full https://github.com/pytorch/pytorch
|
|
213
215
|
```
|
|
214
216
|
|
|
215
217
|
`--depth-cap` configures `metadata.depth_cap`; `metadata.depth_level` records the
|
|
@@ -244,7 +246,9 @@ for the actual depth. Existing baseline loading behavior is unchanged: prefer
|
|
|
244
246
|
|
|
245
247
|
## Supported stack
|
|
246
248
|
|
|
247
|
-
- Languages: Python, TypeScript, JavaScript, Java, Go, PHP, Rust, C#.
|
|
249
|
+
- Languages: Python, TypeScript, JavaScript, Java, Kotlin, Go, PHP, Rust, C#.
|
|
250
|
+
- Java needs a JDK (21 recommended).
|
|
251
|
+
- 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.
|
|
248
252
|
- LLM providers: OpenAI, Anthropic, Google, Vercel AI Gateway, AWS Bedrock, Ollama, OpenRouter, OrcaRouter, Requesty, LiteLLM proxy, and more.
|
|
249
253
|
|
|
250
254
|
## Examples
|
|
@@ -8,7 +8,7 @@ from enum import StrEnum
|
|
|
8
8
|
|
|
9
9
|
from pydantic import BaseModel, Field
|
|
10
10
|
|
|
11
|
-
from clustering_ids import ComponentId
|
|
11
|
+
from infra.clustering_ids import ComponentId
|
|
12
12
|
from agents.file_index_models import FileEntry, FileMethodGroup, MethodIndexEntry
|
|
13
13
|
from agents.scope_ids import ROOT_SCOPE_ID
|
|
14
14
|
|
|
@@ -15,12 +15,7 @@ from langchain_openai import ChatOpenAI
|
|
|
15
15
|
from agents.constants import LLMDefaults, ModelCapabilities
|
|
16
16
|
from agents.model_capabilities import ContextWindow, get_context_window
|
|
17
17
|
from agents.prompts import PromptProfile, resolve_prompt_profile
|
|
18
|
-
from monitoring.callbacks import
|
|
19
|
-
|
|
20
|
-
# Initialize global monitoring callback with its own stats container to avoid ContextVar dependency
|
|
21
|
-
from monitoring.stats import RunStats
|
|
22
|
-
|
|
23
|
-
MONITORING_CALLBACK = MonitoringCallback(stats_container=RunStats())
|
|
18
|
+
from infra.monitoring.callbacks import MONITORING_CALLBACK
|
|
24
19
|
|
|
25
20
|
logger = logging.getLogger(__name__)
|
|
26
21
|
|
|
@@ -15,8 +15,10 @@ dashboard's structured ``error`` columns — populate instead of staying null.
|
|
|
15
15
|
|
|
16
16
|
from __future__ import annotations
|
|
17
17
|
|
|
18
|
+
import email.utils
|
|
18
19
|
import logging
|
|
19
20
|
import re
|
|
21
|
+
import time
|
|
20
22
|
|
|
21
23
|
from agents.llm_config import CODEBOARDING_KEY_TAIL, current_provider_key_context
|
|
22
24
|
|
|
@@ -62,6 +64,11 @@ _AUTH_MESSAGE_PATTERNS = (
|
|
|
62
64
|
)
|
|
63
65
|
|
|
64
66
|
|
|
67
|
+
# Class names, across SDKs, for a request that never got an answer: openai/anthropic/cerebras raise
|
|
68
|
+
# ``APIConnectionError`` (``APITimeoutError`` subclasses it), ollama lets httpx's ``TransportError`` through.
|
|
69
|
+
_TRANSIENT_TYPE_NAMES = {"APIConnectionError", "TransportError", "TimeoutError", "ConnectionError"}
|
|
70
|
+
|
|
71
|
+
|
|
65
72
|
# What each provider says when the prompt is over the model's context window: Google, OpenAI, Anthropic.
|
|
66
73
|
_CONTEXT_OVERFLOW_PATTERNS = (
|
|
67
74
|
re.compile(r"exceeds the maximum number of tokens", re.IGNORECASE),
|
|
@@ -111,6 +118,10 @@ def _status_code(exc: BaseException) -> int | None:
|
|
|
111
118
|
code = getattr(exc, "status_code", None)
|
|
112
119
|
if code is None:
|
|
113
120
|
code = getattr(exc, "code", None) # google GoogleAPICallError.code
|
|
121
|
+
if code is None:
|
|
122
|
+
response = getattr(exc, "response", None) # botocore ClientError (Bedrock) keeps it in a dict
|
|
123
|
+
if isinstance(response, dict):
|
|
124
|
+
code = response.get("ResponseMetadata", {}).get("HTTPStatusCode")
|
|
114
125
|
if code is None:
|
|
115
126
|
return None
|
|
116
127
|
try:
|
|
@@ -144,7 +155,11 @@ def detect_auth_error(exc: BaseException, *, provider: str, key_tail: str) -> LL
|
|
|
144
155
|
status = _status_code(exc)
|
|
145
156
|
provider_message = str(exc)
|
|
146
157
|
status_note = f" (HTTP {status})" if status is not None else ""
|
|
147
|
-
if
|
|
158
|
+
if status == 403:
|
|
159
|
+
# A 403 can refuse one request (a router's moderation, a model the key may not use) while the same key
|
|
160
|
+
# serves the rest, so the provider's own reason says more than a hint about the key.
|
|
161
|
+
friendly = f"{provider} refused the request (HTTP 403): {provider_message[:500]}"
|
|
162
|
+
elif key_tail == CODEBOARDING_KEY_TAIL:
|
|
148
163
|
friendly = (
|
|
149
164
|
f"CodeBoarding's hosted {provider} credentials were rejected{status_note}. This run used no key of "
|
|
150
165
|
"yours: check that the workflow grants `id-token: write`, then re-run."
|
|
@@ -168,6 +183,12 @@ def detect_auth_error(exc: BaseException, *, provider: str, key_tail: str) -> LL
|
|
|
168
183
|
)
|
|
169
184
|
|
|
170
185
|
|
|
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
|
+
|
|
171
192
|
def llm_failure_properties(exc: BaseException) -> dict:
|
|
172
193
|
"""``$exception`` properties for a failed LLM call, telling an exhausted quota or an oversized prompt
|
|
173
194
|
apart from other failures.
|
|
@@ -175,18 +196,52 @@ def llm_failure_properties(exc: BaseException) -> dict:
|
|
|
175
196
|
Why: the hosted proxy's paywall is a 402, and OpenAI reports an empty balance as a 429 ``insufficient_quota``.
|
|
176
197
|
An oversized prompt is ours to fix, not the provider's, so it gets its own type on the dashboard.
|
|
177
198
|
"""
|
|
178
|
-
|
|
179
|
-
quota = status == 402 or (status == 429 and "insufficient_quota" in str(exc))
|
|
199
|
+
quota = _is_quota_exhausted(exc)
|
|
180
200
|
context = isinstance(exc, ScopeContextTooLargeError) or any(p.search(str(exc)) for p in _CONTEXT_OVERFLOW_PATTERNS)
|
|
181
201
|
provider, _key_tail = current_provider_key_context()
|
|
182
202
|
return {
|
|
183
203
|
"error_type": "quota" if quota else "context" if context else "llm",
|
|
184
204
|
"error_provider": provider,
|
|
185
|
-
"error_status_code":
|
|
205
|
+
"error_status_code": _status_code(exc),
|
|
186
206
|
"error_message": str(exc)[:500],
|
|
187
207
|
}
|
|
188
208
|
|
|
189
209
|
|
|
210
|
+
def is_transient_llm_error(exc: BaseException) -> bool:
|
|
211
|
+
"""Whether the same request may succeed if sent again: throttled, a server error, or no answer at all.
|
|
212
|
+
|
|
213
|
+
Why: the hosted proxy answers a burst over its concurrency cap with a 429 and a failed upstream call with a
|
|
214
|
+
502, and one of either used to fail the whole run. A rejected key, a spent quota or a malformed request fails
|
|
215
|
+
the same way every time.
|
|
216
|
+
"""
|
|
217
|
+
status = _status_code(exc)
|
|
218
|
+
if status is not None:
|
|
219
|
+
return status in (408, 429) and not _is_quota_exhausted(exc) or status >= 500
|
|
220
|
+
return any(cls.__name__ in _TRANSIENT_TYPE_NAMES for cls in type(exc).__mro__)
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
def retry_after_seconds(exc: BaseException) -> float | None:
|
|
224
|
+
"""The wait a provider asked for, when the exception carries the response: ``retry-after-ms``, or
|
|
225
|
+
``Retry-After`` as seconds or an HTTP date. None when absent, unreadable or already past."""
|
|
226
|
+
headers = getattr(getattr(exc, "response", None), "headers", None)
|
|
227
|
+
if headers is None:
|
|
228
|
+
return None
|
|
229
|
+
try:
|
|
230
|
+
return max(0.0, float(headers.get("retry-after-ms", "")) / 1000)
|
|
231
|
+
except (TypeError, ValueError):
|
|
232
|
+
pass
|
|
233
|
+
value = headers.get("retry-after", "")
|
|
234
|
+
try:
|
|
235
|
+
return max(0.0, float(value))
|
|
236
|
+
except (TypeError, ValueError):
|
|
237
|
+
pass
|
|
238
|
+
try:
|
|
239
|
+
wait = email.utils.parsedate_to_datetime(value).timestamp() - time.time()
|
|
240
|
+
except (TypeError, ValueError):
|
|
241
|
+
return None
|
|
242
|
+
return wait if wait > 0 else None
|
|
243
|
+
|
|
244
|
+
|
|
190
245
|
def raise_if_auth_error(exc: Exception) -> None:
|
|
191
246
|
"""Raise a typed terminal error when a provider rejected its credentials."""
|
|
192
247
|
provider, key_tail = current_provider_key_context()
|
|
@@ -12,7 +12,7 @@ from typing import Any
|
|
|
12
12
|
from agents.agent_responses import AnalysisInsights
|
|
13
13
|
from agents.constants import ModelCapabilities
|
|
14
14
|
from agents.llm_errors import ScopeContextTooLargeError
|
|
15
|
-
from repo_utils.path_utils import normalize_repo_path
|
|
15
|
+
from infra.repo_utils.path_utils import normalize_repo_path
|
|
16
16
|
from static_analyzer.cfg.edge import EdgeKind
|
|
17
17
|
from static_analyzer.clustering import ClusterConnectionEdge, ClusterGroup, ClusterScopeResult
|
|
18
18
|
from static_analyzer.node import Node
|
|
@@ -9,7 +9,7 @@ from functools import lru_cache
|
|
|
9
9
|
from pathlib import Path
|
|
10
10
|
|
|
11
11
|
from agents.constants import ModelCapabilities
|
|
12
|
-
from utils import get_cache_dir
|
|
12
|
+
from infra.utils import get_cache_dir
|
|
13
13
|
|
|
14
14
|
logger = logging.getLogger(__name__)
|
|
15
15
|
|
|
@@ -74,7 +74,7 @@ def _resolve_user_config(provider: str, model_name: str) -> tuple[int, int] | No
|
|
|
74
74
|
def _user_context_window_override() -> int | None:
|
|
75
75
|
# Why: delayed import avoids a module-load cycle; lru_cache avoids re-parsing
|
|
76
76
|
# config.toml on every get_context_window call.
|
|
77
|
-
from user_config import load_user_config
|
|
77
|
+
from infra.user_config import load_user_config
|
|
78
78
|
|
|
79
79
|
return load_user_config().llm.context_window
|
|
80
80
|
|
|
@@ -4,8 +4,8 @@ from collections.abc import Callable, Collection
|
|
|
4
4
|
from pathlib import Path
|
|
5
5
|
|
|
6
6
|
from agents.agent_responses import AnalysisInsights, Relation, RelationEdge, SourceCodeReference
|
|
7
|
-
from clustering_ids import is_self_or_descendant
|
|
8
|
-
from repo_utils.path_utils import normalize_repo_path
|
|
7
|
+
from infra.clustering_ids import is_self_or_descendant
|
|
8
|
+
from infra.repo_utils.path_utils import normalize_repo_path
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
def append_or_merge_relation(
|
|
@@ -3,12 +3,15 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import logging
|
|
6
|
+
import random
|
|
6
7
|
import time
|
|
7
8
|
from collections.abc import Callable
|
|
8
9
|
from dataclasses import dataclass
|
|
9
10
|
from enum import Enum, auto
|
|
10
11
|
from typing import TypeVar
|
|
11
12
|
|
|
13
|
+
from agents.llm_errors import is_transient_llm_error, retry_after_seconds
|
|
14
|
+
|
|
12
15
|
logger = logging.getLogger(__name__)
|
|
13
16
|
|
|
14
17
|
T = TypeVar("T")
|
|
@@ -37,6 +40,29 @@ def default_backoff(attempt: int, *, initial_s: float, multiplier: float, max_s:
|
|
|
37
40
|
return min(delay, max_s) if max_s is not None else delay
|
|
38
41
|
|
|
39
42
|
|
|
43
|
+
#: Attempts per model request. Why these numbers: the full-jitter ceilings run 4, 8, 16 and 32 s, so the
|
|
44
|
+
#: four retries span up to a minute — long enough for a slot to free up behind the hosted proxy's concurrency cap
|
|
45
|
+
#: (one held slot is one model call in flight, often tens of seconds) without doubling a run that is failing anyway.
|
|
46
|
+
LLM_MAX_ATTEMPTS = 5
|
|
47
|
+
LLM_BACKOFF_INITIAL_S = 4.0
|
|
48
|
+
LLM_BACKOFF_MAX_S = 60.0
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def classify_llm_error(exc: Exception, attempt: int) -> RetryDecision:
|
|
52
|
+
"""Retry a transient provider failure after the wait its ``Retry-After`` asks for, else a full-jitter backoff.
|
|
53
|
+
|
|
54
|
+
Why full jitter: the parallel calls one burst throttles would otherwise all retry in the same second and
|
|
55
|
+
collide again.
|
|
56
|
+
"""
|
|
57
|
+
if not is_transient_llm_error(exc):
|
|
58
|
+
return RetryDecision(action=RetryAction.GIVE_UP)
|
|
59
|
+
delay = retry_after_seconds(exc)
|
|
60
|
+
if delay is None:
|
|
61
|
+
ceiling = default_backoff(attempt, initial_s=LLM_BACKOFF_INITIAL_S, multiplier=2.0, max_s=LLM_BACKOFF_MAX_S)
|
|
62
|
+
delay = random.uniform(0.0, ceiling)
|
|
63
|
+
return RetryDecision(action=RetryAction.RETRY, backoff_s=min(delay, LLM_BACKOFF_MAX_S))
|
|
64
|
+
|
|
65
|
+
|
|
40
66
|
def _default_classify(_exc: Exception, _attempt: int) -> RetryDecision:
|
|
41
67
|
return RetryDecision(action=RetryAction.RETRY)
|
|
42
68
|
|
|
@@ -25,13 +25,15 @@ from pydantic import Field
|
|
|
25
25
|
|
|
26
26
|
from agents.agent_responses import AnalysisInsights, LLMBaseModel, RelationEdge, SourceCodeReference
|
|
27
27
|
from agents.constants import ModelCapabilities
|
|
28
|
-
from agents.llm_config import
|
|
28
|
+
from agents.llm_config import get_current_agent_context_window, get_current_prompt_profile
|
|
29
|
+
from infra.monitoring.callbacks import MONITORING_CALLBACK
|
|
29
30
|
from agents.llm_errors import ScopeContextTooLargeError, raise_if_auth_error
|
|
30
31
|
from agents.llm_renderers import render_scope_context, scope_file_paths, scope_method_names
|
|
31
32
|
from agents.prompts import get_scope_analysis_prompts
|
|
33
|
+
from agents.retry import LLM_MAX_ATTEMPTS, classify_llm_error, with_retries
|
|
32
34
|
from agents.tools import MethodCallsTool, ReadFileTool
|
|
33
35
|
from agents.tools.base import RepoContext
|
|
34
|
-
from monitoring.mixin import MonitoringMixin
|
|
36
|
+
from infra.monitoring.mixin import MonitoringMixin
|
|
35
37
|
from static_analyzer.analysis_result import StaticAnalysisResults
|
|
36
38
|
from static_analyzer.clustering import ClusterScopeResult
|
|
37
39
|
|
|
@@ -159,6 +161,24 @@ class ScopeInputBudget(AgentMiddleware):
|
|
|
159
161
|
logger.warning("Scope %s: truncating tool result %s to fit context", self.scope_id, message.tool_call_id)
|
|
160
162
|
|
|
161
163
|
|
|
164
|
+
class TransientErrorRetry(AgentMiddleware):
|
|
165
|
+
"""Send a model request again when the provider failed it transiently (throttled, 5xx, connection lost).
|
|
166
|
+
|
|
167
|
+
Why here: one model request is retried, not the agent run, so the tool calls already made are kept.
|
|
168
|
+
"""
|
|
169
|
+
|
|
170
|
+
def __init__(self, scope_id: str):
|
|
171
|
+
self.scope_id = scope_id
|
|
172
|
+
|
|
173
|
+
def wrap_model_call(self, request: ModelRequest, handler: Callable[[ModelRequest], ModelResponse]) -> ModelResponse:
|
|
174
|
+
return with_retries(
|
|
175
|
+
lambda: handler(request),
|
|
176
|
+
max_attempts=LLM_MAX_ATTEMPTS,
|
|
177
|
+
classify=classify_llm_error,
|
|
178
|
+
log_prefix=f"Scope {self.scope_id} model call",
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
|
|
162
182
|
class ScopeAnalysisAgent(MonitoringMixin):
|
|
163
183
|
"""Analyze any deterministic scope with two scope-restricted tools."""
|
|
164
184
|
|
|
@@ -209,6 +229,7 @@ class ScopeAnalysisAgent(MonitoringMixin):
|
|
|
209
229
|
RepositoryToolBudget(run_limit=MAX_SCOPE_TOOL_CALLS, exit_behavior="continue"),
|
|
210
230
|
ModelCallLimitMiddleware(run_limit=MAX_SCOPE_MODEL_CALLS, exit_behavior="error"),
|
|
211
231
|
input_budget,
|
|
232
|
+
TransientErrorRetry(scope.scope_id),
|
|
212
233
|
]
|
|
213
234
|
agent: CompiledStateGraph = create_agent(
|
|
214
235
|
model=self.agent_llm,
|
|
@@ -4,7 +4,7 @@ from langchain_core.tools import ArgsSchema
|
|
|
4
4
|
from pydantic import BaseModel, Field
|
|
5
5
|
|
|
6
6
|
from agents.tools.base import BaseRepoTool
|
|
7
|
-
from repo_utils.path_utils import normalize_repo_path
|
|
7
|
+
from infra.repo_utils.path_utils import normalize_repo_path
|
|
8
8
|
|
|
9
9
|
logger = logging.getLogger(__name__)
|
|
10
10
|
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import json
|
|
4
4
|
import logging
|
|
5
5
|
import re
|
|
6
|
+
import time
|
|
6
7
|
from collections import Counter
|
|
7
8
|
from collections.abc import Sequence
|
|
8
9
|
from concurrent.futures import ThreadPoolExecutor
|
|
@@ -13,12 +14,13 @@ from langchain_core.messages import HumanMessage, SystemMessage
|
|
|
13
14
|
from langchain_core.prompts import PromptTemplate
|
|
14
15
|
|
|
15
16
|
from agents.agent_responses import PlannedGroup, TreePlanInsights
|
|
16
|
-
from agents.llm_config import
|
|
17
|
+
from agents.llm_config import get_current_prompt_profile, supports_json_mode
|
|
18
|
+
from infra.monitoring.callbacks import MONITORING_CALLBACK
|
|
17
19
|
from agents.llm_errors import LLMAuthError, raise_if_auth_error
|
|
18
20
|
from agents.prompts import get_tree_plan_prompts
|
|
19
|
-
from agents.retry import RetryAction, RetryDecision,
|
|
20
|
-
from monitoring import trace
|
|
21
|
-
from monitoring.mixin import MonitoringMixin
|
|
21
|
+
from agents.retry import LLM_MAX_ATTEMPTS, RetryAction, RetryDecision, classify_llm_error, with_retries
|
|
22
|
+
from infra.monitoring import trace
|
|
23
|
+
from infra.monitoring.mixin import MonitoringMixin
|
|
22
24
|
from static_analyzer.clustering.names import CandidateGroup, GroupingContext, KinshipGrouper, stem, tokenize
|
|
23
25
|
from static_analyzer.clustering.names.draft import GUARD_SHARE, MIN_UNITS
|
|
24
26
|
from static_analyzer.clustering.names.frontier import Candidate
|
|
@@ -135,15 +137,21 @@ class TreePlannerAgent(MonitoringMixin):
|
|
|
135
137
|
raise ValueError("planner returned malformed JSON")
|
|
136
138
|
return insights
|
|
137
139
|
|
|
140
|
+
# Why: ``_draw`` stops waiting after DRAW_TIMEOUT_SECONDS but cannot stop this worker, so no new
|
|
141
|
+
# attempt starts once the draw has been abandoned.
|
|
142
|
+
deadline = time.monotonic() + DRAW_TIMEOUT_SECONDS
|
|
143
|
+
|
|
138
144
|
def classify(exc: Exception, attempt: int) -> RetryDecision:
|
|
139
145
|
raise_if_auth_error(exc)
|
|
140
146
|
if isinstance(exc, ValueError):
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
)
|
|
145
|
-
|
|
146
|
-
|
|
147
|
+
decision = RetryDecision(action=RetryAction.RETRY_NOW)
|
|
148
|
+
else:
|
|
149
|
+
decision = classify_llm_error(exc, attempt)
|
|
150
|
+
if time.monotonic() + decision.backoff_s >= deadline:
|
|
151
|
+
return RetryDecision(action=RetryAction.GIVE_UP)
|
|
152
|
+
return decision
|
|
153
|
+
|
|
154
|
+
return with_retries(once, max_attempts=LLM_MAX_ATTEMPTS, classify=classify, log_prefix="Planner draw")
|
|
147
155
|
|
|
148
156
|
@staticmethod
|
|
149
157
|
def _read(text: str, labelled: dict[str, CandidateGroup]) -> TreePlanInsights | None:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codeboarding
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.15.1
|
|
4
4
|
Summary: Interactive Diagrams for Code
|
|
5
5
|
Author: CodeBoarding Team
|
|
6
6
|
License-Expression: MIT
|
|
@@ -52,6 +52,7 @@ Requires-Dist: tree-sitter-c-sharp==0.23.5
|
|
|
52
52
|
Requires-Dist: tree-sitter-go==0.25.0
|
|
53
53
|
Requires-Dist: tree-sitter-java==0.23.5
|
|
54
54
|
Requires-Dist: tree-sitter-javascript==0.25.0
|
|
55
|
+
Requires-Dist: tree-sitter-language-pack==1.21.0
|
|
55
56
|
Requires-Dist: tree-sitter-php==0.24.1
|
|
56
57
|
Requires-Dist: tree-sitter-python==0.25.0
|
|
57
58
|
Requires-Dist: tree-sitter-rust==0.24.2
|
|
@@ -84,13 +85,14 @@ Dynamic: license-file
|
|
|
84
85
|
- Builds layered abstractions with an LLM agent (OpenAI, Anthropic, Google Gemini, Ollama, and more)
|
|
85
86
|
- Outputs Mermaid.js diagrams ready for docs, IDEs, and CI/CD pipelines
|
|
86
87
|
|
|
87
|
-
**Supported languages:** Python · TypeScript · JavaScript · Java · Go · PHP
|
|
88
|
+
**Supported languages:** Python · TypeScript · JavaScript · Java · Kotlin · Go · PHP
|
|
88
89
|
|
|
89
90
|
---
|
|
90
91
|
|
|
91
92
|
## Requirements
|
|
92
93
|
|
|
93
94
|
- **Python 3.12 or 3.13** — other versions are currently not supported.
|
|
95
|
+
- **Linux:** glibc 2.34 or newer (Ubuntu 22.04, Debian 12, RHEL 9 or later), for the Kotlin parser.
|
|
94
96
|
|
|
95
97
|
## Installation
|
|
96
98
|
|