devflow-engine 1.0.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.
- devflow_engine/__init__.py +3 -0
- devflow_engine/agentic_prompts.py +100 -0
- devflow_engine/agentic_runtime.py +398 -0
- devflow_engine/api_key_flow_harness.py +539 -0
- devflow_engine/api_keys.py +357 -0
- devflow_engine/bootstrap/__init__.py +2 -0
- devflow_engine/bootstrap/provision_from_template.py +84 -0
- devflow_engine/cli/__init__.py +0 -0
- devflow_engine/cli/app.py +7270 -0
- devflow_engine/core/__init__.py +0 -0
- devflow_engine/core/config.py +86 -0
- devflow_engine/core/logging.py +29 -0
- devflow_engine/core/paths.py +45 -0
- devflow_engine/core/toml_kv.py +33 -0
- devflow_engine/devflow_event_worker.py +1292 -0
- devflow_engine/devflow_state.py +201 -0
- devflow_engine/devin2/__init__.py +9 -0
- devflow_engine/devin2/agent_definition.py +120 -0
- devflow_engine/devin2/pi_runner.py +204 -0
- devflow_engine/devin_orchestration.py +69 -0
- devflow_engine/docs/prompts/anti-patterns.md +42 -0
- devflow_engine/docs/prompts/devin-agent-prompt.md +55 -0
- devflow_engine/docs/prompts/devin2-agent-prompt.md +81 -0
- devflow_engine/docs/prompts/examples/devin-vapi-clone-reference-exchange.json +85 -0
- devflow_engine/doctor/__init__.py +2 -0
- devflow_engine/doctor/triage.py +140 -0
- devflow_engine/error/__init__.py +0 -0
- devflow_engine/error/remediation.py +21 -0
- devflow_engine/errors/error_solver_dag.py +522 -0
- devflow_engine/errors/runtime_observability.py +67 -0
- devflow_engine/idea/__init__.py +4 -0
- devflow_engine/idea/actors.py +481 -0
- devflow_engine/idea/agentic.py +465 -0
- devflow_engine/idea/analyze.py +93 -0
- devflow_engine/idea/devin_chat_dag.py +1 -0
- devflow_engine/idea/diff.py +99 -0
- devflow_engine/idea/drafts.py +446 -0
- devflow_engine/idea/idea_creation_dag.py +643 -0
- devflow_engine/idea/ideation_enrichment.py +355 -0
- devflow_engine/idea/ideation_enrichment_worker.py +19 -0
- devflow_engine/idea/paths.py +28 -0
- devflow_engine/idea/promote.py +53 -0
- devflow_engine/idea/redaction.py +27 -0
- devflow_engine/idea/repo_tools.py +1277 -0
- devflow_engine/idea/response_mode.py +30 -0
- devflow_engine/idea/story_pipeline.py +1585 -0
- devflow_engine/idea/sufficiency.py +376 -0
- devflow_engine/idea/traditional_stories.py +1257 -0
- devflow_engine/implementation/__init__.py +0 -0
- devflow_engine/implementation/alembic_preflight.py +700 -0
- devflow_engine/implementation/dag.py +8450 -0
- devflow_engine/implementation/green_gate.py +93 -0
- devflow_engine/implementation/prompts.py +108 -0
- devflow_engine/implementation/test_runtime.py +623 -0
- devflow_engine/integration/__init__.py +19 -0
- devflow_engine/integration/agentic.py +66 -0
- devflow_engine/integration/dag.py +3539 -0
- devflow_engine/integration/prompts.py +114 -0
- devflow_engine/integration/supabase_schema.sql +31 -0
- devflow_engine/integration/supabase_sync.py +177 -0
- devflow_engine/llm/__init__.py +1 -0
- devflow_engine/llm/cli_one_shot.py +84 -0
- devflow_engine/llm/cli_stream.py +371 -0
- devflow_engine/llm/execution_context.py +26 -0
- devflow_engine/llm/invoke.py +1322 -0
- devflow_engine/llm/provider_api.py +304 -0
- devflow_engine/llm/repo_knowledge.py +588 -0
- devflow_engine/llm_primitives.py +315 -0
- devflow_engine/orchestration.py +62 -0
- devflow_engine/planning/__init__.py +0 -0
- devflow_engine/planning/analyze_repo.py +92 -0
- devflow_engine/planning/render_drafts.py +133 -0
- devflow_engine/playground/__init__.py +0 -0
- devflow_engine/playground/hooks.py +26 -0
- devflow_engine/playwright_workflow/__init__.py +5 -0
- devflow_engine/playwright_workflow/dag.py +1317 -0
- devflow_engine/process/__init__.py +5 -0
- devflow_engine/process/dag.py +59 -0
- devflow_engine/project_registration/__init__.py +3 -0
- devflow_engine/project_registration/dag.py +1581 -0
- devflow_engine/project_registry.py +109 -0
- devflow_engine/prompts/devin/generic/prompt.md +6 -0
- devflow_engine/prompts/devin/ideation/prompt.md +263 -0
- devflow_engine/prompts/devin/ideation/scenarios.md +5 -0
- devflow_engine/prompts/devin/ideation_loop/prompt.md +6 -0
- devflow_engine/prompts/devin/insight/prompt.md +11 -0
- devflow_engine/prompts/devin/insight/scenarios.md +5 -0
- devflow_engine/prompts/devin/intake/prompt.md +15 -0
- devflow_engine/prompts/devin/iterate/prompt.md +12 -0
- devflow_engine/prompts/devin/shared/eval_doctrine.md +9 -0
- devflow_engine/prompts/devin/shared/principles.md +246 -0
- devflow_engine/prompts/devin_eval/assessment/prompt.md +18 -0
- devflow_engine/prompts/idea/api_ideation_agent/prompt.md +8 -0
- devflow_engine/prompts/idea/api_insight_agent/prompt.md +8 -0
- devflow_engine/prompts/idea/response_doctrine/prompt.md +18 -0
- devflow_engine/prompts/implementation/dependency_assessment/prompt.md +12 -0
- devflow_engine/prompts/implementation/green/green/prompt.md +11 -0
- devflow_engine/prompts/implementation/green/node_config/prompt.md +3 -0
- devflow_engine/prompts/implementation/green_review/outcome_review/prompt.md +5 -0
- devflow_engine/prompts/implementation/green_review/prior_run_review/prompt.md +5 -0
- devflow_engine/prompts/implementation/red/prompt.md +27 -0
- devflow_engine/prompts/implementation/redreview/prompt.md +23 -0
- devflow_engine/prompts/implementation/redreview_repair/prompt.md +16 -0
- devflow_engine/prompts/implementation/setupdoc/prompt.md +10 -0
- devflow_engine/prompts/implementation/story_planning/prompt.md +13 -0
- devflow_engine/prompts/implementation/test_design/prompt.md +27 -0
- devflow_engine/prompts/integration/README.md +185 -0
- devflow_engine/prompts/integration/green/example.md +67 -0
- devflow_engine/prompts/integration/green/green/prompt.md +10 -0
- devflow_engine/prompts/integration/green/node_config/prompt.md +42 -0
- devflow_engine/prompts/integration/green/past_prompts/20260417T212300/green/prompt.md +15 -0
- devflow_engine/prompts/integration/green/past_prompts/20260417T212300/node_config/prompt.md +42 -0
- devflow_engine/prompts/integration/green_enrich/example.md +79 -0
- devflow_engine/prompts/integration/green_enrich/green_enrich/prompt.md +9 -0
- devflow_engine/prompts/integration/green_enrich/node_config/prompt.md +41 -0
- devflow_engine/prompts/integration/green_enrich/past_prompts/20260417T212300/green_enrich/prompt.md +14 -0
- devflow_engine/prompts/integration/green_enrich/past_prompts/20260417T212300/node_config/prompt.md +41 -0
- devflow_engine/prompts/integration/red/code_repair/prompt.md +12 -0
- devflow_engine/prompts/integration/red/example.md +152 -0
- devflow_engine/prompts/integration/red/node_config/prompt.md +86 -0
- devflow_engine/prompts/integration/red/past_prompts/20260417T212300/code_repair/prompt.md +19 -0
- devflow_engine/prompts/integration/red/past_prompts/20260417T212300/node_config/prompt.md +84 -0
- devflow_engine/prompts/integration/red/past_prompts/20260417T212300/red/prompt.md +16 -0
- devflow_engine/prompts/integration/red/past_prompts/20260417T212300/red_repair/prompt.md +15 -0
- devflow_engine/prompts/integration/red/past_prompts/20260417T215032/code_repair/prompt.md +10 -0
- devflow_engine/prompts/integration/red/past_prompts/20260417T215032/node_config/prompt.md +84 -0
- devflow_engine/prompts/integration/red/past_prompts/20260417T215032/red_repair/prompt.md +11 -0
- devflow_engine/prompts/integration/red/red/prompt.md +11 -0
- devflow_engine/prompts/integration/red/red_repair/prompt.md +12 -0
- devflow_engine/prompts/integration/red_review/example.md +71 -0
- devflow_engine/prompts/integration/red_review/node_config/prompt.md +41 -0
- devflow_engine/prompts/integration/red_review/past_prompts/20260417T212300/node_config/prompt.md +41 -0
- devflow_engine/prompts/integration/red_review/past_prompts/20260417T212300/red_review/prompt.md +15 -0
- devflow_engine/prompts/integration/red_review/red_review/prompt.md +9 -0
- devflow_engine/prompts/integration/resolve/example.md +111 -0
- devflow_engine/prompts/integration/resolve/node_config/prompt.md +64 -0
- devflow_engine/prompts/integration/resolve/past_prompts/20260417T212300/node_config/prompt.md +64 -0
- devflow_engine/prompts/integration/resolve/past_prompts/20260417T212300/resolve_implicated_users/prompt.md +15 -0
- devflow_engine/prompts/integration/resolve/past_prompts/20260417T212300/resolve_side_effects/prompt.md +15 -0
- devflow_engine/prompts/integration/resolve/resolve_implicated_users/prompt.md +10 -0
- devflow_engine/prompts/integration/resolve/resolve_side_effects/prompt.md +10 -0
- devflow_engine/prompts/integration/validate/build_idea_acceptance_coverage/prompt.md +12 -0
- devflow_engine/prompts/integration/validate/code_repair/prompt.md +13 -0
- devflow_engine/prompts/integration/validate/example.md +143 -0
- devflow_engine/prompts/integration/validate/node_config/prompt.md +87 -0
- devflow_engine/prompts/integration/validate/past_prompts/20260417T212300/code_repair/prompt.md +19 -0
- devflow_engine/prompts/integration/validate/past_prompts/20260417T212300/node_config/prompt.md +67 -0
- devflow_engine/prompts/integration/validate/past_prompts/20260417T212300/validate_enrich_gate/prompt.md +17 -0
- devflow_engine/prompts/integration/validate/past_prompts/20260417T212300/validate_repair/prompt.md +16 -0
- devflow_engine/prompts/integration/validate/past_prompts/20260417T215032/code_repair/prompt.md +10 -0
- devflow_engine/prompts/integration/validate/past_prompts/20260417T215032/node_config/prompt.md +67 -0
- devflow_engine/prompts/integration/validate/past_prompts/20260417T215032/validate_repair/prompt.md +9 -0
- devflow_engine/prompts/integration/validate/validate_enrich_gate/prompt.md +10 -0
- devflow_engine/prompts/integration/validate/validate_repair/prompt.md +20 -0
- devflow_engine/prompts/integration/write_workflows/example.md +100 -0
- devflow_engine/prompts/integration/write_workflows/node_config/prompt.md +44 -0
- devflow_engine/prompts/integration/write_workflows/past_prompts/20260417T212300/node_config/prompt.md +44 -0
- devflow_engine/prompts/integration/write_workflows/past_prompts/20260417T212300/write_workflows/prompt.md +17 -0
- devflow_engine/prompts/integration/write_workflows/write_workflows/prompt.md +11 -0
- devflow_engine/prompts/iterate/README.md +7 -0
- devflow_engine/prompts/iterate/coder/prompt.md +11 -0
- devflow_engine/prompts/iterate/framer/prompt.md +11 -0
- devflow_engine/prompts/iterate/iterator/prompt.md +13 -0
- devflow_engine/prompts/iterate/observer/prompt.md +11 -0
- devflow_engine/prompts/recovery/diagnosis/prompt.md +7 -0
- devflow_engine/prompts/recovery/execution/prompt.md +8 -0
- devflow_engine/prompts/recovery/execution_verification/prompt.md +7 -0
- devflow_engine/prompts/recovery/failure_investigation/prompt.md +10 -0
- devflow_engine/prompts/recovery/preflight_health_repo_repair/prompt.md +8 -0
- devflow_engine/prompts/recovery/remediation_execution/prompt.md +11 -0
- devflow_engine/prompts/recovery/root_cause_investigation/prompt.md +12 -0
- devflow_engine/prompts/scope_idea/doctrine/prompt.md +7 -0
- devflow_engine/prompts/source_doc_eval/document/prompt.md +6 -0
- devflow_engine/prompts/source_doc_eval/targeted_mutation/prompt.md +9 -0
- devflow_engine/prompts/source_doc_mutation/domain_entities/prompt.md +6 -0
- devflow_engine/prompts/source_doc_mutation/product_brief/prompt.md +6 -0
- devflow_engine/prompts/source_doc_mutation/project_doc_coherence/prompt.md +7 -0
- devflow_engine/prompts/source_doc_mutation/project_doc_render/prompt.md +9 -0
- devflow_engine/prompts/source_doc_mutation/source_doc_coherence/prompt.md +5 -0
- devflow_engine/prompts/source_doc_mutation/source_doc_enrichment_coherence/prompt.md +6 -0
- devflow_engine/prompts/source_doc_mutation/user_workflows/prompt.md +6 -0
- devflow_engine/prompts/source_scope/doctrine/prompt.md +10 -0
- devflow_engine/prompts/ui_grounding/doctrine/prompt.md +7 -0
- devflow_engine/recovery/__init__.py +3 -0
- devflow_engine/recovery/dag.py +2609 -0
- devflow_engine/recovery/models.py +220 -0
- devflow_engine/refactor.py +93 -0
- devflow_engine/registry/__init__.py +1 -0
- devflow_engine/registry/cards.py +238 -0
- devflow_engine/registry/domain_normalize.py +60 -0
- devflow_engine/registry/effects.py +65 -0
- devflow_engine/registry/enforce_report.py +150 -0
- devflow_engine/registry/module_cards_classify.py +164 -0
- devflow_engine/registry/module_cards_draft.py +184 -0
- devflow_engine/registry/module_cards_gate.py +59 -0
- devflow_engine/registry/packages.py +347 -0
- devflow_engine/registry/pathways.py +323 -0
- devflow_engine/review/__init__.py +11 -0
- devflow_engine/review/dag.py +588 -0
- devflow_engine/review/review_story.py +67 -0
- devflow_engine/scope_idea/__init__.py +3 -0
- devflow_engine/scope_idea/agentic.py +39 -0
- devflow_engine/scope_idea/dag.py +1069 -0
- devflow_engine/scope_idea/models.py +175 -0
- devflow_engine/skills/builtins/devflow/queue_failure_investigation/SKILL.md +112 -0
- devflow_engine/skills/builtins/devflow/queue_idea_to_story/SKILL.md +120 -0
- devflow_engine/skills/builtins/devflow/queue_integration/SKILL.md +105 -0
- devflow_engine/skills/builtins/devflow/queue_recovery/SKILL.md +108 -0
- devflow_engine/skills/builtins/devflow/queue_runtime_core/SKILL.md +155 -0
- devflow_engine/skills/builtins/devflow/queue_story_implementation/SKILL.md +122 -0
- devflow_engine/skills/builtins/devin/idea_to_story_handoff/SKILL.md +120 -0
- devflow_engine/skills/builtins/devin/ideation/SKILL.md +168 -0
- devflow_engine/skills/builtins/devin/ideation/state-and-phrasing-reference.md +18 -0
- devflow_engine/skills/builtins/devin/insight/SKILL.md +22 -0
- devflow_engine/skills/registry.example.yaml +42 -0
- devflow_engine/source_doc_assumptions.py +291 -0
- devflow_engine/source_doc_mutation_dag.py +1606 -0
- devflow_engine/source_doc_mutation_eval.py +417 -0
- devflow_engine/source_doc_mutation_worker.py +25 -0
- devflow_engine/source_docs_schema.py +207 -0
- devflow_engine/source_docs_updater.py +309 -0
- devflow_engine/source_scope/__init__.py +15 -0
- devflow_engine/source_scope/agentic.py +45 -0
- devflow_engine/source_scope/dag.py +1626 -0
- devflow_engine/source_scope/models.py +177 -0
- devflow_engine/stores/__init__.py +0 -0
- devflow_engine/stores/execution_store.py +3534 -0
- devflow_engine/story/__init__.py +0 -0
- devflow_engine/story/contracts.py +160 -0
- devflow_engine/story/discovery.py +47 -0
- devflow_engine/story/evidence.py +118 -0
- devflow_engine/story/hashing.py +27 -0
- devflow_engine/story/implemented_queue_purge.py +148 -0
- devflow_engine/story/indexer.py +105 -0
- devflow_engine/story/io.py +20 -0
- devflow_engine/story/markdown_contracts.py +298 -0
- devflow_engine/story/reconciliation.py +408 -0
- devflow_engine/story/validate_stories.py +149 -0
- devflow_engine/story/validate_tests_story.py +512 -0
- devflow_engine/story/validation.py +133 -0
- devflow_engine/ui_grounding/__init__.py +11 -0
- devflow_engine/ui_grounding/agentic.py +31 -0
- devflow_engine/ui_grounding/dag.py +874 -0
- devflow_engine/ui_grounding/models.py +224 -0
- devflow_engine/ui_grounding/pencil_bridge.py +247 -0
- devflow_engine/vendor/__init__.py +0 -0
- devflow_engine/vendor/datalumina_genai/__init__.py +11 -0
- devflow_engine/vendor/datalumina_genai/core/__init__.py +0 -0
- devflow_engine/vendor/datalumina_genai/core/exceptions.py +9 -0
- devflow_engine/vendor/datalumina_genai/core/nodes/__init__.py +0 -0
- devflow_engine/vendor/datalumina_genai/core/nodes/agent.py +48 -0
- devflow_engine/vendor/datalumina_genai/core/nodes/agent_streaming_node.py +26 -0
- devflow_engine/vendor/datalumina_genai/core/nodes/base.py +89 -0
- devflow_engine/vendor/datalumina_genai/core/nodes/concurrent.py +30 -0
- devflow_engine/vendor/datalumina_genai/core/nodes/router.py +69 -0
- devflow_engine/vendor/datalumina_genai/core/schema.py +72 -0
- devflow_engine/vendor/datalumina_genai/core/task.py +52 -0
- devflow_engine/vendor/datalumina_genai/core/validate.py +139 -0
- devflow_engine/vendor/datalumina_genai/core/workflow.py +200 -0
- devflow_engine/worker.py +1086 -0
- devflow_engine/worker_guard.py +233 -0
- devflow_engine-1.0.0.dist-info/METADATA +235 -0
- devflow_engine-1.0.0.dist-info/RECORD +393 -0
- devflow_engine-1.0.0.dist-info/WHEEL +4 -0
- devflow_engine-1.0.0.dist-info/entry_points.txt +3 -0
- devin/__init__.py +6 -0
- devin/dag.py +58 -0
- devin/dag_two_arm.py +138 -0
- devin/devin_chat_scenario_catalog.json +588 -0
- devin/devin_eval.py +677 -0
- devin/nodes/__init__.py +0 -0
- devin/nodes/ideation/__init__.py +0 -0
- devin/nodes/ideation/node.py +195 -0
- devin/nodes/ideation/playground.py +267 -0
- devin/nodes/ideation/prompt.md +65 -0
- devin/nodes/ideation/scenarios/continue_refinement.py +13 -0
- devin/nodes/ideation/scenarios/continue_refinement_evals.py +18 -0
- devin/nodes/ideation/scenarios/idea_fits_existing_patterns.py +17 -0
- devin/nodes/ideation/scenarios/idea_fits_existing_patterns_evals.py +16 -0
- devin/nodes/ideation/scenarios/large_idea_split.py +4 -0
- devin/nodes/ideation/scenarios/large_idea_split_evals.py +17 -0
- devin/nodes/ideation/scenarios/source_documentation_added.py +4 -0
- devin/nodes/ideation/scenarios/source_documentation_added_evals.py +16 -0
- devin/nodes/ideation/scenarios/user_says_create_it.py +30 -0
- devin/nodes/ideation/scenarios/user_says_create_it_evals.py +23 -0
- devin/nodes/ideation/scenarios/vague_idea.py +16 -0
- devin/nodes/ideation/scenarios/vague_idea_evals.py +47 -0
- devin/nodes/ideation/tools.json +312 -0
- devin/nodes/insight/__init__.py +0 -0
- devin/nodes/insight/node.py +49 -0
- devin/nodes/insight/playground.py +154 -0
- devin/nodes/insight/prompt.md +61 -0
- devin/nodes/insight/scenarios/architecture_pattern_query.py +15 -0
- devin/nodes/insight/scenarios/architecture_pattern_query_evals.py +25 -0
- devin/nodes/insight/scenarios/codebase_exploration.py +15 -0
- devin/nodes/insight/scenarios/codebase_exploration_evals.py +23 -0
- devin/nodes/insight/scenarios/devin_ideation_routing.py +19 -0
- devin/nodes/insight/scenarios/devin_ideation_routing_evals.py +39 -0
- devin/nodes/insight/scenarios/devin_insight_routing.py +20 -0
- devin/nodes/insight/scenarios/devin_insight_routing_evals.py +40 -0
- devin/nodes/insight/scenarios/operational_debugging.py +15 -0
- devin/nodes/insight/scenarios/operational_debugging_evals.py +23 -0
- devin/nodes/insight/scenarios/operational_question.py +9 -0
- devin/nodes/insight/scenarios/operational_question_evals.py +8 -0
- devin/nodes/insight/scenarios/queue_status.py +15 -0
- devin/nodes/insight/scenarios/queue_status_evals.py +23 -0
- devin/nodes/insight/scenarios/source_doc_explanation.py +14 -0
- devin/nodes/insight/scenarios/source_doc_explanation_evals.py +21 -0
- devin/nodes/insight/scenarios/worker_state_check.py +15 -0
- devin/nodes/insight/scenarios/worker_state_check_evals.py +22 -0
- devin/nodes/insight/tools.json +126 -0
- devin/nodes/intake/__init__.py +0 -0
- devin/nodes/intake/node.py +27 -0
- devin/nodes/intake/playground.py +47 -0
- devin/nodes/intake/prompt.md +12 -0
- devin/nodes/intake/scenarios/ideation_routing.py +4 -0
- devin/nodes/intake/scenarios/ideation_routing_evals.py +5 -0
- devin/nodes/intake/scenarios/insight_routing.py +4 -0
- devin/nodes/intake/scenarios/insight_routing_evals.py +5 -0
- devin/nodes/iterate/README.md +44 -0
- devin/nodes/iterate/__init__.py +1 -0
- devin/nodes/iterate/_archived_design_stages/01-objectives-requirements.md +112 -0
- devin/nodes/iterate/_archived_design_stages/02-evals.md +131 -0
- devin/nodes/iterate/_archived_design_stages/03-tools-and-boundaries.md +110 -0
- devin/nodes/iterate/_archived_design_stages/04-harness-and-playground.md +32 -0
- devin/nodes/iterate/_archived_design_stages/05-prompt-deferred.md +11 -0
- devin/nodes/iterate/_archived_design_stages/coder_agent_design/01-objectives-requirements.md +20 -0
- devin/nodes/iterate/_archived_design_stages/coder_agent_design/02-evals.md +8 -0
- devin/nodes/iterate/_archived_design_stages/coder_agent_design/03-tools-and-boundaries.md +14 -0
- devin/nodes/iterate/_archived_design_stages/coder_agent_design/04-harness-and-playground.md +12 -0
- devin/nodes/iterate/_archived_design_stages/framer_agent_design/01-objectives-requirements.md +20 -0
- devin/nodes/iterate/_archived_design_stages/framer_agent_design/02-evals.md +8 -0
- devin/nodes/iterate/_archived_design_stages/framer_agent_design/03-tools-and-boundaries.md +13 -0
- devin/nodes/iterate/_archived_design_stages/framer_agent_design/04-harness-and-playground.md +12 -0
- devin/nodes/iterate/_archived_design_stages/iterator_agent_design/01-objectives-requirements.md +25 -0
- devin/nodes/iterate/_archived_design_stages/iterator_agent_design/02-evals.md +9 -0
- devin/nodes/iterate/_archived_design_stages/iterator_agent_design/03-tools-and-boundaries.md +14 -0
- devin/nodes/iterate/_archived_design_stages/iterator_agent_design/04-harness-and-playground.md +12 -0
- devin/nodes/iterate/_archived_design_stages/observer_agent_design/01-objectives-requirements.md +20 -0
- devin/nodes/iterate/_archived_design_stages/observer_agent_design/02-evals.md +8 -0
- devin/nodes/iterate/_archived_design_stages/observer_agent_design/03-tools-and-boundaries.md +14 -0
- devin/nodes/iterate/_archived_design_stages/observer_agent_design/04-harness-and-playground.md +13 -0
- devin/nodes/iterate/agent-roles.md +89 -0
- devin/nodes/iterate/agents/README.md +10 -0
- devin/nodes/iterate/artifacts.md +504 -0
- devin/nodes/iterate/contract.md +100 -0
- devin/nodes/iterate/eval-plan.md +74 -0
- devin/nodes/iterate/node.py +100 -0
- devin/nodes/iterate/pipeline/README.md +13 -0
- devin/nodes/iterate/playground-contract.md +76 -0
- devin/nodes/iterate/prompt.md +11 -0
- devin/nodes/iterate/scenarios/README.md +38 -0
- devin/nodes/iterate/scenarios/artifact-and-loop-scenarios.md +101 -0
- devin/nodes/iterate/scenarios/coder_artifact_alignment.py +32 -0
- devin/nodes/iterate/scenarios/coder_artifact_alignment_evals.py +45 -0
- devin/nodes/iterate/scenarios/coder_bounded_fix.py +27 -0
- devin/nodes/iterate/scenarios/coder_bounded_fix_evals.py +45 -0
- devin/nodes/iterate/scenarios/devin_iterate_routing.py +21 -0
- devin/nodes/iterate/scenarios/devin_iterate_routing_evals.py +36 -0
- devin/nodes/iterate/scenarios/framer_scope_boundary.py +25 -0
- devin/nodes/iterate/scenarios/framer_scope_boundary_evals.py +57 -0
- devin/nodes/iterate/scenarios/framer_task_framing.py +25 -0
- devin/nodes/iterate/scenarios/framer_task_framing_evals.py +58 -0
- devin/nodes/iterate/scenarios/iterate_error_fix.py +21 -0
- devin/nodes/iterate/scenarios/iterate_error_fix_evals.py +39 -0
- devin/nodes/iterate/scenarios/iterate_quick_change.py +21 -0
- devin/nodes/iterate/scenarios/iterate_quick_change_evals.py +35 -0
- devin/nodes/iterate/scenarios/iterate_to_idea_promotion.py +23 -0
- devin/nodes/iterate/scenarios/iterate_to_idea_promotion_evals.py +53 -0
- devin/nodes/iterate/scenarios/iterate_to_insight_reroute.py +23 -0
- devin/nodes/iterate/scenarios/iterate_to_insight_reroute_evals.py +53 -0
- devin/nodes/iterate/scenarios/observer_evidence_seam.py +28 -0
- devin/nodes/iterate/scenarios/observer_evidence_seam_evals.py +55 -0
- devin/nodes/iterate/scenarios/observer_repro_creation.py +28 -0
- devin/nodes/iterate/scenarios/observer_repro_creation_evals.py +45 -0
- devin/nodes/iterate/scenarios/routing-matrix.md +45 -0
- devin/nodes/shared/__init__.py +0 -0
- devin/nodes/shared/filemaker_expert.md +80 -0
- devin/nodes/shared/filemaker_expert.py +354 -0
- devin/nodes/shared/filemaker_expert_eval/runner.py +176 -0
- devin/nodes/shared/filemaker_expert_eval/scenarios.json +65 -0
- devin/nodes/shared/goldilocks_advisor_eval/runner.py +214 -0
- devin/nodes/shared/goldilocks_advisor_eval/scenarios.json +58 -0
- devin/nodes/shared/helpers.py +156 -0
- devin/nodes/shared/idea_compliance_advisor_eval/runner.py +252 -0
- devin/nodes/shared/idea_compliance_advisor_eval/scenarios.json +75 -0
- devin/nodes/shared/models.py +44 -0
- devin/nodes/shared/post.py +40 -0
- devin/nodes/shared/router.py +107 -0
- devin/nodes/shared/tools.py +191 -0
- devin/shared/devin-chat-rubric.md +237 -0
- devin/shared/devin-chat-scenario-suite.md +90 -0
- devin/shared/eval_doctrine.md +9 -0
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import re
|
|
4
|
+
from importlib.resources import files
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import Any
|
|
7
|
+
|
|
8
|
+
_REPO_ROOT = Path(__file__).resolve().parents[3]
|
|
9
|
+
_PROMPTS_ROOT = _REPO_ROOT / "prompts" / "integration"
|
|
10
|
+
|
|
11
|
+
_STAGE_PROMPT_LAYOUT: dict[str, tuple[str, str]] = {
|
|
12
|
+
"resolve_side_effects": ("resolve", "resolve_side_effects"),
|
|
13
|
+
"resolve_implicated_users": ("resolve", "resolve_implicated_users"),
|
|
14
|
+
"write_workflows": ("write_workflows", "write_workflows"),
|
|
15
|
+
"build_idea_acceptance_coverage": ("validate", "build_idea_acceptance_coverage"),
|
|
16
|
+
"validate_enrich_gate": ("validate", "validate_enrich_gate"),
|
|
17
|
+
"validate_repair": ("validate", "validate_repair"),
|
|
18
|
+
"red": ("red", "red"),
|
|
19
|
+
"red_repair": ("red", "red_repair"),
|
|
20
|
+
"red_review": ("red_review", "red_review"),
|
|
21
|
+
"green": ("green", "green"),
|
|
22
|
+
"green_enrich": ("green_enrich", "green_enrich"),
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
_NODE_CONFIG_LAYOUT: dict[str, tuple[str, str]] = {
|
|
26
|
+
"resolve": ("resolve", "node_config"),
|
|
27
|
+
"write_workflows": ("write_workflows", "node_config"),
|
|
28
|
+
"validate": ("validate", "node_config"),
|
|
29
|
+
"red": ("red", "node_config"),
|
|
30
|
+
"red_review": ("red_review", "node_config"),
|
|
31
|
+
"green": ("green", "node_config"),
|
|
32
|
+
"green_enrich": ("green_enrich", "node_config"),
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def integration_prompt_path(*, node: str, agent_name: str) -> Path:
|
|
37
|
+
source_path = _PROMPTS_ROOT / node / agent_name / "prompt.md"
|
|
38
|
+
if source_path.exists():
|
|
39
|
+
return source_path
|
|
40
|
+
return Path(str(_packaged_integration_prompts_root().joinpath(node, agent_name, "prompt.md")))
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def _packaged_integration_prompts_root() -> Any:
|
|
44
|
+
return files("devflow_engine").joinpath("prompts", "integration")
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def _prompt_text(path: Path) -> str:
|
|
48
|
+
if path.exists():
|
|
49
|
+
return path.read_text(encoding="utf-8").strip()
|
|
50
|
+
package_path = _packaged_integration_prompts_root().joinpath(*path.parts[-3:])
|
|
51
|
+
return package_path.read_text(encoding="utf-8").strip()
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def integration_stage_prompt_path(stage_name: str) -> Path:
|
|
55
|
+
normalized_stage_name = _normalize_stage_name(stage_name)
|
|
56
|
+
try:
|
|
57
|
+
node, agent_name = _STAGE_PROMPT_LAYOUT[normalized_stage_name]
|
|
58
|
+
except KeyError as exc:
|
|
59
|
+
raise KeyError(f"Unknown integration stage prompt mapping: {stage_name}") from exc
|
|
60
|
+
return integration_prompt_path(node=node, agent_name=agent_name)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def integration_node_prompt_path(node: str) -> Path:
|
|
64
|
+
try:
|
|
65
|
+
mapped_node, agent_name = _NODE_CONFIG_LAYOUT[node]
|
|
66
|
+
except KeyError as exc:
|
|
67
|
+
raise KeyError(f"Unknown integration node prompt mapping: {node}") from exc
|
|
68
|
+
return integration_prompt_path(node=mapped_node, agent_name=agent_name)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def load_integration_prompt_markdown(*, node: str, agent_name: str) -> str:
|
|
72
|
+
return _prompt_text(integration_prompt_path(node=node, agent_name=agent_name))
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def load_integration_stage_prompt_markdown(stage_name: str) -> str:
|
|
76
|
+
return _prompt_text(integration_stage_prompt_path(stage_name))
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def load_integration_node_instruction(node: str) -> str:
|
|
80
|
+
return _parse_prompt_markdown(_prompt_text(integration_node_prompt_path(node)))[0]
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def load_integration_stage_guidance(stage_name: str) -> list[str]:
|
|
84
|
+
return _parse_prompt_markdown(_prompt_text(integration_stage_prompt_path(stage_name)))[1]
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def load_integration_code_repair_guidance(*, red_mode: bool) -> list[str]:
|
|
88
|
+
node = "red" if red_mode else "validate"
|
|
89
|
+
return _parse_prompt_markdown(
|
|
90
|
+
_prompt_text(integration_prompt_path(node=node, agent_name="code_repair"))
|
|
91
|
+
)[1]
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def _parse_prompt_markdown(markdown: str) -> tuple[str, list[str]]:
|
|
95
|
+
instruction = ""
|
|
96
|
+
guidance: list[str] = []
|
|
97
|
+
for raw_line in markdown.splitlines():
|
|
98
|
+
line = raw_line.strip()
|
|
99
|
+
if not line or line.startswith("#"):
|
|
100
|
+
continue
|
|
101
|
+
if line.startswith("- "):
|
|
102
|
+
guidance.append(line[2:].strip())
|
|
103
|
+
continue
|
|
104
|
+
if not instruction:
|
|
105
|
+
instruction = line
|
|
106
|
+
if not instruction:
|
|
107
|
+
raise ValueError("Integration prompt markdown is missing an instruction line.")
|
|
108
|
+
return instruction, guidance
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def _normalize_stage_name(stage_name: str) -> str:
|
|
112
|
+
if re.fullmatch(r"red_repair_iter\d+", stage_name):
|
|
113
|
+
return "red_repair"
|
|
114
|
+
return stage_name
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
CREATE TABLE IF NOT EXISTS devflow_idea_integrations (
|
|
2
|
+
idea_id TEXT PRIMARY KEY,
|
|
3
|
+
project_id TEXT NOT NULL,
|
|
4
|
+
run_id TEXT,
|
|
5
|
+
pipeline_dir TEXT,
|
|
6
|
+
status TEXT NOT NULL DEFAULT 'running',
|
|
7
|
+
exit_code INT,
|
|
8
|
+
iterations_used INT,
|
|
9
|
+
workflow_count INT,
|
|
10
|
+
side_effect_count INT,
|
|
11
|
+
side_effects JSONB,
|
|
12
|
+
implicated_users JSONB,
|
|
13
|
+
workflow_inventory JSONB,
|
|
14
|
+
validation_report JSONB,
|
|
15
|
+
red_package JSONB,
|
|
16
|
+
red_review JSONB,
|
|
17
|
+
green_package JSONB,
|
|
18
|
+
green_enrich JSONB,
|
|
19
|
+
commit_package JSONB,
|
|
20
|
+
failure_message TEXT,
|
|
21
|
+
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
22
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
CREATE INDEX IF NOT EXISTS idx_devflow_idea_integrations_project_status
|
|
26
|
+
ON devflow_idea_integrations(project_id, status, updated_at DESC);
|
|
27
|
+
|
|
28
|
+
ALTER TABLE devflow_idea_integrations
|
|
29
|
+
ADD COLUMN IF NOT EXISTS repair_cycles INT DEFAULT 0,
|
|
30
|
+
ADD COLUMN IF NOT EXISTS repair_patches_count INT DEFAULT 0,
|
|
31
|
+
ADD COLUMN IF NOT EXISTS repair_summary TEXT;
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
import logging
|
|
5
|
+
import os
|
|
6
|
+
import subprocess
|
|
7
|
+
from datetime import UTC, datetime
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
from typing import Any
|
|
10
|
+
from urllib.request import Request, urlopen
|
|
11
|
+
|
|
12
|
+
from ..devflow_state import _is_uuid_like
|
|
13
|
+
from ..project_registration.dag import _infer_owner_repo, _lookup_supabase_project_uuid
|
|
14
|
+
from ..project_registry import find_project_for_repo_root, resolve_project_entry
|
|
15
|
+
|
|
16
|
+
logger = logging.getLogger(__name__)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _keychain_get(service: str, account: str) -> str | None:
|
|
20
|
+
try:
|
|
21
|
+
proc = subprocess.run(
|
|
22
|
+
["security", "find-generic-password", "-s", service, "-a", account, "-w"],
|
|
23
|
+
capture_output=True,
|
|
24
|
+
text=True,
|
|
25
|
+
check=False,
|
|
26
|
+
timeout=10,
|
|
27
|
+
)
|
|
28
|
+
except Exception:
|
|
29
|
+
return None
|
|
30
|
+
if proc.returncode != 0:
|
|
31
|
+
return None
|
|
32
|
+
return proc.stdout.strip() or None
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def resolve_supabase_rest_config() -> tuple[str, str] | None:
|
|
36
|
+
if os.environ.get("PYTEST_CURRENT_TEST"):
|
|
37
|
+
return None
|
|
38
|
+
url = (
|
|
39
|
+
os.environ.get("DEVFLOW_SUPABASE_URL")
|
|
40
|
+
or os.environ.get("SUPABASE_URL")
|
|
41
|
+
or _keychain_get("Supabase URL", "Clarity")
|
|
42
|
+
)
|
|
43
|
+
key = (
|
|
44
|
+
os.environ.get("DEVFLOW_SUPABASE_SERVICE_KEY")
|
|
45
|
+
or os.environ.get("SUPABASE_SERVICE_ROLE_KEY")
|
|
46
|
+
or os.environ.get("SUPABASE_SERVICE_KEY")
|
|
47
|
+
or _keychain_get("Supabase Service Key", "Clarity")
|
|
48
|
+
)
|
|
49
|
+
if not url or not key:
|
|
50
|
+
return None
|
|
51
|
+
return url.rstrip("/"), key
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def postgrest_request(
|
|
55
|
+
*,
|
|
56
|
+
method: str,
|
|
57
|
+
url: str,
|
|
58
|
+
key: str,
|
|
59
|
+
body: Any | None = None,
|
|
60
|
+
prefer: str | None = None,
|
|
61
|
+
) -> Any:
|
|
62
|
+
payload = None if body is None else json.dumps(body).encode("utf-8")
|
|
63
|
+
req = Request(url, data=payload, method=method)
|
|
64
|
+
req.add_header("apikey", key)
|
|
65
|
+
req.add_header("Authorization", f"Bearer {key}")
|
|
66
|
+
if body is not None:
|
|
67
|
+
req.add_header("Content-Type", "application/json")
|
|
68
|
+
if prefer:
|
|
69
|
+
req.add_header("Prefer", prefer)
|
|
70
|
+
with urlopen(req, timeout=30) as resp:
|
|
71
|
+
raw = resp.read().decode("utf-8")
|
|
72
|
+
return json.loads(raw) if raw else None
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def resolve_authoritative_project_id(
|
|
76
|
+
*,
|
|
77
|
+
project_id: str,
|
|
78
|
+
repo_root: Path | None,
|
|
79
|
+
url: str,
|
|
80
|
+
key: str,
|
|
81
|
+
log_prefix: str,
|
|
82
|
+
idea_id: str,
|
|
83
|
+
run_id: str,
|
|
84
|
+
) -> str | None:
|
|
85
|
+
resolved_project_id = str(project_id or "").strip()
|
|
86
|
+
if not resolved_project_id or resolved_project_id.startswith("unregistered:"):
|
|
87
|
+
return None
|
|
88
|
+
if _is_uuid_like(resolved_project_id):
|
|
89
|
+
return resolved_project_id
|
|
90
|
+
if repo_root is None:
|
|
91
|
+
project_entry = resolve_project_entry(resolved_project_id)
|
|
92
|
+
repo_root_value = str((project_entry or {}).get("repo_root") or "").strip()
|
|
93
|
+
if repo_root_value:
|
|
94
|
+
repo_root = Path(repo_root_value).expanduser()
|
|
95
|
+
if repo_root is None:
|
|
96
|
+
logger.warning(
|
|
97
|
+
"%s: skipping sync for idea_id=%s run_id=%s because local project_id=%s is not canonical and repo_root is unavailable",
|
|
98
|
+
log_prefix,
|
|
99
|
+
idea_id,
|
|
100
|
+
run_id,
|
|
101
|
+
project_id,
|
|
102
|
+
)
|
|
103
|
+
return None
|
|
104
|
+
project_entry = find_project_for_repo_root(repo_root)
|
|
105
|
+
remote_url = str((project_entry or {}).get("remote_url") or "").strip() or None
|
|
106
|
+
project_name = str((project_entry or {}).get("name") or "").strip() or None
|
|
107
|
+
owner, repo = _infer_owner_repo(remote_url, repo_root, project_name)
|
|
108
|
+
try:
|
|
109
|
+
resolved_project_id = _lookup_supabase_project_uuid(
|
|
110
|
+
url=url,
|
|
111
|
+
key=key,
|
|
112
|
+
repo_root=repo_root,
|
|
113
|
+
remote_url=remote_url,
|
|
114
|
+
owner=owner,
|
|
115
|
+
repo=repo,
|
|
116
|
+
) or ""
|
|
117
|
+
except Exception as exc:
|
|
118
|
+
logger.warning(
|
|
119
|
+
"%s: skipping sync for idea_id=%s run_id=%s because canonical project UUID lookup failed for local project_id=%s: %s",
|
|
120
|
+
log_prefix,
|
|
121
|
+
idea_id,
|
|
122
|
+
run_id,
|
|
123
|
+
project_id,
|
|
124
|
+
exc,
|
|
125
|
+
)
|
|
126
|
+
return None
|
|
127
|
+
if not _is_uuid_like(resolved_project_id):
|
|
128
|
+
logger.warning(
|
|
129
|
+
"%s: skipping sync for idea_id=%s run_id=%s because canonical project UUID could not be resolved from local project_id=%s",
|
|
130
|
+
log_prefix,
|
|
131
|
+
idea_id,
|
|
132
|
+
run_id,
|
|
133
|
+
project_id,
|
|
134
|
+
)
|
|
135
|
+
return None
|
|
136
|
+
return resolved_project_id
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def upsert_idea_integration_row(
|
|
140
|
+
*,
|
|
141
|
+
idea_id: str,
|
|
142
|
+
project_id: str,
|
|
143
|
+
run_id: str,
|
|
144
|
+
repo_root: Path | None = None,
|
|
145
|
+
row: dict[str, Any],
|
|
146
|
+
log_prefix: str = "integration-supabase-sync",
|
|
147
|
+
) -> None:
|
|
148
|
+
config = resolve_supabase_rest_config()
|
|
149
|
+
if config is None:
|
|
150
|
+
return
|
|
151
|
+
url, key = config
|
|
152
|
+
resolved_project_id = resolve_authoritative_project_id(
|
|
153
|
+
project_id=project_id,
|
|
154
|
+
repo_root=repo_root,
|
|
155
|
+
url=url,
|
|
156
|
+
key=key,
|
|
157
|
+
log_prefix=log_prefix,
|
|
158
|
+
idea_id=idea_id,
|
|
159
|
+
run_id=run_id,
|
|
160
|
+
)
|
|
161
|
+
if not resolved_project_id:
|
|
162
|
+
return
|
|
163
|
+
payload = dict(row)
|
|
164
|
+
payload["idea_id"] = idea_id
|
|
165
|
+
payload["project_id"] = resolved_project_id
|
|
166
|
+
payload["run_id"] = run_id
|
|
167
|
+
payload.setdefault("updated_at", datetime.now(UTC).isoformat())
|
|
168
|
+
try:
|
|
169
|
+
postgrest_request(
|
|
170
|
+
method="POST",
|
|
171
|
+
url=f"{url}/rest/v1/devflow_idea_integrations?on_conflict=idea_id",
|
|
172
|
+
key=key,
|
|
173
|
+
body=[payload],
|
|
174
|
+
prefer="resolution=merge-duplicates",
|
|
175
|
+
)
|
|
176
|
+
except Exception:
|
|
177
|
+
pass
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""LLM execution adapters (CLI one-shot for now)."""
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
import shlex
|
|
5
|
+
import subprocess
|
|
6
|
+
from dataclasses import dataclass
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
|
|
9
|
+
from ..api_keys import bootstrap_provider_api_keys
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@dataclass(frozen=True)
|
|
13
|
+
class OneShotResult:
|
|
14
|
+
ok: bool
|
|
15
|
+
stdout: str
|
|
16
|
+
stderr: str
|
|
17
|
+
returncode: int
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def _normalize_timeout_output(value: str | bytes | None) -> str:
|
|
21
|
+
if value is None:
|
|
22
|
+
return ""
|
|
23
|
+
if isinstance(value, bytes):
|
|
24
|
+
return value.decode("utf-8", errors="replace")
|
|
25
|
+
return value
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def _split_base(cmd: str) -> list[str]:
|
|
29
|
+
parts = shlex.split(cmd)
|
|
30
|
+
return [p for p in parts if p]
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def run_one_shot(
|
|
34
|
+
*,
|
|
35
|
+
base_cmd: str,
|
|
36
|
+
delivery: str,
|
|
37
|
+
prompt: str,
|
|
38
|
+
cwd: Path,
|
|
39
|
+
timeout_seconds: int | None = None,
|
|
40
|
+
provider: str | None = None,
|
|
41
|
+
) -> OneShotResult:
|
|
42
|
+
"""Run a one-shot prompt via an external CLI.
|
|
43
|
+
|
|
44
|
+
delivery:
|
|
45
|
+
- argument: append prompt as a final argv element
|
|
46
|
+
- stdin: pass prompt via stdin
|
|
47
|
+
|
|
48
|
+
This is intentionally simple; streaming/resume can be added later.
|
|
49
|
+
"""
|
|
50
|
+
|
|
51
|
+
argv = _split_base(base_cmd)
|
|
52
|
+
if not argv:
|
|
53
|
+
raise RuntimeError("llm cli base command is empty")
|
|
54
|
+
|
|
55
|
+
child_env = os.environ.copy()
|
|
56
|
+
if provider:
|
|
57
|
+
bootstrap_provider_api_keys(env=child_env)
|
|
58
|
+
|
|
59
|
+
if delivery == "argument":
|
|
60
|
+
argv = argv + [prompt]
|
|
61
|
+
try:
|
|
62
|
+
p = subprocess.run(argv, cwd=str(cwd), text=True, capture_output=True, timeout=timeout_seconds, env=child_env)
|
|
63
|
+
except subprocess.TimeoutExpired as exc:
|
|
64
|
+
return OneShotResult(
|
|
65
|
+
ok=False,
|
|
66
|
+
stdout=_normalize_timeout_output(exc.stdout),
|
|
67
|
+
stderr=_normalize_timeout_output(exc.stderr) + f"\nTIMEOUT after {timeout_seconds}s",
|
|
68
|
+
returncode=124,
|
|
69
|
+
)
|
|
70
|
+
return OneShotResult(ok=p.returncode == 0, stdout=p.stdout, stderr=p.stderr, returncode=p.returncode)
|
|
71
|
+
|
|
72
|
+
if delivery == "stdin":
|
|
73
|
+
try:
|
|
74
|
+
p = subprocess.run(argv, cwd=str(cwd), text=True, input=prompt, capture_output=True, timeout=timeout_seconds, env=child_env)
|
|
75
|
+
except subprocess.TimeoutExpired as exc:
|
|
76
|
+
return OneShotResult(
|
|
77
|
+
ok=False,
|
|
78
|
+
stdout=_normalize_timeout_output(exc.stdout),
|
|
79
|
+
stderr=_normalize_timeout_output(exc.stderr) + f"\nTIMEOUT after {timeout_seconds}s",
|
|
80
|
+
returncode=124,
|
|
81
|
+
)
|
|
82
|
+
return OneShotResult(ok=p.returncode == 0, stdout=p.stdout, stderr=p.stderr, returncode=p.returncode)
|
|
83
|
+
|
|
84
|
+
raise RuntimeError(f"unsupported delivery: {delivery}")
|