fortresscodeai 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.
- backend/Modules/autobuilder_orchestration/backend/models/autobuilder.py +28 -0
- backend/Modules/autobuilder_orchestration/backend/pipelines/autobuilder_pipeline.py +0 -0
- backend/Modules/autobuilder_orchestration/backend/services/autobuilder_service.py +76 -0
- backend/Modules/dispute_resolution_system/backend/models/audit.py +21 -0
- backend/Modules/dispute_resolution_system/backend/models/autobuilder.py +0 -0
- backend/Modules/dispute_resolution_system/backend/models/disputes.py +0 -0
- backend/Modules/dispute_resolution_system/backend/models/hitl.py +0 -0
- backend/Modules/dispute_resolution_system/backend/models/policy.py +0 -0
- backend/Modules/dispute_resolution_system/backend/pipelines/governance_pipeline.py +32 -0
- backend/Modules/dispute_resolution_system/backend/services/audit_service.py +46 -0
- backend/Modules/dispute_resolution_system/backend/services/autobuilder_service.py +0 -0
- backend/Modules/dispute_resolution_system/backend/services/disputes_service.py +65 -0
- backend/Modules/dispute_resolution_system/backend/services/hitl_service.py +0 -0
- backend/Modules/dispute_resolution_system/backend/services/policy_engine.py +0 -0
- backend/__init__.py +0 -0
- backend/app/__init__.py +0 -0
- backend/app/agent_runtime.py +274 -0
- backend/app/api/__init__.py +17 -0
- backend/app/api/audit.py +0 -0
- backend/app/api/governance.py +14 -0
- backend/app/api/hitl.py +0 -0
- backend/app/api/main.py +18 -0
- backend/app/api/policies.py +54 -0
- backend/app/api/routes_devtools.py +32 -0
- backend/app/api/routes_health.py +18 -0
- backend/app/api/routes_metrics.py +40 -0
- backend/app/api/routes_plugins.py +27 -0
- backend/app/api/routes_workflows.py +109 -0
- backend/app/api/security.py +0 -0
- backend/app/api/workers/__init__.py +0 -0
- backend/app/api/workers/events.py +33 -0
- backend/app/api/workers/models.py +37 -0
- backend/app/api/workers/routes.py +20 -0
- backend/app/api/workers/service.py +99 -0
- backend/app/celery_app.py +110 -0
- backend/app/create_app.py +215 -0
- backend/app/db/__init__.py +30 -0
- backend/app/db/in_memory.py +0 -0
- backend/app/db/models.py +54 -0
- backend/app/dependencies.py +55 -0
- backend/app/governance/policies/__init__.py +0 -0
- backend/app/governance/policies/actions.py +39 -0
- backend/app/governance/policies/conditions.py +90 -0
- backend/app/governance/policies/dsl.py +30 -0
- backend/app/governance/policies/evaluator.py +30 -0
- backend/app/governance/policies/loader.py +29 -0
- backend/app/governance/policies/registry.py +41 -0
- backend/app/governance/policies/schema.py +71 -0
- backend/app/governance/policies/versioning.py +35 -0
- backend/app/hitl_queue.py +34 -0
- backend/app/llm/__init__.py +0 -0
- backend/app/llm/client_base.py +0 -0
- backend/app/llm/client_fake.py +0 -0
- backend/app/llm/client_openai.py +0 -0
- backend/app/middleware/security.py +24 -0
- backend/app/models/__init__.py +0 -0
- backend/app/models/task.py +130 -0
- backend/app/orchestrator/__init__.py +33 -0
- backend/app/orchestrator/audit_trail.py +13 -0
- backend/app/orchestrator/execution_backend.py +25 -0
- backend/app/orchestrator/hitl_manager.py +34 -0
- backend/app/orchestrator/orchestrator.py +147 -0
- backend/app/orchestrator/orchestrator_tasks.py +347 -0
- backend/app/orchestrator/policy_engine.py +17 -0
- backend/app/orchestrator/routes.py +127 -0
- backend/app/orchestrator/secrets_manager.py +7 -0
- backend/app/orchestrator/security_events.py +12 -0
- backend/app/orchestrator/workflow_models.py +74 -0
- backend/app/plugin_loader.py +42 -0
- backend/app/plugin_registry.py +26 -0
- backend/app/plugins/__init__.py +0 -0
- backend/app/plugins/example_plugin.py +15 -0
- backend/app/policy_engine.py +33 -0
- backend/app/security_events.py +74 -0
- backend/app/storage.py +202 -0
- backend/app/tools.py +246 -0
- backend/app/types.py +58 -0
- backend/app/ui/__init__.py +0 -0
- backend/app/utils/__init__.py +0 -0
- backend/app/utils/logging.py +0 -0
- backend/app/utils/security.py +0 -0
- backend/app/workers/__init__.py +0 -0
- backend/app/workers/job_queue.py +39 -0
- backend/app/workers/prompt_renderer.py +57 -0
- backend/app/workers/runtime.py +39 -0
- backend/app/workers/runtimes/__init__.py +0 -0
- backend/app/workers/runtimes/base_runtime.py +28 -0
- backend/app/workers/runtimes/codegen.py +21 -0
- backend/app/workers/runtimes/executor.py +47 -0
- backend/app/workers/runtimes/interpreter.py +31 -0
- backend/app/workers/runtimes/researcher.py +20 -0
- backend/app/workers/runtimes/validator.py +44 -0
- backend/app/workers/start.py +17 -0
- backend/app/workers/worker.py +91 -0
- backend/app/workers/worker_registry.py +142 -0
- backend/app/workflow_engine.py +244 -0
- backend/app/workflow_orchestrator.py +44 -0
- backend/cli/__init__.py +0 -0
- backend/cli/commands/__init__.py +0 -0
- backend/cli/commands/create.py +100 -0
- backend/cli/commands/dev.py +53 -0
- backend/cli/commands/doctor.py +39 -0
- backend/cli/commands/down.py +40 -0
- backend/cli/commands/inspect.py +37 -0
- backend/cli/commands/logs.py +16 -0
- backend/cli/commands/replay.py +32 -0
- backend/cli/commands/sandbox.py +51 -0
- backend/cli/commands/setup.py +138 -0
- backend/cli/commands/status.py +17 -0
- backend/cli/commands/up.py +41 -0
- backend/cli/main.py +43 -0
- backend/cli/runtime/__init__.py +0 -0
- backend/cli/runtime/api_launcher.py +123 -0
- backend/cli/runtime/paths.py +59 -0
- backend/cli/runtime/storage_init.py +25 -0
- backend/cli/runtime/worker_launcher.py +82 -0
- backend/db.py +17 -0
- backend/devtools/__init__.py +0 -0
- backend/devtools/ai/__init__.py +0 -0
- backend/devtools/ai/ai_fix.py +106 -0
- backend/devtools/api/__init__.py +0 -0
- backend/devtools/api/agents_api.py +55 -0
- backend/devtools/api/policy_api.py +122 -0
- backend/devtools/api/security_api.py +25 -0
- backend/devtools/api/teams_api.py +58 -0
- backend/devtools/dashboards/__init__.py +0 -0
- backend/devtools/dashboards/agents_panel.py +0 -0
- backend/devtools/dashboards/dev_dashboard.py +0 -0
- backend/devtools/dashboards/diagnostics_panel.py +0 -0
- backend/devtools/dashboards/exec_dashboard.py +180 -0
- backend/devtools/dashboards/performance_panel.py +0 -0
- backend/devtools/dashboards/policies_panel.py +0 -0
- backend/devtools/dashboards/security_panel.py +0 -0
- backend/devtools/dashboards/workflows_panel.py +0 -0
- backend/devtools/diagnostics/__init__.py +0 -0
- backend/devtools/diagnostics/health.py +37 -0
- backend/devtools/diagnostics/logs.py +47 -0
- backend/devtools/diagnostics/metrics.py +20 -0
- backend/devtools/performance/__init__.py +0 -0
- backend/devtools/performance/benchmarks.py +157 -0
- backend/devtools/realtime/__init__.py +0 -0
- backend/devtools/realtime/websocket_bus.py +42 -0
- backend/devtools/security/__init__.py +0 -0
- backend/devtools/security/auth.py +41 -0
- backend/devtools/security/security.py +14 -0
- backend/fortress_cli.py +3 -0
- backend/main.py +32 -0
- backend/models.py +0 -0
- backend/platform/__init__.py +0 -0
- backend/platform/audit/__init__.py +0 -0
- backend/platform/audit/logger.py +210 -0
- backend/platform/audit/logs.py +37 -0
- backend/platform/audit/violations.py +19 -0
- backend/platform/autobuilder/__init__.py +5 -0
- backend/platform/autobuilder/lead/__init__.py +0 -0
- backend/platform/autobuilder/lead/audit.py +28 -0
- backend/platform/autobuilder/lead/enrichment.py +59 -0
- backend/platform/autobuilder/lead/insights.py +81 -0
- backend/platform/autobuilder/lead/normalization.py +53 -0
- backend/platform/autobuilder/lead/outreach.py +33 -0
- backend/platform/autobuilder/lead/renderer.py +95 -0
- backend/platform/autobuilder/lead/service.py +30 -0
- backend/platform/autobuilder/shared/__init__.py +0 -0
- backend/platform/autobuilder/shared/utils.py +16 -0
- backend/platform/core/__init__.py +0 -0
- backend/platform/core/config.py +13 -0
- backend/platform/core/logging.py +46 -0
- backend/platform/core/utils.py +0 -0
- backend/platform/evidence/__init__.py +0 -0
- backend/platform/evidence/evidence_builder.py +41 -0
- backend/platform/evidence/evidence_export.py +0 -0
- backend/platform/evidence/evidence_models.py +13 -0
- backend/platform/governance/__init__.py +0 -0
- backend/platform/governance/policy_coverage.py +15 -0
- backend/platform/governance/policy_diff.py +22 -0
- backend/platform/governance/policy_drift.py +12 -0
- backend/platform/governance/policy_engine.py +59 -0
- backend/platform/governance/scanner.py +241 -0
- backend/platform/models_repo_policy.py +20 -0
- backend/platform/risk/__init__.py +0 -0
- backend/platform/risk/risk_map.py +19 -0
- backend/platform/risk/risk_matrix.py +35 -0
- backend/platform/risk/risk_rules.py +15 -0
- backend/platform/safety_layer/__init__.py +0 -0
- backend/platform/safety_layer/policy_engine/__init__.py +4 -0
- backend/platform/safety_layer/policy_engine/engine.py +48 -0
- backend/platform/safety_layer/policy_engine/rules.py +28 -0
- backend/platform/safety_layer/prompt_defence/__init__.py +2 -0
- backend/platform/safety_layer/prompt_defence/context_leak_detector.py +33 -0
- backend/platform/safety_layer/prompt_defence/prompt_defence_middleware.py +47 -0
- backend/platform/safety_layer/prompt_defence/sanitizer.py +27 -0
- backend/platform/safety_layer/trust_protocols/__init__.py +1 -0
- backend/platform/safety_layer/vuln_scanner/__init__.py +3 -0
- backend/platform/safety_layer/vuln_scanner/license_checker.py +7 -0
- backend/platform/safety_layer/vuln_scanner/semantic_analyzer.py +18 -0
- backend/platform/safety_layer/vuln_scanner/vuln_scanner.py +18 -0
- backend/platform/sbom/__init__.py +0 -0
- backend/platform/sbom/dependency_rules.py +23 -0
- backend/platform/sbom/integrity.py +32 -0
- backend/platform/sbom/parsers.py +37 -0
- backend/platform/security/__init__.py +0 -0
- backend/platform/security/security.py +27 -0
- backend/platform/threat_modeling/__init__.py +0 -0
- backend/platform/threat_modeling/agent_graph_builder.py +21 -0
- backend/platform/threat_modeling/threat_model_generator.py +26 -0
- backend/platform/traceability/__init__.py +0 -0
- backend/platform/traceability/blackbox_logger.py +59 -0
- backend/platform/traceability/replay_engine.py +67 -0
- backend/platform/trust/__init__.py +0 -0
- backend/platform/trust/trust_signals.py +35 -0
- backend/platform/trust/trust_timeline.py +20 -0
- backend/src/__init__.py +0 -0
- backend/src/api/__init__.py +19 -0
- backend/src/api/alerts.py +11 -0
- backend/src/api/analytics.py +25 -0
- backend/src/api/audit.py +27 -0
- backend/src/api/billing.py +39 -0
- backend/src/api/onboarding.py +17 -0
- backend/src/api/repo_policy.py +78 -0
- backend/src/api/routes/agents.py +38 -0
- backend/src/api/routes/assistant.py +114 -0
- backend/src/api/routes/audit.py +20 -0
- backend/src/api/routes/auth.py +41 -0
- backend/src/api/routes/dev.py +32 -0
- backend/src/api/routes/models.py +48 -0
- backend/src/api/routes/policies.py +34 -0
- backend/src/api/routes/proposals.py +76 -0
- backend/src/api/routes/repos.py +32 -0
- backend/src/api/routes/tasks.py +44 -0
- backend/src/api/settings.py +37 -0
- backend/src/api/team.py +63 -0
- backend/src/application/Policies/compliance/rules_service.py +63 -0
- backend/src/audit/__init__.py +0 -0
- backend/src/audit/logger.py +51 -0
- backend/src/cli/security_gate.py +49 -0
- backend/src/config.py +12 -0
- backend/src/domain/__init__.py +0 -0
- backend/src/domain/agents/__init__.py +0 -0
- backend/src/domain/agents/base/__init__.py +0 -0
- backend/src/domain/agents/base/base.py +25 -0
- backend/src/domain/agents/base/behavior.py +31 -0
- backend/src/domain/agents/base/governance.py +36 -0
- backend/src/domain/agents/base/performance.py +12 -0
- backend/src/domain/agents/client/__init__.py +0 -0
- backend/src/domain/agents/client/client.py +41 -0
- backend/src/domain/agents/compliance/__init__.py +0 -0
- backend/src/domain/agents/compliance/compliance_agent.py +70 -0
- backend/src/domain/agents/compliance/license_compliance_agent.py +78 -0
- backend/src/domain/agents/compliance/policy_enforcer_agent.py +52 -0
- backend/src/domain/agents/compliance/regulatory_rules_agent.py +77 -0
- backend/src/domain/agents/implementers/__init__.py +0 -0
- backend/src/domain/agents/implementers/architectural_agent.py +57 -0
- backend/src/domain/agents/implementers/autobuilder.py +42 -0
- backend/src/domain/agents/implementers/code_assistant.py +39 -0
- backend/src/domain/agents/implementers/code_refractor_agent.py +49 -0
- backend/src/domain/agents/implementers/implementer_agent.py +76 -0
- backend/src/domain/agents/implementers/repo_architect.py +38 -0
- backend/src/domain/agents/orchestration/__init__.py +0 -0
- backend/src/domain/agents/orchestration/chains.py +17 -0
- backend/src/domain/agents/orchestration/orchestrator.py +105 -0
- backend/src/domain/agents/orchestration/orchestrator_agent.py +39 -0
- backend/src/domain/agents/orchestration/registry.py +26 -0
- backend/src/domain/agents/orchestration/router.py +50 -0
- backend/src/domain/agents/reviewers/__init__.py +0 -0
- backend/src/domain/agents/reviewers/internal_standards_agent.py +66 -0
- backend/src/domain/agents/reviewers/reviewer_agent.py +56 -0
- backend/src/domain/agents/reviewers/style_agent.py +54 -0
- backend/src/domain/agents/security/__init__.py +0 -0
- backend/src/domain/agents/security/governance_agent.py +53 -0
- backend/src/domain/agents/security/security_agent.py +89 -0
- backend/src/domain/agents/security/security_review_agent.py +109 -0
- backend/src/domain/alerts/__init__.py +0 -0
- backend/src/domain/alerts/api.py +11 -0
- backend/src/domain/core/__init__agents.py +18 -0
- backend/src/domain/core/agent_config.py +40 -0
- backend/src/domain/core/config.py +28 -0
- backend/src/domain/core/db.py +29 -0
- backend/src/domain/core/logging.py +76 -0
- backend/src/domain/core/models.py +74 -0
- backend/src/domain/dev/__init__.py +0 -0
- backend/src/domain/dev/agents_api.py +55 -0
- backend/src/domain/dev/ai_fix.py +106 -0
- backend/src/domain/dev/auth.py +41 -0
- backend/src/domain/dev/benchmarks.py +157 -0
- backend/src/domain/dev/health.py +37 -0
- backend/src/domain/dev/logs.py +47 -0
- backend/src/domain/dev/metrics.py +20 -0
- backend/src/domain/dev/policy_api.py +122 -0
- backend/src/domain/dev/security.py +14 -0
- backend/src/domain/dev/security_api.py +25 -0
- backend/src/domain/dev/teams_api.py +58 -0
- backend/src/domain/dev/websocket_bus.py +42 -0
- backend/src/domain/internal_automations/Autobuilder_orchestration/__init__.py +0 -0
- backend/src/domain/internal_automations/Autobuilder_orchestration/app/__init__.py +0 -0
- backend/src/domain/internal_automations/Autobuilder_orchestration/app/core/config.py +11 -0
- backend/src/domain/internal_automations/Autobuilder_orchestration/app/core/exceptions.py +9 -0
- backend/src/domain/internal_automations/Autobuilder_orchestration/app/core/logging.py +26 -0
- backend/src/domain/internal_automations/Autobuilder_orchestration/app/core/middleware.py +0 -0
- backend/src/domain/internal_automations/Autobuilder_orchestration/app/core/models.py +41 -0
- backend/src/domain/internal_automations/Autobuilder_orchestration/app/domain/models.py +50 -0
- backend/src/domain/internal_automations/Autobuilder_orchestration/app/main.py +13 -0
- backend/src/domain/internal_automations/Autobuilder_orchestration/app/routes/workflows.py +0 -0
- backend/src/domain/internal_automations/Autobuilder_orchestration/app/services/__init__.py +0 -0
- backend/src/domain/internal_automations/Autobuilder_orchestration/app/services/audit.py +0 -0
- backend/src/domain/internal_automations/Autobuilder_orchestration/app/services/executor.py +23 -0
- backend/src/domain/internal_automations/Autobuilder_orchestration/app/services/hitl.py +22 -0
- backend/src/domain/internal_automations/Autobuilder_orchestration/app/services/orchestrator.py +49 -0
- backend/src/domain/internal_automations/Autobuilder_orchestration/app/services/policy.py +13 -0
- backend/src/domain/internal_automations/Autobuilder_orchestration/autobuilder_orchestration.py +406 -0
- backend/src/domain/internal_automations/__init__.py +0 -0
- backend/src/domain/models/__init__.py +5 -0
- backend/src/domain/models/agents.py +20 -0
- backend/src/domain/models/audit.py +16 -0
- backend/src/domain/models/audit_event.py +31 -0
- backend/src/domain/models/base.py +3 -0
- backend/src/domain/models/disputes.py +24 -0
- backend/src/domain/models/governance.py +16 -0
- backend/src/domain/models/hitl.py +25 -0
- backend/src/domain/models/policy.py +28 -0
- backend/src/domain/models/risk.py +15 -0
- backend/src/domain/models/sbom.py +13 -0
- backend/src/domain/models/shared.py +17 -0
- backend/src/domain/models/trust.py +14 -0
- backend/src/domain/models/user.py +11 -0
- backend/src/domain/scoring/__init__.py +0 -0
- backend/src/domain/scoring/governance_scoring.py +27 -0
- backend/src/domain/scoring/risk_scoring.py +25 -0
- backend/src/domain/scoring/supply_chain_scoring.py +22 -0
- backend/src/domain/scoring/trust_scoring.py +24 -0
- backend/src/domain/services/__init__.py +0 -0
- backend/src/domain/services/agent_service.py +32 -0
- backend/src/domain/services/agents/__init__.py +0 -0
- backend/src/domain/services/agents/agent_qa_runner.py +12 -0
- backend/src/domain/services/agents/architectural_agent.py +57 -0
- backend/src/domain/services/agents/base.py +25 -0
- backend/src/domain/services/agents/client.py +41 -0
- backend/src/domain/services/agents/code_refractor_agent.py +49 -0
- backend/src/domain/services/agents/compliance_agent.py +70 -0
- backend/src/domain/services/agents/governance.py +36 -0
- backend/src/domain/services/agents/implementer_agent.py +76 -0
- backend/src/domain/services/agents/internal_standards_agent.py +66 -0
- backend/src/domain/services/agents/license_compliance_agent.py +78 -0
- backend/src/domain/services/agents/orchestrator.py +104 -0
- backend/src/domain/services/agents/orchestrator_agent.py +39 -0
- backend/src/domain/services/agents/policy_enforcer_agent.py +52 -0
- backend/src/domain/services/agents/registry.py +26 -0
- backend/src/domain/services/agents/regulatory_rules_agent.py +77 -0
- backend/src/domain/services/agents/reviewer_agent.py +56 -0
- backend/src/domain/services/agents/security_agent.py +89 -0
- backend/src/domain/services/agents/security_review_agent.py +109 -0
- backend/src/domain/services/agents/style_agent.py +54 -0
- backend/src/domain/services/alerts.py +99 -0
- backend/src/domain/services/analytics.py +62 -0
- backend/src/domain/services/audit.py +113 -0
- backend/src/domain/services/billing.py +88 -0
- backend/src/domain/services/codegraph/__init__.py +0 -0
- backend/src/domain/services/codegraph/graph_builder.py +55 -0
- backend/src/domain/services/codegraph/search.py +163 -0
- backend/src/domain/services/governance_service.py +32 -0
- backend/src/domain/services/hitl_service.py +62 -0
- backend/src/domain/services/ingestion/__init__.py +0 -0
- backend/src/domain/services/ingestion/file_system_ingestion.py +47 -0
- backend/src/domain/services/ingestion/git_ingestion.py +74 -0
- backend/src/domain/services/llm/__init__.py +0 -0
- backend/src/domain/services/llm/ollama_client.py +122 -0
- backend/src/domain/services/onboarding.py +78 -0
- backend/src/domain/services/policy/__init__.py +0 -0
- backend/src/domain/services/policy/dsl.py +85 -0
- backend/src/domain/services/policy/evaluator.py +76 -0
- backend/src/domain/services/policy/policy_engine.py +36 -0
- backend/src/domain/services/proposals/__init__.py +0 -0
- backend/src/domain/services/proposals/generator.py +108 -0
- backend/src/domain/services/proposals/github_integration.py +53 -0
- backend/src/domain/services/rbac.py +33 -0
- backend/src/domain/services/risk_service.py +37 -0
- backend/src/domain/services/rules_service.py +63 -0
- backend/src/domain/services/sbom_service.py +28 -0
- backend/src/domain/services/trust_service.py +27 -0
- backend/src/domain/services/workspace_service.py +36 -0
- backend/src/domain/teams/__init__.py +0 -0
- backend/src/domain/teams/architecture_review_team.py +50 -0
- backend/src/domain/teams/audit_team.py +52 -0
- backend/src/domain/teams/base_team.py +13 -0
- backend/src/domain/teams/compliance_team.py +123 -0
- backend/src/domain/teams/cost_optimization_team.py +59 -0
- backend/src/domain/teams/dx_team.py +49 -0
- backend/src/domain/teams/governance_team.py +125 -0
- backend/src/domain/teams/incident_response_team.py +52 -0
- backend/src/domain/teams/observability_team.py +52 -0
- backend/src/domain/teams/orchestrator_full.py +118 -0
- backend/src/domain/teams/policy_intelligence_team.py +55 -0
- backend/src/domain/teams/privacy_team.py +51 -0
- backend/src/domain/teams/risk_threat_team.py +52 -0
- backend/src/domain/teams/schemas.py +51 -0
- backend/src/domain/teams/security_team.py +96 -0
- backend/src/domain/teams/supply_chain_team.py +52 -0
- backend/src/domain/teams/teams_full_api.py +51 -0
- backend/src/domain/workers/__init__.py +0 -0
- backend/src/domain/workers/anomaly_worker.py +36 -0
- backend/src/domain/workers/models.py +0 -0
- backend/src/domain/workers/models_settings.py +10 -0
- backend/src/extensions/__init__.py +0 -0
- backend/src/extensions/api/__init__.py +19 -0
- backend/src/extensions/api/analytics.py +25 -0
- backend/src/extensions/api/audit.py +27 -0
- backend/src/extensions/api/autobuild_lead.py +39 -0
- backend/src/extensions/api/billing.py +39 -0
- backend/src/extensions/api/onboarding.py +17 -0
- backend/src/extensions/api/repo_policy.py +72 -0
- backend/src/extensions/api/routes/agents.py +30 -0
- backend/src/extensions/api/routes/assistant.py +114 -0
- backend/src/extensions/api/routes/audit.py +25 -0
- backend/src/extensions/api/routes/auth.py +41 -0
- backend/src/extensions/api/routes/dev.py +32 -0
- backend/src/extensions/api/routes/governance.py +35 -0
- backend/src/extensions/api/routes/models.py +48 -0
- backend/src/extensions/api/routes/policies.py +35 -0
- backend/src/extensions/api/routes/proposals.py +77 -0
- backend/src/extensions/api/routes/repos.py +33 -0
- backend/src/extensions/api/routes/risk.py +25 -0
- backend/src/extensions/api/routes/sbom.py +20 -0
- backend/src/extensions/api/routes/tasks.py +46 -0
- backend/src/extensions/api/routes/trust.py +20 -0
- backend/src/extensions/api/routes/workspace.py +13 -0
- backend/src/extensions/api/settings.py +38 -0
- backend/src/extensions/api/team.py +65 -0
- backend/src/extensions/dev/__init__.py +0 -0
- backend/src/extensions/middleware/__init__.py +0 -0
- backend/src/extensions/middleware/audit_middleware.py +40 -0
- backend/src/extensions/middleware/audit_route.py +230 -0
- backend/src/extensions/middleware/auth.py +50 -0
- backend/src/governance/audit_ledger/__init__.py +0 -0
- backend/src/governance/audit_ledger/exporter.py +25 -0
- backend/src/index.py +1 -0
- backend/src/main.py +44 -0
- backend/src/middleware/audit_middleware.py +40 -0
- backend/src/middleware/audit_route.py +36 -0
- backend/src/middleware/auth.py +50 -0
- backend/src/models_repo_policy.py +20 -0
- backend/src/models_settings.py +10 -0
- backend/src/prompt_defence/__init__.py +2 -0
- backend/src/prompt_defence/context_leak_detector.py +33 -0
- backend/src/prompt_defence/prompt_defence_middleware.py +47 -0
- backend/src/prompt_defence/sanitizer.py +27 -0
- backend/src/safety_layer/trust_protocols/__init__.py +1 -0
- backend/src/safety_layer/vuln_scanner/__init__.py +3 -0
- backend/src/safety_layer/vuln_scanner/license_checker.py +7 -0
- backend/src/safety_layer/vuln_scanner/scanner.py +112 -0
- backend/src/safety_layer/vuln_scanner/semantic_analyzer.py +18 -0
- backend/src/safety_layer/vuln_scanner/vuln_scanner.py +18 -0
- backend/src/security.py +27 -0
- backend/src/server.py +15 -0
- backend/src/services/alerts.py +98 -0
- backend/src/services/analytics.py +62 -0
- backend/src/services/audit.py +72 -0
- backend/src/services/billing.py +86 -0
- backend/src/services/onboarding.py +76 -0
- backend/src/services/rbac.py +33 -0
- backend/src/testing/qa_framework/test_codegraph_search.py +29 -0
- backend/src/testing/qa_framework/test_ingestion_fs.py +19 -0
- backend/src/testing/qa_framework/test_runner.py +0 -0
- backend/src/testing/qa_framework/tests/test_security.py +44 -0
- backend/src/testing/risk_scoring/scorer.py +0 -0
- backend/src/threat_modeling/agent_graph_builder.py +21 -0
- backend/src/threat_modeling/threat_model_generator.py +26 -0
- backend/src/traceability/blackbox_logger.py +59 -0
- backend/src/traceability/replay_engine.py +67 -0
- backend/src/workers/anomaly_worker.py +36 -0
- backend/storage/__init__.py +0 -0
- backend/storage/interfaces.py +0 -0
- backend/storage/model_adapter.py +29 -0
- backend/storage/model_mapping.py +17 -0
- backend/storage/provider.py +82 -0
- fortresscodeai-0.1.0.dist-info/METADATA +88 -0
- fortresscodeai-0.1.0.dist-info/RECORD +479 -0
- fortresscodeai-0.1.0.dist-info/WHEEL +5 -0
- fortresscodeai-0.1.0.dist-info/entry_points.txt +2 -0
- fortresscodeai-0.1.0.dist-info/licenses/LICENSE +19 -0
- fortresscodeai-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
from typing import Any, Dict, List, Optional
|
|
2
|
+
from pydantic import BaseModel
|
|
3
|
+
from datetime import datetime
|
|
4
|
+
from enum import Enum
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class BuildStatus(str, Enum):
|
|
8
|
+
PENDING = "pending"
|
|
9
|
+
RUNNING = "running"
|
|
10
|
+
FAILED = "failed"
|
|
11
|
+
COMPLETED = "completed"
|
|
12
|
+
BLOCKED_HITL = "blocked_hitl"
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class BuildRequest(BaseModel):
|
|
16
|
+
id: str
|
|
17
|
+
created_at: datetime
|
|
18
|
+
requested_by: str
|
|
19
|
+
blueprint: Dict[str, Any]
|
|
20
|
+
correlation_id: str
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class BuildArtifact(BaseModel):
|
|
24
|
+
id: str
|
|
25
|
+
build_id: str
|
|
26
|
+
created_at: datetime
|
|
27
|
+
artifact_type: str # e.g. "agent", "workflow", "test_suite"
|
|
28
|
+
content: Dict[str, Any]
|
|
File without changes
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
from typing import Dict, Any
|
|
2
|
+
from datetime import datetime
|
|
3
|
+
import uuid
|
|
4
|
+
|
|
5
|
+
from backend.Modules.autobuilder_orchestration.backend.models.autobuilder import BuildRequest, BuildArtifact, BuildStatus
|
|
6
|
+
from backend.models.policy import PolicyViolation
|
|
7
|
+
from backend.services.policy.policy_engine import PolicyEngine
|
|
8
|
+
from backend.services.hitl_service import HITLService
|
|
9
|
+
from backend.Modules.audit_logging_engine import AuditService
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class AutobuilderService:
|
|
14
|
+
def __init__(self, store, policy_engine: PolicyEngine, hitl: HITLService, audit: AuditService):
|
|
15
|
+
self.store = store
|
|
16
|
+
self.policy_engine = policy_engine
|
|
17
|
+
self.hitl = hitl
|
|
18
|
+
self.audit = audit
|
|
19
|
+
|
|
20
|
+
def submit_build(self, requested_by: str, blueprint: Dict[str, Any]) -> BuildRequest:
|
|
21
|
+
correlation_id = str(uuid.uuid4())
|
|
22
|
+
build_request = BuildRequest(
|
|
23
|
+
id=str(uuid.uuid4()),
|
|
24
|
+
created_at=datetime.utcnow(),
|
|
25
|
+
requested_by=requested_by,
|
|
26
|
+
blueprint=blueprint,
|
|
27
|
+
correlation_id=correlation_id,
|
|
28
|
+
)
|
|
29
|
+
self.store.save_build_request(build_request)
|
|
30
|
+
self.audit.log_event(
|
|
31
|
+
actor=requested_by,
|
|
32
|
+
action="build_submitted",
|
|
33
|
+
resource=f"build:{build_request.id}",
|
|
34
|
+
details={"blueprint": blueprint},
|
|
35
|
+
correlation_id=correlation_id,
|
|
36
|
+
)
|
|
37
|
+
return build_request
|
|
38
|
+
|
|
39
|
+
def run_build(self, build_request: BuildRequest) -> BuildArtifact:
|
|
40
|
+
context = {"blueprint": build_request.blueprint, "requested_by": build_request.requested_by}
|
|
41
|
+
violations = self.policy_engine.evaluate(context)
|
|
42
|
+
|
|
43
|
+
if any(v.severity in ("high", "critical") for v in violations):
|
|
44
|
+
# create HITL task and block
|
|
45
|
+
self.hitl.create_review_task(
|
|
46
|
+
correlation_id=build_request.correlation_id,
|
|
47
|
+
actor="autobuilder",
|
|
48
|
+
payload={"build_request_id": build_request.id, "violations": [v.dict() for v in violations]},
|
|
49
|
+
)
|
|
50
|
+
self.audit.log_event(
|
|
51
|
+
actor="autobuilder",
|
|
52
|
+
action="build_blocked_hitl",
|
|
53
|
+
resource=f"build:{build_request.id}",
|
|
54
|
+
details={"violations": [v.dict() for v in violations]},
|
|
55
|
+
correlation_id=build_request.correlation_id,
|
|
56
|
+
)
|
|
57
|
+
# you might persist status as BLOCKED_HITL here
|
|
58
|
+
raise RuntimeError("Build blocked pending human review")
|
|
59
|
+
|
|
60
|
+
# TODO: actual generation logic
|
|
61
|
+
artifact = BuildArtifact(
|
|
62
|
+
id=str(uuid.uuid4()),
|
|
63
|
+
build_id=build_request.id,
|
|
64
|
+
created_at=datetime.utcnow(),
|
|
65
|
+
artifact_type="agent",
|
|
66
|
+
content={"generated": True, "blueprint": build_request.blueprint},
|
|
67
|
+
)
|
|
68
|
+
self.store.save_build_artifact(artifact)
|
|
69
|
+
self.audit.log_event(
|
|
70
|
+
actor="autobuilder",
|
|
71
|
+
action="build_completed",
|
|
72
|
+
resource=f"build:{build_request.id}",
|
|
73
|
+
details={"artifact_id": artifact.id},
|
|
74
|
+
correlation_id=build_request.correlation_id,
|
|
75
|
+
)
|
|
76
|
+
return artifact
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from typing import Any, Dict, Optional, List
|
|
2
|
+
from pydantic import BaseModel
|
|
3
|
+
from datetime import datetime
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class AuditLogEntry(BaseModel):
|
|
7
|
+
id: str
|
|
8
|
+
timestamp: datetime
|
|
9
|
+
actor: str
|
|
10
|
+
action: str
|
|
11
|
+
resource: Optional[str] = None
|
|
12
|
+
details: Dict[str, Any]
|
|
13
|
+
correlation_id: Optional[str] = None
|
|
14
|
+
tags: List[str] = []
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class AuditBundle(BaseModel):
|
|
18
|
+
bundle_id: str
|
|
19
|
+
created_at: datetime
|
|
20
|
+
correlation_id: str
|
|
21
|
+
entries: List[AuditLogEntry]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
from typing import Dict, Any
|
|
2
|
+
|
|
3
|
+
from backend.services.audit_service import AuditService
|
|
4
|
+
from backend.services.policy.policy_engine import PolicyEngine
|
|
5
|
+
from backend.services.hitl_service import HITLService
|
|
6
|
+
from backend.Modules.dispute_resolution_system.backend.services.disputes_service import DisputesService
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class GovernancePipeline:
|
|
10
|
+
def __init__(
|
|
11
|
+
self,
|
|
12
|
+
audit: AuditService,
|
|
13
|
+
policy: PolicyEngine,
|
|
14
|
+
hitl: HITLService,
|
|
15
|
+
disputes: DisputesService,
|
|
16
|
+
):
|
|
17
|
+
self.audit = audit
|
|
18
|
+
self.policy = policy
|
|
19
|
+
self.hitl = hitl
|
|
20
|
+
self.disputes = disputes
|
|
21
|
+
|
|
22
|
+
def process_action(self, actor: str, action: str, context: Dict[str, Any], correlation_id: str):
|
|
23
|
+
self.audit.log_event(
|
|
24
|
+
actor=actor,
|
|
25
|
+
action=action,
|
|
26
|
+
details=context,
|
|
27
|
+
correlation_id=correlation_id,
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
violations = self.policy.evaluate(context)
|
|
31
|
+
# you can route violations to HITL, autobuilder, etc. here
|
|
32
|
+
return violations
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
from typing import List, Dict, Any, Optional
|
|
2
|
+
from datetime import datetime
|
|
3
|
+
import uuid
|
|
4
|
+
|
|
5
|
+
from backend.models.audit import AuditLogEntry, AuditBundle
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class AuditService:
|
|
9
|
+
def __init__(self, store):
|
|
10
|
+
self.store = store # e.g. DB adapter, message bus, etc.
|
|
11
|
+
|
|
12
|
+
def log_event(
|
|
13
|
+
self,
|
|
14
|
+
actor: str,
|
|
15
|
+
action: str,
|
|
16
|
+
resource: Optional[str] = None,
|
|
17
|
+
details: Optional[Dict[str, Any]] = None,
|
|
18
|
+
correlation_id: Optional[str] = None,
|
|
19
|
+
tags: Optional[List[str]] = None,
|
|
20
|
+
) -> AuditLogEntry:
|
|
21
|
+
entry = AuditLogEntry(
|
|
22
|
+
id=str(uuid.uuid4()),
|
|
23
|
+
timestamp=datetime.utcnow(),
|
|
24
|
+
actor=actor,
|
|
25
|
+
action=action,
|
|
26
|
+
resource=resource,
|
|
27
|
+
details=details or {},
|
|
28
|
+
correlation_id=correlation_id,
|
|
29
|
+
tags=tags or [],
|
|
30
|
+
)
|
|
31
|
+
self.store.save_audit_entry(entry)
|
|
32
|
+
return entry
|
|
33
|
+
|
|
34
|
+
def get_entries_by_correlation(self, correlation_id: str) -> List[AuditLogEntry]:
|
|
35
|
+
return self.store.get_entries_by_correlation(correlation_id)
|
|
36
|
+
|
|
37
|
+
def create_bundle(self, correlation_id: str) -> AuditBundle:
|
|
38
|
+
entries = self.get_entries_by_correlation(correlation_id)
|
|
39
|
+
bundle = AuditBundle(
|
|
40
|
+
bundle_id=str(uuid.uuid4()),
|
|
41
|
+
created_at=datetime.utcnow(),
|
|
42
|
+
correlation_id=correlation_id,
|
|
43
|
+
entries=entries,
|
|
44
|
+
)
|
|
45
|
+
self.store.save_audit_bundle(bundle)
|
|
46
|
+
return bundle
|
|
File without changes
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
from datetime import datetime
|
|
3
|
+
import uuid
|
|
4
|
+
|
|
5
|
+
from backend.models.disputes import DisputeCase, DisputeStatus
|
|
6
|
+
from backend.Modules.audit_logging_engine import AuditService
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class DisputesService:
|
|
10
|
+
def __init__(self, store, audit: AuditService):
|
|
11
|
+
self.store = store
|
|
12
|
+
self.audit = audit
|
|
13
|
+
|
|
14
|
+
def open_dispute(
|
|
15
|
+
self,
|
|
16
|
+
opened_by: str,
|
|
17
|
+
correlation_id: str,
|
|
18
|
+
subject: str,
|
|
19
|
+
description: str,
|
|
20
|
+
) -> DisputeCase:
|
|
21
|
+
case = DisputeCase(
|
|
22
|
+
id=str(uuid.uuid4()),
|
|
23
|
+
created_at=datetime.utcnow(),
|
|
24
|
+
opened_by=opened_by,
|
|
25
|
+
correlation_id=correlation_id,
|
|
26
|
+
subject=subject,
|
|
27
|
+
description=description,
|
|
28
|
+
)
|
|
29
|
+
self.store.save_dispute_case(case)
|
|
30
|
+
self.audit.log_event(
|
|
31
|
+
actor=opened_by,
|
|
32
|
+
action="dispute_opened",
|
|
33
|
+
resource=f"dispute:{case.id}",
|
|
34
|
+
details={"subject": subject},
|
|
35
|
+
correlation_id=correlation_id,
|
|
36
|
+
)
|
|
37
|
+
return case
|
|
38
|
+
|
|
39
|
+
def attach_evidence_bundle(self, case_id: str, bundle_id: str) -> DisputeCase:
|
|
40
|
+
case = self.store.get_dispute_case(case_id)
|
|
41
|
+
case.evidence_bundle_id = bundle_id
|
|
42
|
+
self.store.update_dispute_case(case)
|
|
43
|
+
self.audit.log_event(
|
|
44
|
+
actor="system",
|
|
45
|
+
action="dispute_evidence_attached",
|
|
46
|
+
resource=f"dispute:{case.id}",
|
|
47
|
+
details={"bundle_id": bundle_id},
|
|
48
|
+
correlation_id=case.correlation_id,
|
|
49
|
+
)
|
|
50
|
+
return case
|
|
51
|
+
|
|
52
|
+
def resolve_dispute(self, case_id: str, resolution: str) -> DisputeCase:
|
|
53
|
+
case = self.store.get_dispute_case(case_id)
|
|
54
|
+
case.status = DisputeStatus.RESOLVED
|
|
55
|
+
case.resolution = resolution
|
|
56
|
+
case.resolved_at = datetime.utcnow()
|
|
57
|
+
self.store.update_dispute_case(case)
|
|
58
|
+
self.audit.log_event(
|
|
59
|
+
actor="system",
|
|
60
|
+
action="dispute_resolved",
|
|
61
|
+
resource=f"dispute:{case.id}",
|
|
62
|
+
details={"resolution": resolution},
|
|
63
|
+
correlation_id=case.correlation_id,
|
|
64
|
+
)
|
|
65
|
+
return case
|
|
File without changes
|
|
File without changes
|
backend/__init__.py
ADDED
|
File without changes
|
backend/app/__init__.py
ADDED
|
File without changes
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
"""
|
|
2
|
+
agent_runtime.py
|
|
3
|
+
|
|
4
|
+
Secure, policy-driven agent runtime for FortressCodeAI.
|
|
5
|
+
|
|
6
|
+
Responsibilities:
|
|
7
|
+
- Enforce tenant isolation and sandboxing
|
|
8
|
+
- Load and apply agent policies (tools, limits, network)
|
|
9
|
+
- Build a controlled toolset for the agent
|
|
10
|
+
- Orchestrate LLM calls (currently via a pluggable client)
|
|
11
|
+
- Log all significant actions for auditability
|
|
12
|
+
|
|
13
|
+
This runtime is the core of your "agent sandboxing" story for pen-tests.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
18
|
+
import uuid
|
|
19
|
+
from dataclasses import dataclass, field
|
|
20
|
+
from pathlib import Path
|
|
21
|
+
from typing import Any, Dict, List, Optional, Callable
|
|
22
|
+
|
|
23
|
+
from .dependencies import get_settings
|
|
24
|
+
from .storage import Storage
|
|
25
|
+
from .tools import build_tools, ToolError, ToolSecurityError
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
# ------------------------------------------------------------
|
|
29
|
+
# Agent policy and definition
|
|
30
|
+
# ------------------------------------------------------------
|
|
31
|
+
|
|
32
|
+
@dataclass
|
|
33
|
+
class AgentPolicy:
|
|
34
|
+
"""
|
|
35
|
+
Policy envelope for an agent.
|
|
36
|
+
|
|
37
|
+
Controls:
|
|
38
|
+
- Which tools are allowed
|
|
39
|
+
- Max tokens per call
|
|
40
|
+
- Max steps per run
|
|
41
|
+
- Whether network access is allowed
|
|
42
|
+
- Optional network allowlist
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
allowed_tools: List[str] = field(default_factory=list)
|
|
46
|
+
max_tokens: int = 4096
|
|
47
|
+
max_steps: int = 4
|
|
48
|
+
allow_network: bool = False
|
|
49
|
+
network_allowlist: List[str] = field(default_factory=list)
|
|
50
|
+
|
|
51
|
+
@classmethod
|
|
52
|
+
def from_dict(cls, data: Dict[str, Any]) -> "AgentPolicy":
|
|
53
|
+
return cls(
|
|
54
|
+
allowed_tools=data.get("allowed_tools", []),
|
|
55
|
+
max_tokens=int(data.get("max_tokens", 4096)),
|
|
56
|
+
max_steps=int(data.get("max_steps", 4)),
|
|
57
|
+
allow_network=bool(data.get("allow_network", False)),
|
|
58
|
+
network_allowlist=list(data.get("network_allowlist", [])),
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
@dataclass
|
|
63
|
+
class AgentDefinition:
|
|
64
|
+
"""
|
|
65
|
+
Canonical agent definition.
|
|
66
|
+
|
|
67
|
+
Expected shape of your "agents" table / config:
|
|
68
|
+
- id: unique identifier
|
|
69
|
+
- name: human-readable name
|
|
70
|
+
- prompt: system prompt / instructions
|
|
71
|
+
- policy: dict -> AgentPolicy
|
|
72
|
+
"""
|
|
73
|
+
|
|
74
|
+
id: str
|
|
75
|
+
name: str
|
|
76
|
+
prompt: str
|
|
77
|
+
policy: AgentPolicy
|
|
78
|
+
|
|
79
|
+
@classmethod
|
|
80
|
+
def from_dict(cls, data: Dict[str, Any]) -> "AgentDefinition":
|
|
81
|
+
policy = AgentPolicy.from_dict(data.get("policy", {}))
|
|
82
|
+
return cls(
|
|
83
|
+
id=data.get("id", ""),
|
|
84
|
+
name=data.get("name", ""),
|
|
85
|
+
prompt=data.get("prompt", "You are an agent."),
|
|
86
|
+
policy=policy,
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
# ------------------------------------------------------------
|
|
91
|
+
# LLM client abstraction (fake implementation for now)
|
|
92
|
+
# ------------------------------------------------------------
|
|
93
|
+
|
|
94
|
+
class LLMClient:
|
|
95
|
+
"""
|
|
96
|
+
Pluggable LLM client abstraction.
|
|
97
|
+
|
|
98
|
+
For now, this is a fake implementation that echoes back the payload.
|
|
99
|
+
Later, you can replace this with a real provider (OpenAI, Azure, etc.)
|
|
100
|
+
without changing the AgentRuntime.
|
|
101
|
+
"""
|
|
102
|
+
|
|
103
|
+
def __init__(self, logger: Callable[[str], None]):
|
|
104
|
+
self.logger = logger
|
|
105
|
+
|
|
106
|
+
def call(
|
|
107
|
+
self,
|
|
108
|
+
system_prompt: str,
|
|
109
|
+
task_payload: Dict[str, Any],
|
|
110
|
+
tools: Dict[str, Callable],
|
|
111
|
+
max_tokens: int,
|
|
112
|
+
) -> Dict[str, Any]:
|
|
113
|
+
"""
|
|
114
|
+
Fake LLM call.
|
|
115
|
+
|
|
116
|
+
A real implementation would:
|
|
117
|
+
- Serialize tools as function definitions
|
|
118
|
+
- Call the provider with tool support
|
|
119
|
+
- Execute tool calls as requested
|
|
120
|
+
- Return the final structured result
|
|
121
|
+
"""
|
|
122
|
+
self.logger("[llm] fake call invoked (replace with real provider)")
|
|
123
|
+
|
|
124
|
+
# For now, just echo back the payload and list tools.
|
|
125
|
+
return {
|
|
126
|
+
"summary": "Fake LLM response. Replace LLMClient.call() with a real implementation.",
|
|
127
|
+
"task_payload": task_payload,
|
|
128
|
+
"available_tools": list(tools.keys()),
|
|
129
|
+
"max_tokens_used": min(max_tokens, 512),
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
# ------------------------------------------------------------
|
|
134
|
+
# Agent runtime
|
|
135
|
+
# ------------------------------------------------------------
|
|
136
|
+
|
|
137
|
+
class AgentRuntime:
|
|
138
|
+
"""
|
|
139
|
+
Secure execution environment for a single agent run.
|
|
140
|
+
|
|
141
|
+
Lifecycle:
|
|
142
|
+
- Initialize with tenant_id, agent_def, workflow context, storage, logger
|
|
143
|
+
- Create a per-run sandbox directory
|
|
144
|
+
- Build a policy-bound toolset
|
|
145
|
+
- Call the LLM client with the system prompt + task payload + tools
|
|
146
|
+
- Return a structured result
|
|
147
|
+
|
|
148
|
+
This class is the core of your "agent sandboxing" story.
|
|
149
|
+
"""
|
|
150
|
+
|
|
151
|
+
def __init__(
|
|
152
|
+
self,
|
|
153
|
+
tenant_id: str,
|
|
154
|
+
agent_def: Dict[str, Any],
|
|
155
|
+
workflow_ctx: Dict[str, Any],
|
|
156
|
+
storage: Storage,
|
|
157
|
+
logger: Callable[[str], None],
|
|
158
|
+
):
|
|
159
|
+
self.tenant_id = tenant_id
|
|
160
|
+
self.agent = AgentDefinition.from_dict(agent_def)
|
|
161
|
+
self.workflow_ctx = workflow_ctx
|
|
162
|
+
self.storage = storage
|
|
163
|
+
self.logger = logger
|
|
164
|
+
|
|
165
|
+
settings = get_settings()
|
|
166
|
+
self.sandbox_root = Path(getattr(settings, "AGENT_SANDBOX_PATH", "./workspaces")).resolve()
|
|
167
|
+
|
|
168
|
+
self.policy = self.agent.policy
|
|
169
|
+
self.sandbox_path = self._init_sandbox()
|
|
170
|
+
self.tools = self._build_tools()
|
|
171
|
+
self.llm_client = LLMClient(logger=self._log)
|
|
172
|
+
|
|
173
|
+
# --------------------------------------------------------
|
|
174
|
+
# Internal helpers
|
|
175
|
+
# --------------------------------------------------------
|
|
176
|
+
|
|
177
|
+
def _log(self, message: str) -> None:
|
|
178
|
+
self.logger(f"[agent:{self.agent.id}] {message}")
|
|
179
|
+
|
|
180
|
+
def _init_sandbox(self) -> Path:
|
|
181
|
+
"""
|
|
182
|
+
Create a per-run sandbox directory for this agent execution.
|
|
183
|
+
"""
|
|
184
|
+
run_id = str(uuid.uuid4())
|
|
185
|
+
path = self.sandbox_root / self.tenant_id / run_id
|
|
186
|
+
path.mkdir(parents=True, exist_ok=True)
|
|
187
|
+
self._log(f"sandbox created at {path}")
|
|
188
|
+
return path.resolve()
|
|
189
|
+
|
|
190
|
+
def _build_tools(self) -> Dict[str, Callable]:
|
|
191
|
+
"""
|
|
192
|
+
Build the policy-bound toolset for this agent.
|
|
193
|
+
"""
|
|
194
|
+
network_allowlist: Optional[List[str]] = None
|
|
195
|
+
if self.policy.allow_network:
|
|
196
|
+
network_allowlist = self.policy.network_allowlist
|
|
197
|
+
|
|
198
|
+
tools = build_tools(
|
|
199
|
+
tenant_id=self.tenant_id,
|
|
200
|
+
sandbox_path=self.sandbox_path,
|
|
201
|
+
storage=self.storage,
|
|
202
|
+
logger=self._log,
|
|
203
|
+
allowed_tools=self.policy.allowed_tools,
|
|
204
|
+
network_allowlist=network_allowlist,
|
|
205
|
+
)
|
|
206
|
+
|
|
207
|
+
self._log(f"tools enabled: {list(tools.keys())}")
|
|
208
|
+
return tools
|
|
209
|
+
|
|
210
|
+
def _build_system_prompt(self) -> str:
|
|
211
|
+
"""
|
|
212
|
+
Build the final system prompt for the agent.
|
|
213
|
+
You can enrich this with tenant/workflow context if desired.
|
|
214
|
+
"""
|
|
215
|
+
base = self.agent.prompt
|
|
216
|
+
# You can inject governance / safety instructions here if you want.
|
|
217
|
+
safety_suffix = (
|
|
218
|
+
"\n\n"
|
|
219
|
+
"You must strictly follow the provided tools and never attempt to access resources "
|
|
220
|
+
"outside the sandbox or tenant context. If a requested action is not possible with "
|
|
221
|
+
"the available tools, explain that clearly."
|
|
222
|
+
)
|
|
223
|
+
return base + safety_suffix
|
|
224
|
+
|
|
225
|
+
# --------------------------------------------------------
|
|
226
|
+
# Public API
|
|
227
|
+
# --------------------------------------------------------
|
|
228
|
+
|
|
229
|
+
def run(self, task_payload: Dict[str, Any]) -> Dict[str, Any]:
|
|
230
|
+
"""
|
|
231
|
+
Execute the agent with the given task payload.
|
|
232
|
+
|
|
233
|
+
Returns a structured result that can be stored in workflow context.
|
|
234
|
+
"""
|
|
235
|
+
self._log(
|
|
236
|
+
f"run started for tenant={self.tenant_id}, "
|
|
237
|
+
f"agent={self.agent.name}, "
|
|
238
|
+
f"max_tokens={self.policy.max_tokens}, "
|
|
239
|
+
f"max_steps={self.policy.max_steps}"
|
|
240
|
+
)
|
|
241
|
+
|
|
242
|
+
system_prompt = self._build_system_prompt()
|
|
243
|
+
|
|
244
|
+
try:
|
|
245
|
+
result = self.llm_client.call(
|
|
246
|
+
system_prompt=system_prompt,
|
|
247
|
+
task_payload=task_payload,
|
|
248
|
+
tools=self.tools,
|
|
249
|
+
max_tokens=self.policy.max_tokens,
|
|
250
|
+
)
|
|
251
|
+
except (ToolError, ToolSecurityError) as e:
|
|
252
|
+
self._log(f"tool error: {e}")
|
|
253
|
+
return {
|
|
254
|
+
"status": "error",
|
|
255
|
+
"error_type": "tool_error",
|
|
256
|
+
"message": str(e),
|
|
257
|
+
}
|
|
258
|
+
except Exception as e:
|
|
259
|
+
self._log(f"runtime error: {e}")
|
|
260
|
+
return {
|
|
261
|
+
"status": "error",
|
|
262
|
+
"error_type": "runtime_error",
|
|
263
|
+
"message": str(e),
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
self._log("run completed successfully")
|
|
267
|
+
|
|
268
|
+
return {
|
|
269
|
+
"status": "ok",
|
|
270
|
+
"agent_id": self.agent.id,
|
|
271
|
+
"agent_name": self.agent.name,
|
|
272
|
+
"sandbox_path": str(self.sandbox_path),
|
|
273
|
+
"result": result,
|
|
274
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
from fastapi import APIRouter
|
|
2
|
+
|
|
3
|
+
from .routes_health import router as health_router
|
|
4
|
+
from .routes_plugins import router as plugins_router
|
|
5
|
+
from .routes_workflows import router as workflows_router
|
|
6
|
+
from .routes_devtools import router as devtools_router
|
|
7
|
+
from .routes_metrics import router as metrics_router
|
|
8
|
+
|
|
9
|
+
api_router = APIRouter()
|
|
10
|
+
|
|
11
|
+
api_router.include_router(health_router, prefix="/health")
|
|
12
|
+
api_router.include_router(plugins_router, prefix="/plugins")
|
|
13
|
+
api_router.include_router(workflows_router, prefix="/workflows")
|
|
14
|
+
api_router.include_router(devtools_router, prefix="/devtools")
|
|
15
|
+
api_router.include_router(metrics_router, prefix="/metrics")
|
|
16
|
+
|
|
17
|
+
__all__ = ["api_router"]
|
backend/app/api/audit.py
ADDED
|
File without changes
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
from fastapi import APIRouter
|
|
2
|
+
from typing import Dict, Any
|
|
3
|
+
|
|
4
|
+
from backend.app.governance.policies.evaluator import PolicyEvaluator
|
|
5
|
+
|
|
6
|
+
router = APIRouter(prefix="/governance", tags=["governance"])
|
|
7
|
+
|
|
8
|
+
evaluator: PolicyEvaluator = None # injected in main.py
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@router.post("/evaluate/{trigger}")
|
|
12
|
+
def evaluate(trigger: str, context: Dict[str, Any]):
|
|
13
|
+
results = evaluator.evaluate(trigger, context)
|
|
14
|
+
return {"results": results}
|
backend/app/api/hitl.py
ADDED
|
File without changes
|
backend/app/api/main.py
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import uvicorn
|
|
2
|
+
from backend.app.create_app import create_api_app
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def main():
|
|
6
|
+
app = create_api_app()
|
|
7
|
+
uvicorn.run(
|
|
8
|
+
app,
|
|
9
|
+
host="0.0.0.0",
|
|
10
|
+
port=8000,
|
|
11
|
+
log_level="info",
|
|
12
|
+
proxy_headers=True,
|
|
13
|
+
forwarded_allow_ips="*",
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
if __name__ == "__main__":
|
|
18
|
+
main()
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
from fastapi import APIRouter, HTTPException
|
|
2
|
+
from typing import Dict, Any
|
|
3
|
+
|
|
4
|
+
from backend.app.governance.policies.registry import PolicyRegistry
|
|
5
|
+
from backend.app.governance.policies.loader import PolicyLoader
|
|
6
|
+
from backend.app.governance.policies.evaluator import PolicyEvaluator
|
|
7
|
+
from backend.app.governance.policies.versioning import PolicyVersionStore
|
|
8
|
+
|
|
9
|
+
router = APIRouter(prefix="/policies", tags=["policies"])
|
|
10
|
+
|
|
11
|
+
# Injected singletons (you will initialize these in main.py)
|
|
12
|
+
registry: PolicyRegistry = None
|
|
13
|
+
loader: PolicyLoader = None
|
|
14
|
+
evaluator: PolicyEvaluator = None
|
|
15
|
+
versions: PolicyVersionStore = None
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@router.get("/")
|
|
19
|
+
def list_policies():
|
|
20
|
+
return {
|
|
21
|
+
"active": list(registry.active.values()),
|
|
22
|
+
"disabled": list(registry.disabled.values()),
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@router.get("/{policy_id}")
|
|
27
|
+
def get_policy(policy_id: str):
|
|
28
|
+
policy = registry.get_policy(policy_id)
|
|
29
|
+
if not policy:
|
|
30
|
+
raise HTTPException(404, "Policy not found")
|
|
31
|
+
return policy
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@router.post("/reload")
|
|
35
|
+
def reload_policies():
|
|
36
|
+
registry.active.clear()
|
|
37
|
+
registry.disabled.clear()
|
|
38
|
+
loader.load_all()
|
|
39
|
+
return {"status": "reloaded", "count": len(registry.active)}
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@router.post("/{policy_id}/simulate")
|
|
43
|
+
def simulate_policy(policy_id: str, context: Dict[str, Any]):
|
|
44
|
+
policy = registry.get_policy(policy_id)
|
|
45
|
+
if not policy:
|
|
46
|
+
raise HTTPException(404, "Policy not found")
|
|
47
|
+
|
|
48
|
+
results = evaluator.evaluate(policy.trigger, context)
|
|
49
|
+
return {"results": results}
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
@router.get("/{policy_id}/versions")
|
|
53
|
+
def get_policy_versions(policy_id: str):
|
|
54
|
+
return versions.get_versions(policy_id)
|