DeepFabric 4.8.2__tar.gz → 4.9.0__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.
- {deepfabric-4.8.2 → deepfabric-4.9.0}/.github/workflows/docs.yml +1 -1
- {deepfabric-4.8.2 → deepfabric-4.9.0}/.github/workflows/integration.yml +1 -1
- {deepfabric-4.8.2 → deepfabric-4.9.0}/.github/workflows/publish.yml +1 -1
- {deepfabric-4.8.2 → deepfabric-4.9.0}/.github/workflows/test.yml +1 -1
- deepfabric-4.9.0/CODE_OF_CONDUCT.md +77 -0
- deepfabric-4.9.0/CONTRIBUTING.md +256 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/PKG-INFO +3 -3
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/config.py +5 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/graph.py +51 -11
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/metrics.py +2 -2
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/prompts.py +136 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/schemas.py +3 -1
- {deepfabric-4.8.2 → deepfabric-4.9.0}/docs/cli/upload.md +1 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/docs/dataset-generation/agent.md +1 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/docs/dataset-generation/configuration.md +27 -2
- {deepfabric-4.8.2 → deepfabric-4.9.0}/examples/agent-tools-multi.yaml +1 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/examples/agent-tools-single.yaml +1 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/examples/basic-anthropic.yaml +1 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/examples/basic-gemini.yaml +1 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/examples/basic-graph.yaml +1 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/examples/basic-ollama.yaml +1 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/examples/basic-openai.yaml +1 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/examples/basic-openrouter.yaml +1 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/examples/coding-agent.yaml +1 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/examples/github-mock-tools.yaml +1 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/examples/reasoning.yaml +1 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/examples/spin-vfs-tools.yaml +1 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/examples/tools-sdk-examples/figma/spin-figma.yaml +1 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/examples/tools-sdk-examples/github/spin-github-tools.yaml +1 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/examples/tools-sdk-examples/kubernetes/spin-kubernetes.yaml +1 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/pyproject.toml +3 -3
- {deepfabric-4.8.2 → deepfabric-4.9.0}/tests/unit/test_api_key_validation.py +1 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/tests/unit/test_cli.py +1 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/tests/unit/test_hf_hub.py +8 -1
- {deepfabric-4.8.2 → deepfabric-4.9.0}/uv.lock +61 -22
- deepfabric-4.8.2/examples/mcp-adversarial-suite/README.md +0 -269
- deepfabric-4.8.2/examples/mcp-adversarial-suite/configs/all.yaml +0 -213
- deepfabric-4.8.2/examples/mcp-adversarial-suite/configs/driftlab.yaml +0 -113
- deepfabric-4.8.2/examples/mcp-adversarial-suite/configs/homoglyph.yaml +0 -107
- deepfabric-4.8.2/examples/mcp-adversarial-suite/configs/insecurefs.yaml +0 -139
- deepfabric-4.8.2/examples/mcp-adversarial-suite/configs/resource_trap.yaml +0 -147
- deepfabric-4.8.2/examples/mcp-adversarial-suite/configs/spoofbox.yaml +0 -124
- {deepfabric-4.8.2 → deepfabric-4.9.0}/.github/config.yml +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/.github/dependabot.yml +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/.github/workflows/tools-sdk-docker.yml +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/.gitignore +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/CLAUDE.md +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/LICENSE +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/Makefile +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/README.md +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/assets/df-demo.gif +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/assets/logo-light-hols.png +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/assets/logo-light.png +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/assets/star.gif +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/coverage.xml +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/__init__.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/__main__.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/auth.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/builders.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/builders_agent.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/cli.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/cloud_upload.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/config_manager.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/constants.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/dataset.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/dataset_manager.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/error_codes.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/evaluation/__init__.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/evaluation/backends/__init__.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/evaluation/backends/llm_eval_backend.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/evaluation/backends/ollama_backend.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/evaluation/backends/tool_call_parsers.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/evaluation/backends/transformers_backend.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/evaluation/evaluator.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/evaluation/evaluators/__init__.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/evaluation/evaluators/base.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/evaluation/evaluators/builtin/__init__.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/evaluation/evaluators/builtin/tool_calling.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/evaluation/evaluators/registry.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/evaluation/inference.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/evaluation/metrics.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/evaluation/parser.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/evaluation/reporters/__init__.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/evaluation/reporters/base.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/evaluation/reporters/cloud_reporter.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/evaluation/reporters/file_reporter.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/evaluation/reporters/multi_reporter.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/exceptions.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/factory.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/generator.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/hf_hub.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/kaggle_hub.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/llm/__init__.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/llm/api_key_verifier.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/llm/client.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/llm/errors.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/llm/rate_limit_config.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/llm/rate_limit_detector.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/llm/retry_handler.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/loader.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/progress.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/spin/__init__.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/spin/client.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/spin/models.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/stream_simulator.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/tools/__init__.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/tools/defaults.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/tools/loader.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/tools/mcp_client.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/topic_manager.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/topic_model.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/training/__init__.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/training/api_key_prompt.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/training/callback.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/training/dataset_utils.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/training/metrics_sender.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/tree.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/tui.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/update_checker.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/utils.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/deepfabric/validation.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/docs/cli/evaluate.md +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/docs/cli/generate.md +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/docs/cli/import-tools.md +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/docs/cli/index.md +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/docs/cli/info.md +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/docs/cli/upload-hf.md +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/docs/cli/upload-kaggle.md +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/docs/cli/validate.md +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/docs/cli/visualize.md +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/docs/dataset-generation/basic.md +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/docs/dataset-generation/index.md +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/docs/dataset-generation/rate-limiting.md +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/docs/dataset-generation/reasoning.md +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/docs/evaluation/index.md +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/docs/evaluation/metrics.md +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/docs/evaluation/running.md +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/docs/images/logo-light.png +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/docs/images/python-spin.png +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/docs/index.md +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/docs/tools/custom.md +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/docs/tools/index.md +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/docs/tools/mock.md +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/docs/tools/spin.md +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/docs/tools/tutorials/go.md +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/docs/tools/tutorials/index.md +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/docs/tools/tutorials/python.md +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/docs/tools/tutorials/rust.md +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/docs/tools/tutorials/typescript.md +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/docs/tools/vfs.md +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/docs/training/chat-templates.md +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/docs/training/dataset-preparation.md +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/docs/training/frameworks.md +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/docs/training/index.md +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/docs/training/loading.md +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/examples/basic-tree.yaml +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/examples/complete.yaml +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/examples/custom-tools.yaml +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/examples/tools-sdk-examples/blender/load-blender-mock-data.sh +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/examples/tools-sdk-examples/blender/spin-blender.yaml +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/examples/tools-sdk-examples/figma/load-figma-mock-data.sh +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/examples/tools-sdk-examples/github/load-github-mock-data.sh +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/examples/tools-sdk-examples/kubernetes/load-kubernetes-mock-data.sh +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/misc/test_update_manual.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/mkdocs.yml +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/notebooks/Train_and_Evaluate_Qwen3_4B_Thinking_as_a_Blender_MCP_Agent.ipynb +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/notebooks/dataset-compatibility-check.ipynb +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/notebooks/evaluations.ipynb +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/test-run/01-alpaca.txt +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/test-run/01-chatml.txt +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/test-run/01-grpo.txt +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/test-run/01-xlam_v2.txt +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/test-run/02-trl2.txt +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/test-run/02-xlam_v2.txt +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/test-run/04-agent-tool-conversations.jsnl +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/test-run/04-single-agent-tools +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/tests/__init__.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/tests/integration/__init__.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/tests/integration/conftest.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/tests/integration/test_generator_integration.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/tests/integration/test_graph_integration.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/tests/integration/test_llm_client_integration.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/tests/integration/test_spin_integration.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/tests/integration/test_tree_integration.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/tests/unit/__init__.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/tests/unit/conftest.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/tests/unit/test_cloud_upload.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/tests/unit/test_config.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/tests/unit/test_dataset.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/tests/unit/test_error_codes.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/tests/unit/test_gemini_schema.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/tests/unit/test_generator.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/tests/unit/test_kaggle_hub.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/tests/unit/test_llm_eval_backend.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/tests/unit/test_loader.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/tests/unit/test_modular_config.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/tests/unit/test_rate_limiting.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/tests/unit/test_schemas.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/tests/unit/test_tool_call_parsers.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/tests/unit/test_topic_graph.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/tests/unit/test_training_callback.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/tests/unit/test_update_checker.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/tools/extract_messages.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/tools/function.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/tools/yaml_to_openai_tools.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/tools-sdk/.dockerignore +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/tools-sdk/Dockerfile +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/tools-sdk/README.md +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/tools-sdk/components/github/README.md +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/tools-sdk/components/github/app.py +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/tools-sdk/components/github/github.wasm +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/tools-sdk/components/github/pyproject.toml +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/tools-sdk/components/github/requirements.txt +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/tools-sdk/components/github/spin.toml +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/tools-sdk/components/github/uv.lock +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/tools-sdk/components/mock/Cargo.lock +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/tools-sdk/components/mock/Cargo.toml +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/tools-sdk/components/mock/README.md +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/tools-sdk/components/mock/src/lib.rs +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/tools-sdk/components/vfs/Cargo.lock +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/tools-sdk/components/vfs/Cargo.toml +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/tools-sdk/components/vfs/src/lib.rs +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/tools-sdk/docker-compose.yaml +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/tools-sdk/runtime-config.toml +0 -0
- {deepfabric-4.8.2 → deepfabric-4.9.0}/tools-sdk/spin.toml +0 -0
|
@@ -23,7 +23,7 @@ jobs:
|
|
|
23
23
|
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v5
|
|
24
24
|
|
|
25
25
|
- name: Install uv
|
|
26
|
-
uses: astral-sh/setup-uv@
|
|
26
|
+
uses: astral-sh/setup-uv@61cb8a9741eeb8a550a1b8544337180c0fc8476b # v7
|
|
27
27
|
|
|
28
28
|
- name: Set up Python
|
|
29
29
|
run: uv python install
|
|
@@ -22,7 +22,7 @@ jobs:
|
|
|
22
22
|
python-version: ${{ matrix.python-version }}
|
|
23
23
|
|
|
24
24
|
- name: Install uv
|
|
25
|
-
uses: astral-sh/setup-uv@
|
|
25
|
+
uses: astral-sh/setup-uv@61cb8a9741eeb8a550a1b8544337180c0fc8476b # v7
|
|
26
26
|
with:
|
|
27
27
|
enable-cache: true
|
|
28
28
|
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
|
|
2
|
+
# Contributor Covenant Code of Conduct
|
|
3
|
+
|
|
4
|
+
## Our Pledge
|
|
5
|
+
|
|
6
|
+
In the interest of fostering an open and welcoming environment, we as
|
|
7
|
+
contributors and maintainers pledge to make participation in our project and
|
|
8
|
+
our community a harassment-free experience for everyone, regardless of age, body
|
|
9
|
+
size, disability, ethnicity, sex characteristics, gender identity and expression,
|
|
10
|
+
level of experience, education, socio-economic status, nationality, personal
|
|
11
|
+
appearance, race, religion, or sexual identity and orientation.
|
|
12
|
+
|
|
13
|
+
## Our Standards
|
|
14
|
+
|
|
15
|
+
Examples of behavior that contributes to creating a positive environment
|
|
16
|
+
include:
|
|
17
|
+
|
|
18
|
+
* Using welcoming and inclusive language
|
|
19
|
+
* Being respectful of differing viewpoints and experiences
|
|
20
|
+
* Gracefully accepting constructive criticism
|
|
21
|
+
* Focusing on what is best for the community
|
|
22
|
+
* Showing empathy towards other community members
|
|
23
|
+
|
|
24
|
+
Examples of unacceptable behavior by participants include:
|
|
25
|
+
|
|
26
|
+
* The use of sexualized language or imagery and unwelcome sexual attention or
|
|
27
|
+
advances
|
|
28
|
+
* Trolling, insulting/derogatory comments, and personal or political attacks
|
|
29
|
+
* Public or private harassment
|
|
30
|
+
* Publishing others' private information, such as a physical or electronic
|
|
31
|
+
address, without explicit permission
|
|
32
|
+
* Other conduct which could reasonably be considered inappropriate in a
|
|
33
|
+
professional setting
|
|
34
|
+
|
|
35
|
+
## Our Responsibilities
|
|
36
|
+
|
|
37
|
+
Project maintainers are responsible for clarifying the standards of acceptable
|
|
38
|
+
behavior and are expected to take appropriate and fair corrective action in
|
|
39
|
+
response to any instances of unacceptable behavior.
|
|
40
|
+
|
|
41
|
+
Project maintainers have the right and responsibility to remove, edit, or
|
|
42
|
+
reject comments, commits, code, wiki edits, issues, and other contributions
|
|
43
|
+
that are not aligned to this Code of Conduct, or to ban temporarily or
|
|
44
|
+
permanently any contributor for other behaviors that they deem inappropriate,
|
|
45
|
+
threatening, offensive, or harmful.
|
|
46
|
+
|
|
47
|
+
## Scope
|
|
48
|
+
|
|
49
|
+
This Code of Conduct applies within all project spaces, and it also applies when
|
|
50
|
+
an individual is representing the project or its community in public spaces.
|
|
51
|
+
Examples of representing a project or community include using an official
|
|
52
|
+
project e-mail address, posting via an official social media account, or acting
|
|
53
|
+
as an appointed representative at an online or offline event. Representation of
|
|
54
|
+
a project may be further defined and clarified by project maintainers.
|
|
55
|
+
|
|
56
|
+
## Enforcement
|
|
57
|
+
|
|
58
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
|
59
|
+
reported by contacting the project team at [hello@alwaysfurther.ai](mailto:hello@alwaysfurther.ai).
|
|
60
|
+
All complaints will be reviewed and investigated and will result in a response that
|
|
61
|
+
is deemed necessary and appropriate to the circumstances. The project team is
|
|
62
|
+
obligated to maintain confidentiality with regard to the reporter of an incident.
|
|
63
|
+
Further details of specific enforcement policies may be posted separately.
|
|
64
|
+
|
|
65
|
+
Project maintainers who do not follow or enforce the Code of Conduct in good
|
|
66
|
+
faith may face temporary or permanent repercussions as determined by other
|
|
67
|
+
members of the project's leadership.
|
|
68
|
+
|
|
69
|
+
## Attribution
|
|
70
|
+
|
|
71
|
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
|
72
|
+
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
|
|
73
|
+
|
|
74
|
+
[homepage]: https://www.contributor-covenant.org
|
|
75
|
+
|
|
76
|
+
For answers to common questions about this code of conduct, see
|
|
77
|
+
https://www.contributor-covenant.org/faq
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
## Contributing
|
|
2
|
+
|
|
3
|
+
Thank you for considering contributing to [deepfabric](https://github.com/always-further/deepfabric)!
|
|
4
|
+
|
|
5
|
+
When contributing, please first discuss the change you wish to make via [issue](https://github.com/always-further/deepfabric/issues), [email](mailto:hello@alwaysfurther.ai), or any other method with the owners of this repository before making a change.
|
|
6
|
+
|
|
7
|
+
Note that we have a [Code of Conduct](./CODE_OF_CONDUCT.md), please follow it in all your interactions with the project.
|
|
8
|
+
|
|
9
|
+
## Setup
|
|
10
|
+
|
|
11
|
+
### Prerequisites
|
|
12
|
+
|
|
13
|
+
- **Python 3.10 or later**
|
|
14
|
+
|
|
15
|
+
## Development
|
|
16
|
+
|
|
17
|
+
### 1. Fork and clone the repository
|
|
18
|
+
|
|
19
|
+
Fork this repository and create your branch from `main`.
|
|
20
|
+
|
|
21
|
+
```sh
|
|
22
|
+
git clone https://github.com/<YOUR-USERNAME>/deepfabric
|
|
23
|
+
cd deepfabric
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### 2. Create and activate a virtual environment
|
|
27
|
+
|
|
28
|
+
We strongly recommend using an isolated virtual environment.
|
|
29
|
+
|
|
30
|
+
#### Option A: Using `venv` (standard Python)
|
|
31
|
+
|
|
32
|
+
```sh
|
|
33
|
+
python -m venv .venv
|
|
34
|
+
source .venv/bin/activate
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
#### Option B: Using [`uv`](https://docs.astral.sh/uv/) (recommended)
|
|
38
|
+
|
|
39
|
+
DeepFabric supports running all development tasks via [`uv`](https://docs.astral.sh/uv/), which provides fast and reproducible environments without manual virtual environment activation.
|
|
40
|
+
|
|
41
|
+
### 3. Install the project and development dependencies
|
|
42
|
+
|
|
43
|
+
DeepFabric uses [PEP 621 (pyproject.toml)](https://peps.python.org/pep-0621/) with [Hatch](https://hatch.pypa.io/latest/) as the build backend.
|
|
44
|
+
|
|
45
|
+
<details>
|
|
46
|
+
<summary>Option A: Standard Python (`venv` + `pip`)</summary>
|
|
47
|
+
|
|
48
|
+
```sh
|
|
49
|
+
# Make sure your virtual environment is activated.
|
|
50
|
+
pip install -U pip
|
|
51
|
+
pip install -e '.[dev]'
|
|
52
|
+
```
|
|
53
|
+
</details>
|
|
54
|
+
|
|
55
|
+
<details>
|
|
56
|
+
<summary>Option B: Using `uv` (recommended)</summary>
|
|
57
|
+
|
|
58
|
+
```sh
|
|
59
|
+
uv sync --extra dev
|
|
60
|
+
```
|
|
61
|
+
</details>
|
|
62
|
+
|
|
63
|
+
This installs:
|
|
64
|
+
- test dependencies (`pytest`, `pytest-cov`, etc.)
|
|
65
|
+
- linting and security tools (`ruff`, `bandit`)
|
|
66
|
+
|
|
67
|
+
### 4. Run the test suite
|
|
68
|
+
|
|
69
|
+
Ensure all tests pass before submitting changes.
|
|
70
|
+
|
|
71
|
+
#### Unit tests (required)
|
|
72
|
+
|
|
73
|
+
At a minimum, please run the unit test suite. Additional integration and security checks are recommended when relevant.
|
|
74
|
+
|
|
75
|
+
<details>
|
|
76
|
+
<summary>Option A: Standard Python (`venv` + `pip`)</summary>
|
|
77
|
+
|
|
78
|
+
```sh
|
|
79
|
+
# Make sure your virtual environment is activated.
|
|
80
|
+
pytest tests/unit/
|
|
81
|
+
```
|
|
82
|
+
</details>
|
|
83
|
+
|
|
84
|
+
<details>
|
|
85
|
+
<summary>Option B: Using `uv` (recommended)</summary>
|
|
86
|
+
|
|
87
|
+
```sh
|
|
88
|
+
uv run pytest tests/unit/
|
|
89
|
+
```
|
|
90
|
+
</details>
|
|
91
|
+
|
|
92
|
+
#### Integration tests (optional, but recommended)
|
|
93
|
+
|
|
94
|
+
Integration tests cover interactions with external systems (e.g. LLM providers). They may require additional environment variables or credentials.
|
|
95
|
+
Please refer to the [Makefile](./Makefile) for available integration test targets.
|
|
96
|
+
|
|
97
|
+
#### Security checks (optional)
|
|
98
|
+
|
|
99
|
+
We recommend running security checks before submitting larger or user-facing changes.
|
|
100
|
+
|
|
101
|
+
<details>
|
|
102
|
+
<summary>Option A: Standard Python (`venv` + `pip`)</summary>
|
|
103
|
+
|
|
104
|
+
```sh
|
|
105
|
+
# Make sure your virtual environment is activated.
|
|
106
|
+
bandit -r deepfabric/
|
|
107
|
+
```
|
|
108
|
+
</details>
|
|
109
|
+
|
|
110
|
+
<details>
|
|
111
|
+
<summary>Option B: Using `uv` (recommended)</summary>
|
|
112
|
+
|
|
113
|
+
```sh
|
|
114
|
+
uv run bandit -r deepfabric/
|
|
115
|
+
```
|
|
116
|
+
</details>
|
|
117
|
+
|
|
118
|
+
### 5. Lint and format the code
|
|
119
|
+
|
|
120
|
+
Ensure the codebase is properly linted and formatted before submitting changes.
|
|
121
|
+
|
|
122
|
+
<details>
|
|
123
|
+
<summary>Option A: Standard Python (`venv` + `pip`)</summary>
|
|
124
|
+
|
|
125
|
+
```sh
|
|
126
|
+
# Make sure your virtual environment is activated.
|
|
127
|
+
ruff format deepfabric/ tests/
|
|
128
|
+
ruff check . --exclude notebooks/
|
|
129
|
+
```
|
|
130
|
+
</details>
|
|
131
|
+
|
|
132
|
+
<details>
|
|
133
|
+
<summary>Option B: Using `uv` (recommended)</summary>
|
|
134
|
+
|
|
135
|
+
```sh
|
|
136
|
+
uv run ruff format deepfabric/ tests/
|
|
137
|
+
uv run ruff check . --exclude notebooks/
|
|
138
|
+
```
|
|
139
|
+
</details>
|
|
140
|
+
|
|
141
|
+
### 6. Commit your changes
|
|
142
|
+
|
|
143
|
+
We strongly recommend following the [Conventional Commits specification](https://www.conventionalcommits.org/en/v1.0.0/) when committing:
|
|
144
|
+
|
|
145
|
+
- **feat:** new features
|
|
146
|
+
- **fix:** bug fixes
|
|
147
|
+
- **docs:** documentation-only changes
|
|
148
|
+
- **refactor:** code refactoring
|
|
149
|
+
- **test:** adding or updating tests
|
|
150
|
+
- **chore:** tooling and maintenance
|
|
151
|
+
|
|
152
|
+
Example:
|
|
153
|
+
|
|
154
|
+
```sh
|
|
155
|
+
git commit -m "feat: add dataset validation pipeline"
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## Documentation
|
|
159
|
+
|
|
160
|
+
### 1. Install documentation dependencies
|
|
161
|
+
|
|
162
|
+
DeepFabric uses [MkDocs](https://www.mkdocs.org/) with the [Material theme](https://squidfunk.github.io/mkdocs-material/) for documentation.
|
|
163
|
+
|
|
164
|
+
<details>
|
|
165
|
+
<summary>Option A: Standard Python (`venv` + `pip`)</summary>
|
|
166
|
+
|
|
167
|
+
```sh
|
|
168
|
+
# Make sure your virtual environment is activated.
|
|
169
|
+
pip install -U pip
|
|
170
|
+
pip install -e '.[docs]'
|
|
171
|
+
```
|
|
172
|
+
</details>
|
|
173
|
+
|
|
174
|
+
<details>
|
|
175
|
+
<summary>Option B: Using `uv` (recommended)</summary>
|
|
176
|
+
|
|
177
|
+
```sh
|
|
178
|
+
uv sync --extra docs
|
|
179
|
+
```
|
|
180
|
+
</details>
|
|
181
|
+
|
|
182
|
+
This installs:
|
|
183
|
+
- MkDocs and the Material theme (`mkdocs-material`)
|
|
184
|
+
- Python API documentation support via `mkdocstrings[python]`
|
|
185
|
+
|
|
186
|
+
### 2. Writing documentation
|
|
187
|
+
|
|
188
|
+
- User-facing documentation lives in the [docs](./docs) directory.
|
|
189
|
+
- API documentation is generated from [Python docstrings](https://peps.python.org/pep-0257/) via `mkdocstrings`.
|
|
190
|
+
- Please follow the existing style and structure when adding new pages.
|
|
191
|
+
|
|
192
|
+
### 3. Docstring conventions
|
|
193
|
+
|
|
194
|
+
DeepFabric enforces [Google-style docstrings](https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings), consistent with the `ruff` configuration:
|
|
195
|
+
|
|
196
|
+
```toml
|
|
197
|
+
[tool.ruff.lint.pydocstyle]
|
|
198
|
+
convention = "google"
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
Example:
|
|
202
|
+
|
|
203
|
+
```python
|
|
204
|
+
def load_dataset(path: str) -> Dataset:
|
|
205
|
+
"""Load a dataset from disk.
|
|
206
|
+
|
|
207
|
+
Args:
|
|
208
|
+
path: Path to the dataset directory.
|
|
209
|
+
|
|
210
|
+
Returns:
|
|
211
|
+
The loaded dataset.
|
|
212
|
+
"""
|
|
213
|
+
...
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### 4. Serve the documentation locally
|
|
217
|
+
|
|
218
|
+
Ensure you can preview the documentation site locally before submitting changes.
|
|
219
|
+
|
|
220
|
+
<details>
|
|
221
|
+
<summary>Option A: Standard Python (`venv` + `pip`)</summary>
|
|
222
|
+
|
|
223
|
+
```sh
|
|
224
|
+
# Make sure your virtual environment is activated.
|
|
225
|
+
mkdocs serve
|
|
226
|
+
```
|
|
227
|
+
</details>
|
|
228
|
+
|
|
229
|
+
<details>
|
|
230
|
+
<summary>Option B: Using `uv` (recommended)</summary>
|
|
231
|
+
|
|
232
|
+
```sh
|
|
233
|
+
uv run mkdocs serve
|
|
234
|
+
```
|
|
235
|
+
</details>
|
|
236
|
+
|
|
237
|
+
### 5. Build the documentation
|
|
238
|
+
|
|
239
|
+
Ensure you generate the static documentation site before publishing or submitting changes.
|
|
240
|
+
|
|
241
|
+
<details>
|
|
242
|
+
<summary>Option A: Standard Python (`venv` + `pip`)</summary>
|
|
243
|
+
|
|
244
|
+
```sh
|
|
245
|
+
# Make sure your virtual environment is activated.
|
|
246
|
+
mkdocs build
|
|
247
|
+
```
|
|
248
|
+
</details>
|
|
249
|
+
|
|
250
|
+
<details>
|
|
251
|
+
<summary>Option B: Using `uv` (recommended)</summary>
|
|
252
|
+
|
|
253
|
+
```sh
|
|
254
|
+
uv run mkdocs build
|
|
255
|
+
```
|
|
256
|
+
</details>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: DeepFabric
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.9.0
|
|
4
4
|
Summary: Curate High Quality Datasets, Train, Evaluate and Ship
|
|
5
5
|
Author-email: DeepFabric Team <oss@alwaysfurther.ai>
|
|
6
6
|
License-File: LICENSE
|
|
@@ -11,7 +11,7 @@ Requires-Dist: componentize-py>=0.19.3
|
|
|
11
11
|
Requires-Dist: datasets<5.0,>=3.0
|
|
12
12
|
Requires-Dist: google-api-core>=2.0.0
|
|
13
13
|
Requires-Dist: google-genai>=1.56.0
|
|
14
|
-
Requires-Dist: huggingface-hub
|
|
14
|
+
Requires-Dist: huggingface-hub>=1.3.1
|
|
15
15
|
Requires-Dist: kagglehub>=0.3.0
|
|
16
16
|
Requires-Dist: mermaid-py>=0.8.0
|
|
17
17
|
Requires-Dist: ollama>=0.6.1
|
|
@@ -25,7 +25,7 @@ Requires-Dist: pyyaml>=6.0.1
|
|
|
25
25
|
Requires-Dist: rich>=13.0.0
|
|
26
26
|
Requires-Dist: sentencepiece>=0.1.99
|
|
27
27
|
Requires-Dist: spin-sdk>=3.4.1
|
|
28
|
-
Requires-Dist: transformers
|
|
28
|
+
Requires-Dist: transformers==5.0.0rc2
|
|
29
29
|
Provides-Extra: dev
|
|
30
30
|
Requires-Dist: bandit>=1.7.10; extra == 'dev'
|
|
31
31
|
Requires-Dist: mermaid-py>=0.2.0; extra == 'dev'
|
|
@@ -109,6 +109,10 @@ class TopicsConfig(BaseModel):
|
|
|
109
109
|
description="Maximum concurrent LLM calls during graph expansion (helps avoid rate limits)",
|
|
110
110
|
)
|
|
111
111
|
save_as: str | None = Field(default=None, description="Where to save the generated topics")
|
|
112
|
+
prompt_style: Literal["default", "isolated", "anchored"] = Field(
|
|
113
|
+
default="default",
|
|
114
|
+
description="For graph mode: 'default' enables cross-connections with generic prompts, 'isolated' disables connections with generic prompts, 'anchored' disables connections and uses domain-aware prompts with examples for focused topic generation",
|
|
115
|
+
)
|
|
112
116
|
|
|
113
117
|
# Optional LLM overrides (inherits from top-level llm if not specified)
|
|
114
118
|
llm: LLMConfig | None = Field(
|
|
@@ -603,6 +607,7 @@ See documentation for full examples.
|
|
|
603
607
|
"depth": self.topics.depth,
|
|
604
608
|
"degree": self.topics.degree,
|
|
605
609
|
"max_concurrent": self.topics.max_concurrent,
|
|
610
|
+
"prompt_style": self.topics.prompt_style,
|
|
606
611
|
}
|
|
607
612
|
|
|
608
613
|
# Handle overrides
|
|
@@ -5,7 +5,7 @@ import textwrap
|
|
|
5
5
|
import uuid
|
|
6
6
|
|
|
7
7
|
from datetime import datetime, timezone
|
|
8
|
-
from typing import TYPE_CHECKING, Any
|
|
8
|
+
from typing import TYPE_CHECKING, Any, Literal
|
|
9
9
|
|
|
10
10
|
from pydantic import BaseModel, ConfigDict, Field
|
|
11
11
|
|
|
@@ -19,7 +19,11 @@ from .constants import (
|
|
|
19
19
|
from .llm import LLMClient
|
|
20
20
|
from .llm.rate_limit_detector import RateLimitDetector
|
|
21
21
|
from .metrics import trace
|
|
22
|
-
from .prompts import
|
|
22
|
+
from .prompts import (
|
|
23
|
+
GRAPH_EXPANSION_PROMPT,
|
|
24
|
+
GRAPH_EXPANSION_PROMPT_NO_CONNECTIONS,
|
|
25
|
+
GraphPromptBuilder,
|
|
26
|
+
)
|
|
23
27
|
from .schemas import GraphSubtopics
|
|
24
28
|
from .stream_simulator import simulate_stream
|
|
25
29
|
from .topic_model import TopicModel
|
|
@@ -70,6 +74,10 @@ class GraphConfig(BaseModel):
|
|
|
70
74
|
default=None,
|
|
71
75
|
description="Base URL for API endpoint (e.g., custom OpenAI-compatible servers)",
|
|
72
76
|
)
|
|
77
|
+
prompt_style: Literal["default", "isolated", "anchored"] = Field(
|
|
78
|
+
default="default",
|
|
79
|
+
description="Prompt style: 'default' (cross-connections, generic), 'isolated' (no connections, generic), 'anchored' (no connections, domain-aware)",
|
|
80
|
+
)
|
|
73
81
|
|
|
74
82
|
|
|
75
83
|
class GraphMetadata(BaseModel):
|
|
@@ -148,6 +156,7 @@ class Graph(TopicModel):
|
|
|
148
156
|
self.degree = self.config.degree
|
|
149
157
|
self.depth = self.config.depth
|
|
150
158
|
self.max_concurrent = self.config.max_concurrent
|
|
159
|
+
self.prompt_style = self.config.prompt_style
|
|
151
160
|
|
|
152
161
|
# Initialize LLM client
|
|
153
162
|
llm_kwargs = {}
|
|
@@ -493,6 +502,17 @@ class Graph(TopicModel):
|
|
|
493
502
|
)
|
|
494
503
|
return None
|
|
495
504
|
|
|
505
|
+
def _get_path_to_node(self, node: Node) -> list[str]:
|
|
506
|
+
"""Get the topic path from root to the given node."""
|
|
507
|
+
path = []
|
|
508
|
+
current = node
|
|
509
|
+
while current is not None:
|
|
510
|
+
path.append(current.topic)
|
|
511
|
+
# First parent is the primary parent from tree expansion;
|
|
512
|
+
# cross-connections are added later and appear after index 0
|
|
513
|
+
current = current.parents[0] if current.parents else None
|
|
514
|
+
return list(reversed(path))
|
|
515
|
+
|
|
496
516
|
async def get_subtopics_and_connections(
|
|
497
517
|
self, parent_node: Node, num_subtopics: int
|
|
498
518
|
) -> tuple[int, int]:
|
|
@@ -505,15 +525,35 @@ class Graph(TopicModel):
|
|
|
505
525
|
Returns:
|
|
506
526
|
A tuple of (subtopics_added, connections_added).
|
|
507
527
|
"""
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
528
|
+
# Choose prompt based on prompt_style setting
|
|
529
|
+
if self.prompt_style == "anchored":
|
|
530
|
+
# Domain-aware prompts with examples for focused generation
|
|
531
|
+
topic_path = self._get_path_to_node(parent_node)
|
|
532
|
+
domain = GraphPromptBuilder.detect_domain(self.model_system_prompt, topic_path)
|
|
533
|
+
graph_prompt = GraphPromptBuilder.build_anchored_prompt(
|
|
534
|
+
topic_path=topic_path,
|
|
535
|
+
num_subtopics=num_subtopics,
|
|
536
|
+
system_prompt=self.model_system_prompt,
|
|
537
|
+
domain=domain,
|
|
538
|
+
)
|
|
539
|
+
elif self.prompt_style == "isolated":
|
|
540
|
+
# No connections, generic prompt
|
|
541
|
+
graph_prompt = GRAPH_EXPANSION_PROMPT_NO_CONNECTIONS.replace(
|
|
542
|
+
"{{current_topic}}", parent_node.topic
|
|
543
|
+
)
|
|
544
|
+
graph_prompt = graph_prompt.replace("{{num_subtopics}}", str(num_subtopics))
|
|
545
|
+
else:
|
|
546
|
+
# default: cross-connections enabled, generic prompt
|
|
547
|
+
graph_summary = (
|
|
548
|
+
self.to_json()
|
|
549
|
+
if len(self.nodes) <= TOPIC_GRAPH_SUMMARY
|
|
550
|
+
else "Graph too large to display"
|
|
551
|
+
)
|
|
552
|
+
graph_prompt = GRAPH_EXPANSION_PROMPT.replace(
|
|
553
|
+
"{{current_graph_summary}}", graph_summary
|
|
554
|
+
)
|
|
555
|
+
graph_prompt = graph_prompt.replace("{{current_topic}}", parent_node.topic)
|
|
556
|
+
graph_prompt = graph_prompt.replace("{{num_subtopics}}", str(num_subtopics))
|
|
517
557
|
|
|
518
558
|
response = await self._generate_subtopics_with_retry(graph_prompt, parent_node)
|
|
519
559
|
if response is None:
|
|
@@ -19,8 +19,8 @@ except (ImportError, importlib.metadata.PackageNotFoundError):
|
|
|
19
19
|
|
|
20
20
|
# Initialize PostHog client
|
|
21
21
|
posthog = Posthog(
|
|
22
|
-
project_api_key="
|
|
23
|
-
host="https://
|
|
22
|
+
project_api_key="phc_JZWiTzIDNnBp6Jj6uUb0JQKuIp3dv0gkay9aU50n38h",
|
|
23
|
+
host="https://eu.i.posthog.com",
|
|
24
24
|
)
|
|
25
25
|
|
|
26
26
|
logger = logging.getLogger(__name__)
|
|
@@ -264,6 +264,142 @@ Generate a list of {{num_subtopics}} subtopics. For each subtopic, provide:
|
|
|
264
264
|
2. A "connections" list of IDs of existing topics it should connect to for creating cross-links (use empty list if no connections)
|
|
265
265
|
"""
|
|
266
266
|
|
|
267
|
+
GRAPH_EXPANSION_PROMPT_NO_CONNECTIONS = """
|
|
268
|
+
You are an expert in topic generation. Your task is to expand a topic into a set of focused subtopics.
|
|
269
|
+
|
|
270
|
+
You are expanding the topic: "{{current_topic}}"
|
|
271
|
+
|
|
272
|
+
Generate a list of {{num_subtopics}} subtopics. For each subtopic, provide:
|
|
273
|
+
1. A "topic" string - the name of the new subtopic
|
|
274
|
+
2. A "connections" list - ALWAYS use an empty list []
|
|
275
|
+
|
|
276
|
+
IMPORTANT: Do NOT create cross-connections between topics. Each subtopic should be independent and directly related only to its parent topic. Always return connections as an empty list [].
|
|
277
|
+
"""
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
class GraphPromptBuilder:
|
|
281
|
+
"""Build domain-aware prompts for graph topic expansion with anchoring examples."""
|
|
282
|
+
|
|
283
|
+
MAX_PROMPT_EXAMPLES = 3
|
|
284
|
+
|
|
285
|
+
SECURITY_KEYWORDS = frozenset(
|
|
286
|
+
{
|
|
287
|
+
"security",
|
|
288
|
+
"attack",
|
|
289
|
+
"credential",
|
|
290
|
+
"exfiltration",
|
|
291
|
+
"injection",
|
|
292
|
+
"malicious",
|
|
293
|
+
"adversarial",
|
|
294
|
+
"threat",
|
|
295
|
+
}
|
|
296
|
+
)
|
|
297
|
+
|
|
298
|
+
# Domain-specific expansion examples - formatted to match GraphSubtopics schema
|
|
299
|
+
EXAMPLES = {
|
|
300
|
+
"security": [
|
|
301
|
+
{
|
|
302
|
+
"path": ["Security Threats", "Credential Access"],
|
|
303
|
+
"subtopics": [
|
|
304
|
+
{"topic": "reading .env files", "connections": []},
|
|
305
|
+
{"topic": "extracting API keys", "connections": []},
|
|
306
|
+
{"topic": "accessing SSH keys", "connections": []},
|
|
307
|
+
{"topic": "dumping AWS credentials", "connections": []},
|
|
308
|
+
{"topic": "stealing database passwords", "connections": []},
|
|
309
|
+
],
|
|
310
|
+
},
|
|
311
|
+
{
|
|
312
|
+
"path": ["Security Threats", "Data Exfiltration"],
|
|
313
|
+
"subtopics": [
|
|
314
|
+
{"topic": "sending to webhooks", "connections": []},
|
|
315
|
+
{"topic": "encoding in base64", "connections": []},
|
|
316
|
+
{"topic": "uploading to external URLs", "connections": []},
|
|
317
|
+
{"topic": "email forwarding", "connections": []},
|
|
318
|
+
{"topic": "DNS tunneling", "connections": []},
|
|
319
|
+
],
|
|
320
|
+
},
|
|
321
|
+
],
|
|
322
|
+
"technical": [
|
|
323
|
+
{
|
|
324
|
+
"path": ["Programming", "Python"],
|
|
325
|
+
"subtopics": [
|
|
326
|
+
{"topic": "pandas", "connections": []},
|
|
327
|
+
{"topic": "flask", "connections": []},
|
|
328
|
+
{"topic": "pytest", "connections": []},
|
|
329
|
+
{"topic": "asyncio", "connections": []},
|
|
330
|
+
{"topic": "django", "connections": []},
|
|
331
|
+
],
|
|
332
|
+
},
|
|
333
|
+
{
|
|
334
|
+
"path": ["Infrastructure", "Kubernetes"],
|
|
335
|
+
"subtopics": [
|
|
336
|
+
{"topic": "pods", "connections": []},
|
|
337
|
+
{"topic": "deployments", "connections": []},
|
|
338
|
+
{"topic": "services", "connections": []},
|
|
339
|
+
{"topic": "ingress", "connections": []},
|
|
340
|
+
{"topic": "helm charts", "connections": []},
|
|
341
|
+
],
|
|
342
|
+
},
|
|
343
|
+
],
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
@classmethod
|
|
347
|
+
def build_anchored_prompt(
|
|
348
|
+
cls,
|
|
349
|
+
topic_path: list[str],
|
|
350
|
+
num_subtopics: int,
|
|
351
|
+
system_prompt: str = "",
|
|
352
|
+
domain: str = "technical",
|
|
353
|
+
) -> str:
|
|
354
|
+
"""Build a domain-anchored prompt for graph expansion.
|
|
355
|
+
|
|
356
|
+
Returns a prompt that produces focused, on-topic subtopics by providing
|
|
357
|
+
domain-specific examples and the full topic path context.
|
|
358
|
+
"""
|
|
359
|
+
path_str = " -> ".join(f'"{topic}"' for topic in topic_path)
|
|
360
|
+
examples = cls._format_examples(cls.EXAMPLES.get(domain, cls.EXAMPLES["technical"]))
|
|
361
|
+
|
|
362
|
+
return f"""Generate {num_subtopics} subtopics for training data organization.
|
|
363
|
+
|
|
364
|
+
Task: Create diverse but related subtopics that expand on the given topic path.
|
|
365
|
+
|
|
366
|
+
Examples:
|
|
367
|
+
{examples}
|
|
368
|
+
|
|
369
|
+
Context: {system_prompt}
|
|
370
|
+
|
|
371
|
+
Topic path: {path_str}
|
|
372
|
+
|
|
373
|
+
Generate {num_subtopics} subtopics. For each subtopic, provide:
|
|
374
|
+
1. A "topic" string - a specific, concrete subtopic directly related to the parent
|
|
375
|
+
2. A "connections" list - ALWAYS use an empty list []
|
|
376
|
+
|
|
377
|
+
Return focused subtopics that stay on-topic with the path above."""
|
|
378
|
+
|
|
379
|
+
@classmethod
|
|
380
|
+
def _format_examples(cls, examples: list) -> str:
|
|
381
|
+
"""Format examples for inclusion in prompt."""
|
|
382
|
+
formatted = []
|
|
383
|
+
for ex in examples[: cls.MAX_PROMPT_EXAMPLES]:
|
|
384
|
+
path_str = " -> ".join(f'"{topic}"' for topic in ex["path"])
|
|
385
|
+
subtopics_str = str(ex["subtopics"])
|
|
386
|
+
formatted.append(f"Path: {path_str}\nSubtopics: {subtopics_str}")
|
|
387
|
+
return "\n\n".join(formatted)
|
|
388
|
+
|
|
389
|
+
@classmethod
|
|
390
|
+
def detect_domain(cls, system_prompt: str, topic_path: list[str]) -> str:
|
|
391
|
+
"""Detect the appropriate domain for prompt examples based on context.
|
|
392
|
+
|
|
393
|
+
Returns 'security' or 'technical' based on keywords in the system prompt
|
|
394
|
+
and topic path. Defaults to 'technical' if no security keywords found.
|
|
395
|
+
"""
|
|
396
|
+
combined_text = f"{system_prompt} {' '.join(topic_path)}".lower()
|
|
397
|
+
|
|
398
|
+
if any(word in combined_text for word in cls.SECURITY_KEYWORDS):
|
|
399
|
+
return "security"
|
|
400
|
+
return "technical"
|
|
401
|
+
|
|
402
|
+
|
|
267
403
|
# Chain of Thought prompts for reasoning-based dataset generation
|
|
268
404
|
FREETEXT_COT_PROMPT = """Generate a reasoning problem that requires analytical thinking to solve.
|
|
269
405
|
|
|
@@ -136,7 +136,9 @@ class MCPInputSchemaProperty(BaseModel):
|
|
|
136
136
|
|
|
137
137
|
model_config = {"extra": "allow"}
|
|
138
138
|
|
|
139
|
-
type: str | list[str] = Field(
|
|
139
|
+
type: str | list[str] = Field(
|
|
140
|
+
default="string", description="JSON Schema type (string or array for nullable)"
|
|
141
|
+
)
|
|
140
142
|
description: str = Field(default="", description="Property description")
|
|
141
143
|
default: Any | None = Field(default=None, description="Default value")
|
|
142
144
|
|