deepdoc 0.6.1__tar.gz → 0.6.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {deepdoc-0.6.1 → deepdoc-0.6.2}/PKG-INFO +1 -1
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/__init__.py +1 -1
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/generator/generation.py +6 -4
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/openapi.py +43 -32
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc.egg-info/PKG-INFO +1 -1
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc.egg-info/SOURCES.txt +1 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/pyproject.toml +1 -1
- deepdoc-0.6.2/tests/test_openapi_null_values.py +62 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/LICENSE +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/README.md +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/__main__.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/benchmark_v2.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/call_graph/__init__.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/call_graph/extractor.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/call_graph/go_extractor.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/call_graph/graph_builder.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/call_graph/java_extractor.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/call_graph/js_ts_extractor.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/call_graph/php_extractor.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/call_graph/python_extractor.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/changelog_writer.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/chatbot/__init__.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/chatbot/answer_mixin.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/chatbot/chunker.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/chatbot/constants.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/chatbot/deep_research.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/chatbot/docs_summary.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/chatbot/embedding_capabilities.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/chatbot/embeddings.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/chatbot/indexer.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/chatbot/linking.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/chatbot/live_fallback_mixin.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/chatbot/persistence.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/chatbot/providers.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/chatbot/retrieval_mixin.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/chatbot/routes.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/chatbot/scaffold.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/chatbot/service.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/chatbot/settings.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/chatbot/source_archive.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/chatbot/symbol_index.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/chatbot/types.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/cli.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/config.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/content_store.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/docs_system.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/generator/__init__.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/generator/claims.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/generator/consistency.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/generator/evidence.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/generator/post_processors.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/generator/validation.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/language_support.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/llm/__init__.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/llm/client.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/llm/json_utils.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/llm/litellm_compat.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/llm/rate_limit.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/llm/retry.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/llm/token_budget.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/manifest.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/output_safety.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/parser/__init__.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/parser/api_detector.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/parser/base.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/parser/go_parser.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/parser/java_parser.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/parser/js_ts_parser.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/parser/php_parser.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/parser/python_parser.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/parser/registry.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/parser/routes/__init__.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/parser/routes/base.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/parser/routes/common.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/parser/routes/detector.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/parser/routes/django.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/parser/routes/express.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/parser/routes/falcon.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/parser/routes/fastapi.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/parser/routes/fastify.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/parser/routes/go.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/parser/routes/js_shared.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/parser/routes/laravel.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/parser/routes/nestjs.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/parser/routes/python_shared.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/parser/routes/registry.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/parser/routes/repo_resolver.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/parser/rust_parser.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/parser/vue_parser.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/persistence_v2.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/persistent_index.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/pipeline_v2.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/plan_contract.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/planner/__init__.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/planner/bucket_injection.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/planner/bucket_refinement.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/planner/common.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/planner/endpoint_refs.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/planner/engine.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/planner/flow_candidates.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/planner/heuristics.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/planner/merge.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/planner/nav_shaping.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/planner/partitioning.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/planner/specializations.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/planner/topology.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/planner/unit_boundaries.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/planner/utils.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/prompts/__init__.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/prompts/bucket_types.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/prompts/page_types.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/prompts/selectors.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/prompts/system.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/prompts/update.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/py.typed +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/repo_model.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/scale_utils.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/scanner/__init__.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/scanner/artifacts.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/scanner/clustering.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/scanner/common.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/scanner/database.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/scanner/endpoints.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/scanner/integrations.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/scanner/runtime.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/scanner/utils.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/site/__init__.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/site/builder/__init__.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/site/builder/common.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/site/builder/mdx_utils.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/site/builder/next_builder.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/site/builder/next_template/.gitignore +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/site/builder/next_template/app/(main)/[[...slug]]/page.tsx +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/site/builder/next_template/app/(main)/layout.tsx +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/site/builder/next_template/app/api/search/route.ts +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/site/builder/next_template/app/ask/layout.tsx +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/site/builder/next_template/app/ask/page.tsx +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/site/builder/next_template/app/components/mermaid-runner.tsx +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/site/builder/next_template/app/globals.css +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/site/builder/next_template/app/layout.tsx +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/site/builder/next_template/components/chatbot.tsx +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/site/builder/next_template/deepdoc.config.json +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/site/builder/next_template/lib/config.ts +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/site/builder/next_template/lib/docs.ts +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/site/builder/next_template/lib/nav.ts +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/site/builder/next_template/next.config.mjs +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/site/builder/next_template/package.json +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/site/builder/next_template/postcss.config.mjs +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/site/builder/next_template/tsconfig.json +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/site/builder/presets.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/site/builder/vendor/highlight.min.js +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/site/builder/vendor/hljs-theme.css +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/site/builder/vendor/markdown-it.min.js +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/smart_update_v2.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/source_metadata.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/telemetry.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/updater_v2.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/v2_models.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc.egg-info/dependency_links.txt +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc.egg-info/entry_points.txt +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc.egg-info/requires.txt +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc.egg-info/top_level.txt +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/setup.cfg +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_benchmark_scorecard.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_call_graph.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_changelog.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_chatbot_config.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_chatbot_embeddings.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_chatbot_eval.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_chatbot_index.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_chatbot_persistence.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_chatbot_providers.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_chatbot_query.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_chatbot_relationship.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_chatbot_scaffold.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_chatbot_source_archive.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_citations.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_claim_validation.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_classify.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_cli_generate.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_cli_serve.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_cli_update.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_config_defaults.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_consistency_pass.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_coverage_report.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_docs_system.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_embedding_capabilities.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_empty_repo_guard.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_endpoint_priority_dedupe.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_fastapi_phantom_endpoints.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_fastapi_product_gate.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_flow_candidates.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_framework_fixtures.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_framework_support.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_generation_evidence.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_hosted_upload.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_internal_docs_metadata.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_language_support.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_litellm_compat.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_llm_json_utils.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_llm_retry.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_manifest_performance.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_nav_shaping.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_next_builder.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_output_safety.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_parallel_pipeline.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_parallel_scan.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_parser_ranges.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_persistent_index.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_phase1_perf.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_plan_contract.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_planner_assignment_partition.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_planner_consolidation.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_planner_granularity.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_planner_merge.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_planner_partitioning.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_planner_unit_boundaries.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_planner_unit_orchestration.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_rate_limit.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_repo_model.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_route_composition.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_route_registry.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_runtime_evidence_regressions.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_runtime_scan.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_scale.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_scan_guards.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_scan_telemetry.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_scanner_llm_bounds.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_serve_resync.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_site_config_schema.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_slug_dedup.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_smart_update.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_stale.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_state.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_telemetry.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_token_budget.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_unknown_language_coverage.py +0 -0
- {deepdoc-0.6.1 → deepdoc-0.6.2}/tests/test_word_count.py +0 -0
|
@@ -473,10 +473,12 @@ class BucketGenerationEngine:
|
|
|
473
473
|
for spec_path in self.scan.openapi_paths:
|
|
474
474
|
spec = parse_openapi_spec(self.repo_root / spec_path)
|
|
475
475
|
if spec:
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
476
|
+
# Supplemental context only: a malformed spec must not abort the run.
|
|
477
|
+
try:
|
|
478
|
+
rendered = spec_to_context_string(spec)[:per_spec_limit]
|
|
479
|
+
except Exception:
|
|
480
|
+
continue
|
|
481
|
+
chunk = f"\n## OpenAPI Spec ({spec_path}):\n{rendered}"
|
|
480
482
|
parts.append(chunk)
|
|
481
483
|
total += len(chunk)
|
|
482
484
|
if total >= 6000:
|
|
@@ -12,6 +12,16 @@ from typing import Any
|
|
|
12
12
|
from urllib.parse import urlparse
|
|
13
13
|
|
|
14
14
|
|
|
15
|
+
def _d(value: Any) -> dict:
|
|
16
|
+
"""Coerce to a dict. YAML ``key:`` with no value parses to None, and
|
|
17
|
+
``.get(key, default)`` returns that None instead of the default."""
|
|
18
|
+
return value if isinstance(value, dict) else {}
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def _l(value: Any) -> list:
|
|
22
|
+
return value if isinstance(value, list) else []
|
|
23
|
+
|
|
24
|
+
|
|
15
25
|
def find_openapi_specs(repo_root: Path) -> list[Path]:
|
|
16
26
|
"""Find all OpenAPI/Swagger spec files in the repo."""
|
|
17
27
|
candidates = [
|
|
@@ -35,16 +45,17 @@ def parse_openapi_spec(spec_path: Path) -> dict[str, Any] | None:
|
|
|
35
45
|
try:
|
|
36
46
|
content = spec_path.read_text(encoding="utf-8")
|
|
37
47
|
if spec_path.suffix == ".json":
|
|
38
|
-
|
|
48
|
+
parsed = json.loads(content)
|
|
39
49
|
else:
|
|
40
50
|
try:
|
|
41
51
|
import yaml
|
|
42
|
-
|
|
52
|
+
parsed = yaml.safe_load(content)
|
|
43
53
|
except ImportError:
|
|
44
54
|
# Try JSON anyway
|
|
45
|
-
|
|
55
|
+
parsed = json.loads(content)
|
|
46
56
|
except Exception:
|
|
47
57
|
return None
|
|
58
|
+
return parsed if isinstance(parsed, dict) else None
|
|
48
59
|
|
|
49
60
|
|
|
50
61
|
def extract_endpoints_from_spec(spec: dict[str, Any]) -> list[dict[str, Any]]:
|
|
@@ -55,9 +66,9 @@ def extract_endpoints_from_spec(spec: dict[str, Any]) -> list[dict[str, Any]]:
|
|
|
55
66
|
|
|
56
67
|
# OpenAPI 3.x
|
|
57
68
|
if "openapi" in spec:
|
|
58
|
-
servers = spec.get("servers"
|
|
69
|
+
servers = _l(spec.get("servers"))
|
|
59
70
|
if servers:
|
|
60
|
-
server_url = str(servers[0].get("url", "") or "").strip()
|
|
71
|
+
server_url = str(_d(servers[0]).get("url", "") or "").strip()
|
|
61
72
|
if server_url:
|
|
62
73
|
parsed = urlparse(server_url)
|
|
63
74
|
if parsed.scheme or parsed.netloc:
|
|
@@ -67,26 +78,27 @@ def extract_endpoints_from_spec(spec: dict[str, Any]) -> list[dict[str, Any]]:
|
|
|
67
78
|
|
|
68
79
|
# Swagger 2.x
|
|
69
80
|
elif "swagger" in spec:
|
|
70
|
-
base_path = spec.get("basePath"
|
|
81
|
+
base_path = str(spec.get("basePath") or "")
|
|
71
82
|
|
|
72
|
-
|
|
73
|
-
|
|
83
|
+
for path, methods in _d(spec.get("paths")).items():
|
|
84
|
+
path = str(path)
|
|
74
85
|
full_path = base_path + path if not path.startswith("http") else path
|
|
75
86
|
|
|
76
|
-
for method, details in methods.items():
|
|
77
|
-
|
|
87
|
+
for method, details in _d(methods).items():
|
|
88
|
+
details = _d(details)
|
|
89
|
+
if str(method).lower() in ("get", "post", "put", "patch", "delete", "head", "options"):
|
|
78
90
|
endpoint = {
|
|
79
91
|
"method": method.upper(),
|
|
80
92
|
"path": full_path,
|
|
81
|
-
"summary": details.get("summary"
|
|
82
|
-
"description": details.get("description"
|
|
83
|
-
"operation_id": details.get("operationId"
|
|
84
|
-
"tags": details.get("tags"
|
|
93
|
+
"summary": str(details.get("summary") or ""),
|
|
94
|
+
"description": str(details.get("description") or ""),
|
|
95
|
+
"operation_id": str(details.get("operationId") or ""),
|
|
96
|
+
"tags": _l(details.get("tags")),
|
|
85
97
|
"parameters": _extract_parameters(details, spec),
|
|
86
98
|
"request_body": _extract_request_body(details, spec),
|
|
87
99
|
"responses": _extract_responses(details, spec),
|
|
88
|
-
"security": details.get("security", spec.get("security"
|
|
89
|
-
"deprecated": details.get("deprecated", False),
|
|
100
|
+
"security": _l(details.get("security", spec.get("security"))),
|
|
101
|
+
"deprecated": bool(details.get("deprecated", False)),
|
|
90
102
|
}
|
|
91
103
|
endpoints.append(endpoint)
|
|
92
104
|
|
|
@@ -96,10 +108,10 @@ def extract_endpoints_from_spec(spec: dict[str, Any]) -> list[dict[str, Any]]:
|
|
|
96
108
|
def spec_to_context_string(spec: dict[str, Any]) -> str:
|
|
97
109
|
"""Convert an OpenAPI spec into a compact string for LLM context."""
|
|
98
110
|
lines = []
|
|
99
|
-
info = spec.get("info"
|
|
100
|
-
lines.append(f"API: {info.get('title'
|
|
111
|
+
info = _d(spec.get("info"))
|
|
112
|
+
lines.append(f"API: {info.get('title') or 'Unknown'} v{info.get('version') or '?'}")
|
|
101
113
|
if info.get("description"):
|
|
102
|
-
lines.append(f"Description: {info['description'][:200]}")
|
|
114
|
+
lines.append(f"Description: {str(info['description'])[:200]}")
|
|
103
115
|
|
|
104
116
|
endpoints = extract_endpoints_from_spec(spec)
|
|
105
117
|
lines.append(f"\nEndpoints ({len(endpoints)}):")
|
|
@@ -131,8 +143,8 @@ def spec_to_context_string(spec: dict[str, Any]) -> str:
|
|
|
131
143
|
|
|
132
144
|
def _extract_parameters(details: dict, spec: dict) -> list[dict]:
|
|
133
145
|
params = []
|
|
134
|
-
for p in details.get("parameters"
|
|
135
|
-
p = _resolve_ref(p, spec)
|
|
146
|
+
for p in _l(details.get("parameters")):
|
|
147
|
+
p = _d(_resolve_ref(p, spec))
|
|
136
148
|
params.append({
|
|
137
149
|
"name": p.get("name", "?"),
|
|
138
150
|
"in": p.get("in", "?"),
|
|
@@ -144,26 +156,25 @@ def _extract_parameters(details: dict, spec: dict) -> list[dict]:
|
|
|
144
156
|
|
|
145
157
|
|
|
146
158
|
def _extract_request_body(details: dict, spec: dict) -> str:
|
|
147
|
-
rb = details.get("requestBody"
|
|
159
|
+
rb = details.get("requestBody")
|
|
148
160
|
if not rb:
|
|
149
161
|
return ""
|
|
150
|
-
rb = _resolve_ref(rb, spec)
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
schema = _resolve_ref(schema_info.get("schema", {}), spec)
|
|
162
|
+
rb = _d(_resolve_ref(rb, spec))
|
|
163
|
+
for _media_type, schema_info in _d(rb.get("content")).items():
|
|
164
|
+
schema = _resolve_ref(_d(schema_info).get("schema", {}), spec)
|
|
154
165
|
return json.dumps(schema, indent=2)[:500]
|
|
155
166
|
return ""
|
|
156
167
|
|
|
157
168
|
|
|
158
169
|
def _extract_responses(details: dict, spec: dict) -> dict[str, str]:
|
|
159
170
|
responses = {}
|
|
160
|
-
for status, resp in details.get("responses"
|
|
161
|
-
resp = _resolve_ref(resp, spec)
|
|
162
|
-
desc = resp.get("description"
|
|
163
|
-
content = resp.get("content"
|
|
171
|
+
for status, resp in _d(details.get("responses")).items():
|
|
172
|
+
resp = _d(_resolve_ref(resp, spec))
|
|
173
|
+
desc = str(resp.get("description") or "")
|
|
174
|
+
content = _d(resp.get("content"))
|
|
164
175
|
if content:
|
|
165
176
|
for _media_type, schema_info in content.items():
|
|
166
|
-
schema = _resolve_ref(schema_info.get("schema", {}), spec)
|
|
177
|
+
schema = _resolve_ref(_d(schema_info).get("schema", {}), spec)
|
|
167
178
|
desc += f" | schema: {json.dumps(schema)[:200]}"
|
|
168
179
|
break
|
|
169
180
|
responses[str(status)] = desc[:300]
|
|
@@ -180,7 +191,7 @@ def _resolve_ref(obj: dict, spec: dict) -> dict:
|
|
|
180
191
|
parts = ref.lstrip("#/").split("/")
|
|
181
192
|
resolved = spec
|
|
182
193
|
for part in parts:
|
|
183
|
-
resolved = resolved.get(part, {})
|
|
194
|
+
resolved = _d(resolved).get(part, {})
|
|
184
195
|
return resolved if isinstance(resolved, dict) else obj
|
|
185
196
|
|
|
186
197
|
|
|
@@ -199,6 +199,7 @@ tests/test_llm_retry.py
|
|
|
199
199
|
tests/test_manifest_performance.py
|
|
200
200
|
tests/test_nav_shaping.py
|
|
201
201
|
tests/test_next_builder.py
|
|
202
|
+
tests/test_openapi_null_values.py
|
|
202
203
|
tests/test_output_safety.py
|
|
203
204
|
tests/test_parallel_pipeline.py
|
|
204
205
|
tests/test_parallel_scan.py
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"""Specs with empty YAML values (``info:`` with nothing under it) parse to None.
|
|
2
|
+
|
|
3
|
+
``dict.get(key, default)`` returns that None, so a sloppy-but-loadable spec used
|
|
4
|
+
to crash ``spec_to_context_string`` and abort the whole generation run.
|
|
5
|
+
"""
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
from deepdoc.openapi import (
|
|
9
|
+
extract_endpoints_from_spec,
|
|
10
|
+
parse_openapi_spec,
|
|
11
|
+
spec_to_context_string,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
SLOPPY_YAML = """\
|
|
15
|
+
openapi: 3.0.0
|
|
16
|
+
info:
|
|
17
|
+
servers:
|
|
18
|
+
paths:
|
|
19
|
+
/things:
|
|
20
|
+
get:
|
|
21
|
+
summary:
|
|
22
|
+
tags:
|
|
23
|
+
parameters:
|
|
24
|
+
requestBody:
|
|
25
|
+
responses:
|
|
26
|
+
"200":
|
|
27
|
+
description:
|
|
28
|
+
content:
|
|
29
|
+
post:
|
|
30
|
+
/empty:
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def test_null_valued_spec_renders_context(tmp_path):
|
|
35
|
+
path = tmp_path / "openapi.yaml"
|
|
36
|
+
path.write_text(SLOPPY_YAML, encoding="utf-8")
|
|
37
|
+
spec = parse_openapi_spec(path)
|
|
38
|
+
assert spec is not None
|
|
39
|
+
|
|
40
|
+
text = spec_to_context_string(spec)
|
|
41
|
+
|
|
42
|
+
assert "API: Unknown v?" in text
|
|
43
|
+
assert "GET /things" in text
|
|
44
|
+
assert "POST /things" in text
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def test_null_valued_spec_extracts_endpoints(tmp_path):
|
|
48
|
+
path = tmp_path / "openapi.yaml"
|
|
49
|
+
path.write_text(SLOPPY_YAML, encoding="utf-8")
|
|
50
|
+
endpoints = extract_endpoints_from_spec(parse_openapi_spec(path))
|
|
51
|
+
|
|
52
|
+
assert {(e["method"], e["path"]) for e in endpoints} == {
|
|
53
|
+
("GET", "/things"),
|
|
54
|
+
("POST", "/things"),
|
|
55
|
+
}
|
|
56
|
+
assert all(isinstance(e["tags"], list) for e in endpoints)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def test_non_mapping_spec_is_rejected(tmp_path):
|
|
60
|
+
path = tmp_path / "openapi.yaml"
|
|
61
|
+
path.write_text("- just\n- a list\n", encoding="utf-8")
|
|
62
|
+
assert parse_openapi_spec(path) is None
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{deepdoc-0.6.1 → deepdoc-0.6.2}/deepdoc/site/builder/next_template/app/(main)/[[...slug]]/page.tsx
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|