attocode-code-intel 0.1.0__py3-none-any.whl

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.
Files changed (345) hide show
  1. attocode_code_intel-0.1.0.dist-info/METADATA +221 -0
  2. attocode_code_intel-0.1.0.dist-info/RECORD +345 -0
  3. attocode_code_intel-0.1.0.dist-info/WHEEL +4 -0
  4. attocode_code_intel-0.1.0.dist-info/entry_points.txt +2 -0
  5. attocode_code_intel-0.1.0.dist-info/licenses/LICENSE +21 -0
  6. attocode_intel/GUIDELINES.md +432 -0
  7. attocode_intel/__init__.py +52 -0
  8. attocode_intel/_internal/__init__.py +1 -0
  9. attocode_intel/_internal/errors/__init__.py +126 -0
  10. attocode_intel/_internal/integrations/__init__.py +1 -0
  11. attocode_intel/_internal/integrations/context/__init__.py +1 -0
  12. attocode_intel/_internal/integrations/context/architecture_drift.py +354 -0
  13. attocode_intel/_internal/integrations/context/ast_chunker.py +202 -0
  14. attocode_intel/_internal/integrations/context/ast_service.py +1483 -0
  15. attocode_intel/_internal/integrations/context/blob_oid.py +423 -0
  16. attocode_intel/_internal/integrations/context/cache_manifest.py +221 -0
  17. attocode_intel/_internal/integrations/context/cas.py +466 -0
  18. attocode_intel/_internal/integrations/context/code_analyzer.py +528 -0
  19. attocode_intel/_internal/integrations/context/codebase_ast.py +1461 -0
  20. attocode_intel/_internal/integrations/context/codebase_context.py +1736 -0
  21. attocode_intel/_internal/integrations/context/cross_mode.py +263 -0
  22. attocode_intel/_internal/integrations/context/cross_references.py +616 -0
  23. attocode_intel/_internal/integrations/context/embedding_rotation.py +597 -0
  24. attocode_intel/_internal/integrations/context/embeddings.py +282 -0
  25. attocode_intel/_internal/integrations/context/frecency.py +427 -0
  26. attocode_intel/_internal/integrations/context/fuzzy.py +320 -0
  27. attocode_intel/_internal/integrations/context/hierarchical_explorer.py +331 -0
  28. attocode_intel/_internal/integrations/context/hydration.py +90 -0
  29. attocode_intel/_internal/integrations/context/index_repair.py +87 -0
  30. attocode_intel/_internal/integrations/context/index_store.py +586 -0
  31. attocode_intel/_internal/integrations/context/memory_store.py +602 -0
  32. attocode_intel/_internal/integrations/context/module_resolution.py +52 -0
  33. attocode_intel/_internal/integrations/context/query_constraints.py +361 -0
  34. attocode_intel/_internal/integrations/context/query_history.py +417 -0
  35. attocode_intel/_internal/integrations/context/reranker.py +351 -0
  36. attocode_intel/_internal/integrations/context/semantic_search.py +2931 -0
  37. attocode_intel/_internal/integrations/context/syntax_evidence.py +94 -0
  38. attocode_intel/_internal/integrations/context/systemone_ranker.py +245 -0
  39. attocode_intel/_internal/integrations/context/temporal_coupling.py +411 -0
  40. attocode_intel/_internal/integrations/context/trigram_index.py +820 -0
  41. attocode_intel/_internal/integrations/context/trigram_regex.py +171 -0
  42. attocode_intel/_internal/integrations/context/ts_parser.py +2199 -0
  43. attocode_intel/_internal/integrations/context/vector_store.py +795 -0
  44. attocode_intel/_internal/integrations/feature_flags/__init__.py +357 -0
  45. attocode_intel/_internal/integrations/lsp/__init__.py +1 -0
  46. attocode_intel/_internal/integrations/lsp/client.py +1140 -0
  47. attocode_intel/_internal/integrations/mcp/__init__.py +1 -0
  48. attocode_intel/_internal/integrations/mcp/client.py +253 -0
  49. attocode_intel/_internal/integrations/security/__init__.py +1 -0
  50. attocode_intel/_internal/integrations/security/custom_rules.py +176 -0
  51. attocode_intel/_internal/integrations/security/dataflow.py +522 -0
  52. attocode_intel/_internal/integrations/security/dependency_audit.py +303 -0
  53. attocode_intel/_internal/integrations/security/matcher.py +44 -0
  54. attocode_intel/_internal/integrations/security/patterns.py +724 -0
  55. attocode_intel/_internal/integrations/security/scanner.py +351 -0
  56. attocode_intel/_internal/integrations/utilities/__init__.py +1 -0
  57. attocode_intel/_internal/integrations/utilities/ignore.py +64 -0
  58. attocode_intel/_internal/integrations/utilities/token_estimate.py +51 -0
  59. attocode_intel/_internal/tricks/__init__.py +1 -0
  60. attocode_intel/_internal/tricks/recursive_context.py +357 -0
  61. attocode_intel/_internal/types/__init__.py +1 -0
  62. attocode_intel/_internal/types/events.py +289 -0
  63. attocode_intel/_internal/types/severity.py +15 -0
  64. attocode_intel/_shared.py +341 -0
  65. attocode_intel/analysis_coverage.py +56 -0
  66. attocode_intel/api/__init__.py +1 -0
  67. attocode_intel/api/access.py +32 -0
  68. attocode_intel/api/app.py +247 -0
  69. attocode_intel/api/auth/__init__.py +128 -0
  70. attocode_intel/api/auth/api_keys.py +61 -0
  71. attocode_intel/api/auth/context.py +34 -0
  72. attocode_intel/api/auth/jwt.py +66 -0
  73. attocode_intel/api/auth/oauth.py +146 -0
  74. attocode_intel/api/auth/passwords.py +15 -0
  75. attocode_intel/api/deps.py +351 -0
  76. attocode_intel/api/knowledge_bridge.py +13 -0
  77. attocode_intel/api/mcp_transport.py +51 -0
  78. attocode_intel/api/middleware.py +411 -0
  79. attocode_intel/api/models.py +698 -0
  80. attocode_intel/api/providers/__init__.py +1 -0
  81. attocode_intel/api/providers/db_provider.py +1106 -0
  82. attocode_intel/api/providers/local_provider.py +476 -0
  83. attocode_intel/api/providers/remote_provider.py +740 -0
  84. attocode_intel/api/repository_source.py +21 -0
  85. attocode_intel/api/routes/__init__.py +1 -0
  86. attocode_intel/api/routes/_pin_helper.py +158 -0
  87. attocode_intel/api/routes/activity.py +148 -0
  88. attocode_intel/api/routes/adr.py +102 -0
  89. attocode_intel/api/routes/analysis.py +515 -0
  90. attocode_intel/api/routes/api_keys.py +170 -0
  91. attocode_intel/api/routes/auth.py +428 -0
  92. attocode_intel/api/routes/branches.py +262 -0
  93. attocode_intel/api/routes/cross_repo_search.py +198 -0
  94. attocode_intel/api/routes/embeddings.py +386 -0
  95. attocode_intel/api/routes/files.py +132 -0
  96. attocode_intel/api/routes/files_v2.py +388 -0
  97. attocode_intel/api/routes/gc.py +322 -0
  98. attocode_intel/api/routes/git_v2.py +433 -0
  99. attocode_intel/api/routes/graph.py +174 -0
  100. attocode_intel/api/routes/graph_viz.py +160 -0
  101. attocode_intel/api/routes/health.py +62 -0
  102. attocode_intel/api/routes/history.py +175 -0
  103. attocode_intel/api/routes/jobs.py +84 -0
  104. attocode_intel/api/routes/learning.py +205 -0
  105. attocode_intel/api/routes/lsp.py +272 -0
  106. attocode_intel/api/routes/notify.py +623 -0
  107. attocode_intel/api/routes/operations.py +27 -0
  108. attocode_intel/api/routes/orgs.py +924 -0
  109. attocode_intel/api/routes/preferences.py +100 -0
  110. attocode_intel/api/routes/presence.py +42 -0
  111. attocode_intel/api/routes/projects.py +116 -0
  112. attocode_intel/api/routes/repos.py +47 -0
  113. attocode_intel/api/routes/search.py +180 -0
  114. attocode_intel/api/routes/snapshots.py +614 -0
  115. attocode_intel/api/routes/webhooks.py +313 -0
  116. attocode_intel/api/routes/websocket.py +116 -0
  117. attocode_intel/api/static/graph.html +239 -0
  118. attocode_intel/api/utils.py +96 -0
  119. attocode_intel/artifacts/__init__.py +45 -0
  120. attocode_intel/artifacts/hashing.py +230 -0
  121. attocode_intel/artifacts/provenance.py +190 -0
  122. attocode_intel/artifacts/retrieval_pin.py +159 -0
  123. attocode_intel/audit.py +59 -0
  124. attocode_intel/bug_finder.py +206 -0
  125. attocode_intel/bundle.py +80 -0
  126. attocode_intel/catalog.py +242 -0
  127. attocode_intel/change_review.py +75 -0
  128. attocode_intel/cli.py +3062 -0
  129. attocode_intel/community.py +63 -0
  130. attocode_intel/confidence/__init__.py +144 -0
  131. attocode_intel/confidence/jev.py +234 -0
  132. attocode_intel/confidence/llm.py +330 -0
  133. attocode_intel/confidence/redact.py +44 -0
  134. attocode_intel/confidence/settings.py +74 -0
  135. attocode_intel/config.py +256 -0
  136. attocode_intel/crypto.py +31 -0
  137. attocode_intel/db/__init__.py +7 -0
  138. attocode_intel/db/base.py +33 -0
  139. attocode_intel/db/engine.py +61 -0
  140. attocode_intel/db/models.py +529 -0
  141. attocode_intel/entrypoint.py +185 -0
  142. attocode_intel/focused_evidence.py +130 -0
  143. attocode_intel/freshness.py +154 -0
  144. attocode_intel/gateway.py +734 -0
  145. attocode_intel/git/__init__.py +7 -0
  146. attocode_intel/git/credentials.py +75 -0
  147. attocode_intel/git/manager.py +493 -0
  148. attocode_intel/git/models.py +96 -0
  149. attocode_intel/git/storage.py +98 -0
  150. attocode_intel/graph_query_parser.py +761 -0
  151. attocode_intel/helpers.py +712 -0
  152. attocode_intel/indexing/__init__.py +29 -0
  153. attocode_intel/indexing/debouncer.py +136 -0
  154. attocode_intel/indexing/delta_indexer.py +151 -0
  155. attocode_intel/indexing/full_indexer.py +323 -0
  156. attocode_intel/indexing/incremental.py +240 -0
  157. attocode_intel/indexing/parser.py +403 -0
  158. attocode_intel/indexing/summarizer.py +264 -0
  159. attocode_intel/installer.py +1896 -0
  160. attocode_intel/knowledge.py +269 -0
  161. attocode_intel/local_knowledge.py +77 -0
  162. attocode_intel/migrations/alembic.ini +36 -0
  163. attocode_intel/migrations/env.py +71 -0
  164. attocode_intel/migrations/script.py.mako +27 -0
  165. attocode_intel/migrations/versions/001_initial_schema.py +219 -0
  166. attocode_intel/migrations/versions/002_branch_version_and_embeddings.py +61 -0
  167. attocode_intel/migrations/versions/003_embedding_uniqueness_and_cascade.py +51 -0
  168. attocode_intel/migrations/versions/004_audit_events.py +38 -0
  169. attocode_intel/migrations/versions/005_user_preferences.py +30 -0
  170. attocode_intel/migrations/versions/006_google_oauth.py +27 -0
  171. attocode_intel/migrations/versions/007_pgvector_embeddings.py +28 -0
  172. attocode_intel/migrations/versions/008_symbol_references.py +37 -0
  173. attocode_intel/migrations/versions/009_webhook_secret_encryption.py +25 -0
  174. attocode_intel/migrations/versions/010_add_commits_table.py +40 -0
  175. attocode_intel/migrations/versions/011_commit_changed_files.py +25 -0
  176. attocode_intel/migrations/versions/012_branch_merged_at.py +25 -0
  177. attocode_intel/migrations/versions/013_revoked_tokens.py +32 -0
  178. attocode_intel/migrations/versions/014_blame_hunks.py +40 -0
  179. attocode_intel/migrations/versions/015_commit_file_stats.py +40 -0
  180. attocode_intel/migrations/versions/016_embedding_provenance_columns.py +179 -0
  181. attocode_intel/migrations/versions/017_provenance_table.py +102 -0
  182. attocode_intel/migrations/versions/018_repo_snapshots.py +178 -0
  183. attocode_intel/migrations/versions/019_symref_caller.py +42 -0
  184. attocode_intel/migrations/versions/020_shared_knowledge.py +29 -0
  185. attocode_intel/onboarding.py +258 -0
  186. attocode_intel/output.py +178 -0
  187. attocode_intel/precision.py +133 -0
  188. attocode_intel/presence.py +160 -0
  189. attocode_intel/probe.py +110 -0
  190. attocode_intel/project_dir.py +97 -0
  191. attocode_intel/pubsub.py +113 -0
  192. attocode_intel/query_ranking.py +242 -0
  193. attocode_intel/readiness.py +972 -0
  194. attocode_intel/redis.py +51 -0
  195. attocode_intel/reference_pages.py +60 -0
  196. attocode_intel/remote.py +131 -0
  197. attocode_intel/repo_ranker.py +246 -0
  198. attocode_intel/request_context.py +82 -0
  199. attocode_intel/rules/__init__.py +28 -0
  200. attocode_intel/rules/ci.py +320 -0
  201. attocode_intel/rules/combinators.py +293 -0
  202. attocode_intel/rules/enricher.py +127 -0
  203. attocode_intel/rules/evolution.py +452 -0
  204. attocode_intel/rules/executor.py +531 -0
  205. attocode_intel/rules/filters/__init__.py +5 -0
  206. attocode_intel/rules/filters/pipeline.py +151 -0
  207. attocode_intel/rules/formatter.py +198 -0
  208. attocode_intel/rules/hygiene.py +242 -0
  209. attocode_intel/rules/importers/__init__.py +1 -0
  210. attocode_intel/rules/importers/semgrep.py +382 -0
  211. attocode_intel/rules/loader.py +292 -0
  212. attocode_intel/rules/marketplace.py +375 -0
  213. attocode_intel/rules/metavar.py +181 -0
  214. attocode_intel/rules/model.py +317 -0
  215. attocode_intel/rules/packs/__init__.py +1 -0
  216. attocode_intel/rules/packs/community/_license_templates/Apache-2.0.txt +176 -0
  217. attocode_intel/rules/packs/community/_license_templates/MIT.txt +21 -0
  218. attocode_intel/rules/packs/community/bandit-python/LICENSE +176 -0
  219. attocode_intel/rules/packs/community/bandit-python/NOTICE +13 -0
  220. attocode_intel/rules/packs/community/bandit-python/PORTING.md +23 -0
  221. attocode_intel/rules/packs/community/bandit-python/manifest.yaml +14 -0
  222. attocode_intel/rules/packs/community/bandit-python/rules/B105-hardcoded-password.yaml +23 -0
  223. attocode_intel/rules/packs/community/bandit-python/rules/B303-weak-md5.yaml +21 -0
  224. attocode_intel/rules/packs/community/bandit-python/rules/B304-weak-des.yaml +20 -0
  225. attocode_intel/rules/packs/community/bandit-python/rules/B307-use-of-eval.yaml +22 -0
  226. attocode_intel/rules/packs/community/bandit-python/rules/B324-weak-sha1.yaml +21 -0
  227. attocode_intel/rules/packs/community/bandit-python/rules/B501-no-cert-validation.yaml +23 -0
  228. attocode_intel/rules/packs/community/bandit-python/rules/B602-shell-true.yaml +22 -0
  229. attocode_intel/rules/packs/community/bandit-python/rules/B608-sqli.yaml +22 -0
  230. attocode_intel/rules/packs/community/eslint-typescript/LICENSE +21 -0
  231. attocode_intel/rules/packs/community/eslint-typescript/NOTICE +13 -0
  232. attocode_intel/rules/packs/community/eslint-typescript/PORTING.md +23 -0
  233. attocode_intel/rules/packs/community/eslint-typescript/manifest.yaml +14 -0
  234. attocode_intel/rules/packs/community/eslint-typescript/rules/eqeqeq.yaml +20 -0
  235. attocode_intel/rules/packs/community/eslint-typescript/rules/no-eval.yaml +22 -0
  236. attocode_intel/rules/packs/community/eslint-typescript/rules/no-implied-eval.yaml +20 -0
  237. attocode_intel/rules/packs/community/eslint-typescript/rules/no-new-func.yaml +21 -0
  238. attocode_intel/rules/packs/community/eslint-typescript/rules/no-throw-literal.yaml +19 -0
  239. attocode_intel/rules/packs/community/eslint-typescript/rules/no-var.yaml +20 -0
  240. attocode_intel/rules/packs/community/eslint-typescript/rules/no-with.yaml +18 -0
  241. attocode_intel/rules/packs/community/gosec-go/LICENSE +176 -0
  242. attocode_intel/rules/packs/community/gosec-go/NOTICE +13 -0
  243. attocode_intel/rules/packs/community/gosec-go/PORTING.md +23 -0
  244. attocode_intel/rules/packs/community/gosec-go/manifest.yaml +14 -0
  245. attocode_intel/rules/packs/community/gosec-go/rules/G101-hardcoded-credentials.yaml +22 -0
  246. attocode_intel/rules/packs/community/gosec-go/rules/G102-bind-all-interfaces.yaml +21 -0
  247. attocode_intel/rules/packs/community/gosec-go/rules/G103-unsafe-block.yaml +21 -0
  248. attocode_intel/rules/packs/community/gosec-go/rules/G201-sql-format.yaml +21 -0
  249. attocode_intel/rules/packs/community/gosec-go/rules/G304-file-inclusion.yaml +23 -0
  250. attocode_intel/rules/packs/community/gosec-go/rules/G401-weak-cipher.yaml +20 -0
  251. attocode_intel/rules/packs/community/gosec-go/rules/G402-tls-min-version.yaml +20 -0
  252. attocode_intel/rules/packs/community/gosec-go/rules/G501-md5-import.yaml +21 -0
  253. attocode_intel/rules/packs/examples/cpp/manifest.yaml +4 -0
  254. attocode_intel/rules/packs/examples/cpp/rules/security.yaml +90 -0
  255. attocode_intel/rules/packs/examples/cpp/rules/structural.yaml +42 -0
  256. attocode_intel/rules/packs/examples/csharp/manifest.yaml +4 -0
  257. attocode_intel/rules/packs/examples/csharp/rules/security.yaml +69 -0
  258. attocode_intel/rules/packs/examples/csharp/rules/structural.yaml +42 -0
  259. attocode_intel/rules/packs/examples/go/manifest.yaml +4 -0
  260. attocode_intel/rules/packs/examples/go/rules/performance.yaml +136 -0
  261. attocode_intel/rules/packs/examples/go/rules/security.yaml +48 -0
  262. attocode_intel/rules/packs/examples/go/rules/structural.yaml +58 -0
  263. attocode_intel/rules/packs/examples/go/taint/sanitizers.yaml +24 -0
  264. attocode_intel/rules/packs/examples/go/taint/sinks.yaml +51 -0
  265. attocode_intel/rules/packs/examples/go/taint/sources.yaml +26 -0
  266. attocode_intel/rules/packs/examples/java/manifest.yaml +4 -0
  267. attocode_intel/rules/packs/examples/java/rules/correctness.yaml +55 -0
  268. attocode_intel/rules/packs/examples/java/rules/structural.yaml +48 -0
  269. attocode_intel/rules/packs/examples/java/taint/sinks.yaml +37 -0
  270. attocode_intel/rules/packs/examples/java/taint/sources.yaml +21 -0
  271. attocode_intel/rules/packs/examples/kotlin/manifest.yaml +4 -0
  272. attocode_intel/rules/packs/examples/kotlin/rules/correctness.yaml +50 -0
  273. attocode_intel/rules/packs/examples/kotlin/rules/structural.yaml +38 -0
  274. attocode_intel/rules/packs/examples/php/manifest.yaml +4 -0
  275. attocode_intel/rules/packs/examples/php/rules/security.yaml +66 -0
  276. attocode_intel/rules/packs/examples/php/rules/structural.yaml +41 -0
  277. attocode_intel/rules/packs/examples/python/manifest.yaml +4 -0
  278. attocode_intel/rules/packs/examples/python/rules/performance.yaml +90 -0
  279. attocode_intel/rules/packs/examples/python/rules/structural.yaml +55 -0
  280. attocode_intel/rules/packs/examples/ruby/manifest.yaml +4 -0
  281. attocode_intel/rules/packs/examples/ruby/rules/security.yaml +73 -0
  282. attocode_intel/rules/packs/examples/ruby/rules/structural.yaml +41 -0
  283. attocode_intel/rules/packs/examples/rust/manifest.yaml +4 -0
  284. attocode_intel/rules/packs/examples/rust/rules/correctness.yaml +51 -0
  285. attocode_intel/rules/packs/examples/rust/rules/structural.yaml +49 -0
  286. attocode_intel/rules/packs/examples/typescript/manifest.yaml +4 -0
  287. attocode_intel/rules/packs/examples/typescript/rules/performance.yaml +70 -0
  288. attocode_intel/rules/packs/examples/typescript/rules/structural.yaml +48 -0
  289. attocode_intel/rules/packs/pack_loader.py +244 -0
  290. attocode_intel/rules/plugins/__init__.py +1 -0
  291. attocode_intel/rules/plugins/plugin_loader.py +132 -0
  292. attocode_intel/rules/profiling.py +332 -0
  293. attocode_intel/rules/registry.py +213 -0
  294. attocode_intel/rules/sarif.py +187 -0
  295. attocode_intel/rules/synthesis.py +420 -0
  296. attocode_intel/rules/testing.py +326 -0
  297. attocode_intel/server.py +734 -0
  298. attocode_intel/service.py +3416 -0
  299. attocode_intel/sharing.py +57 -0
  300. attocode_intel/storage/__init__.py +6 -0
  301. attocode_intel/storage/branch_overlay.py +352 -0
  302. attocode_intel/storage/content_store.py +220 -0
  303. attocode_intel/storage/dependency_store.py +143 -0
  304. attocode_intel/storage/diff_engine.py +187 -0
  305. attocode_intel/storage/embedding_store.py +594 -0
  306. attocode_intel/storage/provenance_store.py +137 -0
  307. attocode_intel/storage/security_scanner_db.py +164 -0
  308. attocode_intel/storage/symbol_store.py +160 -0
  309. attocode_intel/structural_evidence.py +144 -0
  310. attocode_intel/symbol_inspection.py +141 -0
  311. attocode_intel/symbol_links.py +167 -0
  312. attocode_intel/telemetry.py +42 -0
  313. attocode_intel/test_ranking.py +73 -0
  314. attocode_intel/testing/__init__.py +43 -0
  315. attocode_intel/testing/fixtures.py +122 -0
  316. attocode_intel/testing/helpers.py +75 -0
  317. attocode_intel/testing/mocks.py +99 -0
  318. attocode_intel/tools/__init__.py +2 -0
  319. attocode_intel/tools/adr_tools.py +628 -0
  320. attocode_intel/tools/analysis_tools.py +382 -0
  321. attocode_intel/tools/composite_tools.py +695 -0
  322. attocode_intel/tools/cross_mode_tools.py +173 -0
  323. attocode_intel/tools/dead_code_tools.py +582 -0
  324. attocode_intel/tools/distill_tools.py +353 -0
  325. attocode_intel/tools/frecency_tools.py +220 -0
  326. attocode_intel/tools/fuzzy_tools.py +255 -0
  327. attocode_intel/tools/history_tools.py +486 -0
  328. attocode_intel/tools/learning_tools.py +222 -0
  329. attocode_intel/tools/lsp_tools.py +218 -0
  330. attocode_intel/tools/maintenance_tools.py +1662 -0
  331. attocode_intel/tools/navigation_tools.py +220 -0
  332. attocode_intel/tools/overlay_tools.py +540 -0
  333. attocode_intel/tools/pin_store.py +432 -0
  334. attocode_intel/tools/pin_tools.py +266 -0
  335. attocode_intel/tools/query_constraints_tools.py +262 -0
  336. attocode_intel/tools/query_history_tools.py +158 -0
  337. attocode_intel/tools/readiness_tools.py +44 -0
  338. attocode_intel/tools/rule_tools.py +992 -0
  339. attocode_intel/tools/search_tools.py +770 -0
  340. attocode_intel/tools/snapshot_tools.py +624 -0
  341. attocode_intel/workers/__init__.py +1 -0
  342. attocode_intel/workers/job_utils.py +111 -0
  343. attocode_intel/workers/jobs.py +573 -0
  344. attocode_intel/workers/run.py +30 -0
  345. attocode_intel/workers/settings.py +61 -0
@@ -0,0 +1,432 @@
1
+ # Code Intelligence MCP Server — Agent Guidelines
2
+
3
+ > A broad tool suite for deep codebase understanding. This guide helps AI agents use it
4
+ > efficiently, minimizing token usage while maximizing insight.
5
+ >
6
+ > These tools are available via MCP (stdio/SSE) **and** as a REST API over HTTP.
7
+ > The HTTP API supports multi-project management, bearer token auth, and interactive
8
+ > docs at `/docs`. Start the HTTP server with:
9
+ > `attocode code-intel serve --transport http --project /path/to/repo`
10
+
11
+ ---
12
+
13
+ ## Tool Inventory
14
+
15
+ ### Orientation (300–6000 tokens each)
16
+
17
+ | Tool | Purpose | When to Use |
18
+ |------|---------|-------------|
19
+ | `project_summary` | High-level overview (identity, stats, entry points, architecture) | First call on unknown codebase |
20
+ | `repo_map` | Token-budgeted file tree with symbols | Small/medium codebases (<2000 files) |
21
+ | `explore_codebase` | Drill down one directory at a time | Large codebases, targeted exploration |
22
+ | `hotspots` | Files ranked by complexity/coupling/risk | Identify risky areas before changes |
23
+ | `conventions` | Coding style and patterns detected from code | Before writing new code |
24
+ | `bootstrap` | All-in-one orientation (summary + map + conventions + search). Optional `indexing_depth` param: "auto" (default), "eager", "lazy", "minimal" | **Best first call** — replaces 2-4 sequential calls |
25
+ | `hydration_status` | Check indexing progress (tier, phase, coverage) | Large repos — decide whether to wait or proceed |
26
+
27
+ ### Symbol Lookup (50–3000 tokens each)
28
+
29
+ | Tool | Purpose | When to Use |
30
+ |------|---------|-------------|
31
+ | `search_symbols` | Find function/class definitions by name | Know the name, need the location |
32
+ | `symbols` | List all symbols in a single file | Understand a file's API surface |
33
+ | `cross_references` | Definition sites + all usage sites for a symbol | Understand how something is used |
34
+ | `file_analysis` | Detailed file analysis (chunks, imports, exports) | Need full file understanding |
35
+
36
+ ### Dependencies (100–1500 tokens each)
37
+
38
+ | Tool | Purpose | When to Use |
39
+ |------|---------|-------------|
40
+ | `dependencies` | Direct imports and importers for a file | Quick dependency check |
41
+ | `dependency_graph` | Multi-hop dependency tree (BFS both directions) | Understand module relationships |
42
+ | `graph_query` | BFS traversal with typed edges and direction control | Targeted import/importer walks |
43
+ | `find_related` | Find structurally similar files (Jaccard + 2-hop) | Discover related modules |
44
+ | `community_detection` | Connected-component clustering of the import graph | Understand module boundaries |
45
+ | `impact_analysis` | Transitive blast radius of file changes | **Before modifying files** |
46
+ | `relevant_context` | Subgraph capsule — file + neighbors with symbols | Understand a file in context (replaces N+1 calls) |
47
+
48
+ ### LSP (20–1500 tokens each)
49
+
50
+ | Tool | Purpose | When to Use |
51
+ |------|---------|-------------|
52
+ | `lsp_definition` | Type-resolved go-to-definition | Jump to where something is defined |
53
+ | `lsp_references` | All references with type awareness | Find all usages precisely |
54
+ | `lsp_hover` | Type signature + documentation | Check types without reading code |
55
+ | `lsp_diagnostics` | Errors and warnings from language server | Verify code correctness |
56
+
57
+ ### Search & Security (300–2000 tokens each)
58
+
59
+ | Tool | Purpose | When to Use |
60
+ |------|---------|-------------|
61
+ | `semantic_search` | Natural language code search. Optional `mode`: "auto" (default), "keyword" (fast), "vector" (wait for embeddings) | Find code by description, not name |
62
+ | `security_scan` | Secret detection (13 patterns), anti-patterns (21 rules incl. supply-chain obfuscation: invisible Unicode, eval-on-decoded-data, install-hook scrutiny), dependency issues | Security review, supply-chain hardening |
63
+
64
+ ### Rule-Based Analysis (200–5000 tokens each)
65
+
66
+ | Tool | Purpose | When to Use |
67
+ |------|---------|-------------|
68
+ | `analyze` | Run rules from language packs against files. Returns rich findings with code context, antipattern explanations, few-shot examples, and fix suggestions. Filter by language, category, severity, or pack. | **Deep analysis** — performance antipatterns, correctness bugs, security issues, style violations |
69
+ | `list_rules` | Browse all registered rules by language, category, severity, or pack. Use `verbose=True` for descriptions. | Discover available checks before running analysis |
70
+ | `list_packs` | Show installed packs and available example packs | See what's active vs what can be installed |
71
+ | `install_pack` | Install an example language pack (go, python, typescript, rust, java) into `.attocode/packs/` | Activate language-specific analysis for your project |
72
+ | `register_rule` | Register a custom YAML rule at runtime. For permanent rules, add files to `.attocode/rules/` | Add project-specific or domain-specific checks on the fly |
73
+
74
+ **Language packs are NOT auto-loaded** — use `install_pack("go")` to activate packs relevant to your project. Once installed, rules are customizable in `.attocode/packs/<name>/rules/*.yaml`. Each finding includes surrounding code context (10 lines), an explanation of why it matters, and fix examples.
75
+
76
+ **Custom rules** in `.attocode/rules/*.yaml` or `.attocode/plugins/` are auto-loaded alongside installed packs.
77
+
78
+ ### Memory & Recall (50–500 tokens each)
79
+
80
+ | Tool | Purpose | When to Use |
81
+ |------|---------|-------------|
82
+ | `recall` | Retrieve relevant project learnings | At task start or in unfamiliar code |
83
+ | `record_learning` | Record patterns/conventions/gotchas | When you discover something important |
84
+ | `learning_feedback` | Mark learning as helpful/unhelpful | After using a recalled learning |
85
+ | `list_learnings` | Browse all stored learnings | Audit or review project knowledge |
86
+
87
+ ---
88
+
89
+ ## The Cardinal Rule: Progressive Disclosure
90
+
91
+ **Never load what you don't need.** Start broad, drill down only where relevant.
92
+
93
+ ```
94
+ LEVEL 0: Orient → bootstrap() or project_summary() + repo_map()
95
+ LEVEL 1: Locate → explore_codebase() or search_symbols() or semantic_search()
96
+ LEVEL 2: Understand → relevant_context() or symbols() + dependencies()
97
+ LEVEL 3: Deep Dive → lsp_hover(), lsp_references(), impact_analysis()
98
+ LEVEL 4: Act → Make changes, then lsp_diagnostics() + impact_analysis() to verify
99
+ ```
100
+
101
+ **Flow:**
102
+ 1. Already familiar with codebase? Skip to Level 1 or 2.
103
+ 2. Know which file to target? Go directly to Level 2.
104
+ 3. Know a symbol name? Use `search_symbols` → Level 2.
105
+ 4. No idea where to look? `bootstrap(task_hint="your task")` → Level 1.
106
+
107
+ ---
108
+
109
+ ## Codebase Size Strategies
110
+
111
+ ### Small (<100 files) — 2 calls for complete understanding
112
+
113
+ ```
114
+ project_summary(max_tokens=2000) + repo_map(max_tokens=3000, include_symbols=True)
115
+ ```
116
+
117
+ Or just: `bootstrap(max_tokens=5000)` (1 call)
118
+
119
+ ### Medium (100–2000 files) — 3 orientation + targeted drill-down
120
+
121
+ ```
122
+ bootstrap(task_hint="your task", max_tokens=8000)
123
+ → explore_codebase("relevant_dir")
124
+ → relevant_context(["target_file.py"])
125
+ ```
126
+
127
+ ### Large (2000+ files) — Hierarchical, NO full repo_map
128
+
129
+ ```
130
+ bootstrap(task_hint="your task", max_tokens=8000)
131
+ → explore_codebase("src")
132
+ → explore_codebase("src/core")
133
+ → search_symbols("TargetClass") or semantic_search("what you need")
134
+ → relevant_context(["found_file.py"])
135
+ ```
136
+
137
+ **Never call `repo_map` on large codebases** — it wastes tokens. Use `explore_codebase` to drill down.
138
+
139
+ > **Progressive hydration**: For repos with >1K source files, code-intel uses skeleton
140
+ > initialization (parses only the top ~300-500 most important files in <2s). Remaining
141
+ > files are parsed in the background. Use `hydration_status` to check progress.
142
+ > Tools like `symbols()` and `cross_references()` automatically trigger on-demand
143
+ > parsing for files not yet in the index — you don't need to wait for full hydration.
144
+
145
+ ---
146
+
147
+ ## Task-Specific Workflows
148
+
149
+ ### Bug Fixing
150
+
151
+ ```
152
+ 1. search_symbols(bug_related_name) → Find the function/class
153
+ 2. lsp_diagnostics(file) → Check for existing errors
154
+ 3. cross_references(symbol_name) → Find all usage sites
155
+ 4. lsp_hover(file, line) → Understand types
156
+ 5. impact_analysis([file]) → Check blast radius before fix
157
+ 6. Fix the bug
158
+ ```
159
+
160
+ ### Feature Development
161
+
162
+ ```
163
+ 1. bootstrap(task_hint="feature desc") → Orient + find similar code
164
+ 2. conventions() → Learn project style (if not in bootstrap)
165
+ 3. dependency_graph(similar_file, 2) → Understand module boundaries
166
+ 4. symbols(target_file) → Understand API surface
167
+ 5. Implement the feature
168
+ ```
169
+
170
+ ### Refactoring
171
+
172
+ ```
173
+ 1. hotspots(10) → Find highest-risk files
174
+ 2. cross_references(symbol) → Find all usages of what you're changing
175
+ 3. impact_analysis([files_to_change]) → Full blast radius
176
+ 4. dependency_graph(file, 2) → Understand coupling
177
+ 5. lsp_references(file, line) → Precise reference locations
178
+ 6. Refactor
179
+ ```
180
+
181
+ ### Code Review
182
+
183
+ ```
184
+ 1. impact_analysis(changed_files) → Blast radius of changes
185
+ 2. hotspots(10) → Are changes in risky areas?
186
+ 3. conventions() → Do changes follow project style?
187
+ 4. analyze(files=changed_files) → Rule-based analysis (perf, correctness, security)
188
+ 5. lsp_diagnostics(file) × N → Errors in each changed file (parallel)
189
+ 6. security_scan(path="changed_dir") → Secret/supply-chain check
190
+ ```
191
+
192
+ ### Onboarding / First Contact
193
+
194
+ ```
195
+ 1. bootstrap(max_tokens=8000) → Complete orientation (1 call)
196
+ OR
197
+ project_summary() ∥ repo_map() → Orientation (2 parallel calls)
198
+ 2. hotspots() ∥ conventions() → Risk areas + style (2 parallel calls)
199
+ 3. explore_codebase("src") → Drill into source
200
+ ```
201
+
202
+ Total: ~6 calls, ~12-15K tokens for complete codebase understanding.
203
+
204
+ ---
205
+
206
+ ## Parallel Call Groupings
207
+
208
+ These tools are safe to call simultaneously:
209
+
210
+ ```
211
+ # Orientation (no dependencies between them)
212
+ project_summary() ∥ repo_map()
213
+
214
+ # File understanding (different data sources)
215
+ symbols(file) ∥ dependencies(file) ∥ lsp_diagnostics(file)
216
+
217
+ # Cross-cutting analysis (independent queries)
218
+ impact_analysis([files]) ∥ cross_references(name) ∥ hotspots()
219
+
220
+ # Multi-file diagnostics (no shared state)
221
+ lsp_diagnostics(file_a) ∥ lsp_diagnostics(file_b) ∥ lsp_diagnostics(file_c)
222
+
223
+ # Orientation + task search
224
+ project_summary() ∥ semantic_search(task_description)
225
+ ```
226
+
227
+ **Do NOT parallelize:** `bootstrap()` with `project_summary()` or `repo_map()` — bootstrap already includes them.
228
+
229
+ ---
230
+
231
+ ## LSP Fallback Table
232
+
233
+ When the language server is unavailable or returns "LSP not available":
234
+
235
+ | LSP Tool | Fallback |
236
+ |----------|----------|
237
+ | `lsp_definition` | `search_symbols(name)` — finds definitions by name matching |
238
+ | `lsp_references` | `cross_references(symbol_name)` — regex-based reference finding |
239
+ | `lsp_hover` | `file_analysis(path)` — shows full file structure with types |
240
+ | `lsp_diagnostics` | Run linter via bash (e.g., `ruff check file.py`, `eslint file.ts`) |
241
+
242
+ ---
243
+
244
+ ## Token Budget Rules
245
+
246
+ | Tool | Optimal Budget | Notes |
247
+ |------|---------------|-------|
248
+ | `repo_map` | 6000 tokens | Above 10000 wastes context with low-value files |
249
+ | `explore_codebase` | ~600-900 tokens | `max_items=30` is the sweet spot |
250
+ | `file_analysis` | ~1500 tokens (500-line file) | Most expensive per-file tool — use `symbols` if you only need API surface |
251
+ | `dependency_graph` | depth=2 | depth=3 explodes on hub files (exponential growth) |
252
+ | `bootstrap` | 8000 tokens | Includes summary + map + conventions + search |
253
+ | `project_summary` | 4000 tokens | Trim to 2000 for small codebases |
254
+ | `hotspots` | Stable | Call at most once per session |
255
+ | `conventions` | Stable | Call at most once per session (use `path` param for directory-specific) |
256
+
257
+ ---
258
+
259
+ ## Anti-Patterns
260
+
261
+ 1. **Reading 10+ files when 2 tool calls suffice.** `dependency_graph + symbols` gives the same structural info as reading all those files.
262
+
263
+ 2. **Skipping orientation.** Always call `bootstrap()` or `project_summary()` first on unknown codebases. Context saves more tokens than it costs.
264
+
265
+ 3. **Oversized repo maps.** `repo_map(max_tokens=20000)` wastes context. Stay at 6000 for medium, skip entirely for large codebases.
266
+
267
+ 4. **Using regex `cross_references` when LSP is available.** `lsp_references` is more precise. Only use `cross_references` as a fallback.
268
+
269
+ 5. **Repeated `hotspots`/`conventions` calls.** These are stable within a session — results won't change. Call each at most once.
270
+
271
+ 6. **Deep dependency graphs on hub files.** `dependency_graph("types.py", depth=3)` will return hundreds of files. Use depth=2 max, or depth=1 for hub files.
272
+
273
+ 7. **`file_analysis` when you only need `symbols`.** `file_analysis` returns full chunks with code; `symbols` returns just the API surface at 1/3 the tokens.
274
+
275
+ 8. **`semantic_search` for known exact names.** Use `search_symbols("MyClass")` — it's faster and more precise. Save `semantic_search` for "find code that handles authentication"-style queries.
276
+
277
+ 9. **Ignoring importance scores in `explore_codebase` output.** High-importance files (>0.7) are entry points and hubs. Start there.
278
+
279
+ ---
280
+
281
+ ## Graph Query Tools (New)
282
+
283
+ ### `graph_query` — Directed BFS with edge types
284
+
285
+ Walk imports or importers from a file with depth control.
286
+
287
+ ```json
288
+ {"file": "src/core/loop.py", "edge_type": "IMPORTS", "direction": "outbound", "depth": 2}
289
+ ```
290
+
291
+ Returns files grouped by hop distance:
292
+ ```
293
+ Hop 1:
294
+ > src/core/tool_executor.py
295
+ > src/core/response_handler.py
296
+ Hop 2:
297
+ >> src/providers/base.py
298
+ >> src/tools/registry.py
299
+ ```
300
+
301
+ Use `direction: "inbound"` or `edge_type: "IMPORTED_BY"` to reverse:
302
+ ```json
303
+ {"file": "src/types/events.py", "direction": "inbound", "depth": 1}
304
+ ```
305
+
306
+ ### `find_related` — Structural similarity
307
+
308
+ Find files related by import patterns (not just direct imports).
309
+
310
+ ```json
311
+ {"file": "src/agent/agent.py", "top_k": 5}
312
+ ```
313
+
314
+ Returns ranked list with relationship type:
315
+ ```
316
+ Files related to src/agent/agent.py:
317
+ [ 9] src/agent/builder.py (direct)
318
+ [ 6] src/core/loop.py (direct)
319
+ [ 3] src/agent/context.py (direct)
320
+ [ 2] src/providers/base.py (transitive)
321
+ ```
322
+
323
+ ### `community_detection` — Module clustering
324
+
325
+ Find natural groupings in the codebase.
326
+
327
+ ```json
328
+ {"min_community_size": 5, "max_communities": 10}
329
+ ```
330
+
331
+ Returns communities with hub files:
332
+ ```
333
+ Community 1 (45 files):
334
+ Hub: src/types/events.py (degree 32)
335
+ - src/agent/agent.py (degree 15)
336
+ - src/core/loop.py (degree 12)
337
+ ...
338
+
339
+ Community 2 (18 files):
340
+ Hub: src/tui/app.py (degree 14)
341
+ ...
342
+ ```
343
+
344
+ ### Resources
345
+
346
+ Two MCP resources for direct content access:
347
+
348
+ - `attocode://project/{path}` — File content with line numbers (path-traversal protected)
349
+ - `attocode://symbols/{name}` — Symbol definitions with source snippets
350
+
351
+ 10. **Modifying files without `impact_analysis` first.** Always check the blast radius before making changes to shared/hub files.
352
+
353
+ 11. **Skipping `recall()` at task start.** Recalled learnings prevent repeated mistakes and surface project conventions you'd otherwise miss.
354
+
355
+ ---
356
+
357
+ ## Keeping the Index Fresh
358
+
359
+ The code-intel server maintains an AST index and semantic search embeddings. These update automatically via a file watcher, but you can also trigger updates explicitly:
360
+
361
+ ### `notify_file_changed` Tool
362
+
363
+ Call this after batch file edits to immediately refresh the index:
364
+
365
+ ```
366
+ notify_file_changed(files=["src/foo.py", "src/bar.py"])
367
+ ```
368
+
369
+ This updates the AST index **and** invalidates stale semantic search embeddings for those files. Recommended after:
370
+ - Editing multiple files in a batch
371
+ - Creating or deleting files
372
+ - Operations where the ~200ms watcher debounce matters
373
+
374
+ ### Automatic Updates
375
+
376
+ The file watcher handles most cases automatically. It:
377
+ - Monitors code files (`.py`, `.js`, `.ts`, `.go`, `.rs`, etc.)
378
+ - Updates AST index + invalidates embeddings on change
379
+ - Has ~200ms debounce (handled by watchfiles)
380
+
381
+ If `watchfiles` is not installed, use the `notify_file_changed` tool as the primary update mechanism.
382
+
383
+ ---
384
+
385
+ ## Quick Reference Card
386
+
387
+ ```
388
+ TASK PRIMARY TOOL FOLLOW-UP
389
+ ─────────────────────────────────────────────────────────────────
390
+ First time in codebase bootstrap(task_hint) explore_codebase(dir)
391
+ Find a function/class search_symbols(name) symbols, file_analysis
392
+ Navigate directories explore_codebase(path) explore_codebase(deeper)
393
+ Find similar code semantic_search(query) dependency_graph
394
+ Understand a file symbols + dependencies file_analysis if needed
395
+ Understand a file in context relevant_context([file]) (includes neighbors)
396
+ Check types lsp_hover lsp_definition
397
+ Find all usages lsp_references cross_references (fallback)
398
+ Before modifying impact_analysis([files]) dependency_graph
399
+ Identify risky code hotspots conventions
400
+ Review changes impact_analysis lsp_diagnostics, security_scan
401
+ Learn project style conventions(path=dir) conventions() for global
402
+ Recall project learnings recall(query, scope) learning_feedback(id)
403
+ Record a discovery record_learning(...) (persists across sessions)
404
+ ```
405
+
406
+ ---
407
+
408
+ ## Memory & Recall
409
+
410
+ The server maintains a project-local learning database (`.attocode/cache/memory.db`).
411
+ Use these tools to build institutional knowledge that persists across sessions.
412
+
413
+ **Recommended workflow:**
414
+ 1. At task start: `recall(query="what I'm about to do", scope="relevant/dir/")`
415
+ 2. During work: When you discover gotchas or patterns, `record_learning(...)`
416
+ 3. After using recalled info: `learning_feedback(id, helpful=true/false)`
417
+
418
+ **Learning types:**
419
+
420
+ | Type | When to use |
421
+ |------|-------------|
422
+ | `pattern` | Recurring code pattern that works well |
423
+ | `convention` | Project naming/style/architecture convention |
424
+ | `gotcha` | Non-obvious behavior or common mistake |
425
+ | `workaround` | Known issue with a known workaround |
426
+ | `antipattern` | Pattern that looks right but causes problems |
427
+
428
+ **Scope matching:** Learnings are scoped to directories. `recall(scope="src/core/")`
429
+ returns learnings for `src/core/`, then `src/`, then global — most specific first.
430
+
431
+ **Confidence:** Learnings start at 0.7 confidence. Helpful feedback boosts (+0.05),
432
+ unhelpful reduces (-0.1). Learnings with < 0.15 confidence are auto-archived.
@@ -0,0 +1,52 @@
1
+ """Attocode Code Intelligence MCP Server.
2
+
3
+ Exports are lazy-loaded to avoid pulling in heavy dependencies (tree-sitter,
4
+ numpy, AST parsing) at import time. Basic sessions that only use grep/glob
5
+ tools pay no startup cost for code-intel.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import importlib
11
+ from typing import Any
12
+
13
+ __all__ = [
14
+ "BugReport",
15
+ "Finding",
16
+ "ReadinessEngine",
17
+ "ReadinessReport",
18
+ "RepoMapResult",
19
+ "format_repo_map",
20
+ "pagerank",
21
+ "rank_repo_files",
22
+ "scan_diff",
23
+ "scan_text",
24
+ ]
25
+
26
+ # Lazy-load map: attribute name -> (module_path, attribute_name)
27
+ _LAZY_IMPORTS: dict[str, tuple[str, str]] = {
28
+ "BugReport": ("attocode_intel.bug_finder", "BugReport"),
29
+ "Finding": ("attocode_intel.bug_finder", "Finding"),
30
+ "scan_diff": ("attocode_intel.bug_finder", "scan_diff"),
31
+ "scan_text": ("attocode_intel.bug_finder", "scan_text"),
32
+ "ReadinessEngine": ("attocode_intel.readiness", "ReadinessEngine"),
33
+ "ReadinessReport": ("attocode_intel.readiness", "ReadinessReport"),
34
+ "RepoMapResult": ("attocode_intel.repo_ranker", "RepoMapResult"),
35
+ "format_repo_map": ("attocode_intel.repo_ranker", "format_repo_map"),
36
+ "pagerank": ("attocode_intel.repo_ranker", "pagerank"),
37
+ "rank_repo_files": ("attocode_intel.repo_ranker", "rank_repo_files"),
38
+ }
39
+
40
+
41
+ def __getattr__(name: str) -> Any:
42
+ if name in _LAZY_IMPORTS:
43
+ module_path, attr = _LAZY_IMPORTS[name]
44
+ mod = importlib.import_module(module_path)
45
+ value = getattr(mod, attr)
46
+ # Cache on the module so subsequent accesses are fast
47
+ globals()[name] = value
48
+ return value
49
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
50
+
51
+ # The other copy is packages/code-intel/pyproject.toml. A test checks that both match.
52
+ __version__ = "0.1.0"
@@ -0,0 +1 @@
1
+ """Internal code intelligence support; not a public API."""
@@ -0,0 +1,126 @@
1
+ """Attocode error hierarchy."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from enum import StrEnum
6
+ from typing import Any
7
+
8
+
9
+ class ErrorCategory(StrEnum):
10
+ """Category of error for classification and handling."""
11
+
12
+ LLM = "llm"
13
+ PROVIDER = "provider"
14
+ TOOL = "tool"
15
+ BUDGET = "budget"
16
+ CANCELLATION = "cancellation"
17
+ PERMISSION = "permission"
18
+ CONFIGURATION = "configuration"
19
+ INTERNAL = "internal"
20
+
21
+
22
+ class AgentError(Exception):
23
+ """Base error for all agent exceptions."""
24
+
25
+ def __init__(
26
+ self,
27
+ message: str,
28
+ *,
29
+ category: ErrorCategory = ErrorCategory.INTERNAL,
30
+ retryable: bool = False,
31
+ details: dict[str, Any] | None = None,
32
+ ) -> None:
33
+ super().__init__(message)
34
+ self.category = category
35
+ self.retryable = retryable
36
+ self.details: dict[str, Any] = details or {}
37
+
38
+ def __repr__(self) -> str:
39
+ return f"{type(self).__name__}({str(self)!r}, category={self.category!r})"
40
+
41
+
42
+ class LLMError(AgentError):
43
+ """Error from LLM interaction (empty response, malformed output, etc.)."""
44
+
45
+ def __init__(self, message: str, *, retryable: bool = True, **kwargs: Any) -> None:
46
+ super().__init__(message, category=ErrorCategory.LLM, retryable=retryable, **kwargs)
47
+
48
+
49
+ class ProviderError(AgentError):
50
+ """Error from an LLM provider (rate limit, network, auth)."""
51
+
52
+ def __init__(
53
+ self,
54
+ message: str,
55
+ *,
56
+ provider: str | None = None,
57
+ status_code: int | None = None,
58
+ retryable: bool = True,
59
+ **kwargs: Any,
60
+ ) -> None:
61
+ super().__init__(message, category=ErrorCategory.PROVIDER, retryable=retryable, **kwargs)
62
+ self.provider = provider
63
+ self.status_code = status_code
64
+
65
+
66
+ class ToolError(AgentError):
67
+ """Error during tool execution."""
68
+
69
+ def __init__(
70
+ self,
71
+ message: str,
72
+ *,
73
+ tool_name: str | None = None,
74
+ retryable: bool = False,
75
+ **kwargs: Any,
76
+ ) -> None:
77
+ super().__init__(message, category=ErrorCategory.TOOL, retryable=retryable, **kwargs)
78
+ self.tool_name = tool_name
79
+
80
+
81
+ class ToolNotFoundError(ToolError):
82
+ """Requested tool does not exist."""
83
+
84
+ def __init__(self, tool_name: str) -> None:
85
+ super().__init__(f"Tool not found: {tool_name}", tool_name=tool_name)
86
+
87
+
88
+ class ToolTimeoutError(ToolError):
89
+ """Tool execution timed out."""
90
+
91
+ def __init__(self, tool_name: str, timeout: float) -> None:
92
+ super().__init__(
93
+ f"Tool '{tool_name}' timed out after {timeout}s",
94
+ tool_name=tool_name,
95
+ retryable=True,
96
+ )
97
+ self.timeout = timeout
98
+
99
+
100
+ class BudgetExhaustedError(AgentError):
101
+ """Token/cost/time budget has been exhausted."""
102
+
103
+ def __init__(self, message: str = "Budget exhausted") -> None:
104
+ super().__init__(message, category=ErrorCategory.BUDGET, retryable=False)
105
+
106
+
107
+ class CancellationError(AgentError):
108
+ """Operation was cancelled by user or system."""
109
+
110
+ def __init__(self, message: str = "Operation cancelled") -> None:
111
+ super().__init__(message, category=ErrorCategory.CANCELLATION, retryable=False)
112
+
113
+
114
+ class PermissionDeniedError(AgentError):
115
+ """Tool execution was denied by permission system."""
116
+
117
+ def __init__(self, message: str, *, tool_name: str | None = None) -> None:
118
+ super().__init__(message, category=ErrorCategory.PERMISSION, retryable=False)
119
+ self.tool_name = tool_name
120
+
121
+
122
+ class ConfigurationError(AgentError):
123
+ """Invalid or missing configuration."""
124
+
125
+ def __init__(self, message: str) -> None:
126
+ super().__init__(message, category=ErrorCategory.CONFIGURATION, retryable=False)
@@ -0,0 +1 @@
1
+ """Internal code intelligence support; not a public API."""
@@ -0,0 +1 @@
1
+ """Internal code intelligence support; not a public API."""