Parcourir la source

主机:按角色收紧脚本工具注册表

注册精简 Planner 输入、Direction client-key 保存、批量 Paragraph 操作和受保护 Validator evidence;统一工具失败 envelope,并从创作 preset 移除低效单条 Paragraph 路径。
SamLee il y a 17 heures
Parent
commit
43f09e8bf0
1 fichiers modifiés avec 70 ajouts et 121 suppressions
  1. 70 121
      script_build_host/src/script_build_host/tools/registry.py

+ 70 - 121
script_build_host/src/script_build_host/tools/registry.py

@@ -8,9 +8,9 @@ import json
 from functools import wraps
 from typing import Any
 
+from agent import FailureDetail, FailureDisposition, ToolExecutionError, ToolRegistry
 from agent.tools.models import ToolResult
 
-from agent import FailureDetail, FailureDisposition, ToolExecutionError, ToolRegistry
 from script_build_host.domain.errors import ScriptBuildError
 
 from .failures import classify_script_tool_failure
@@ -85,7 +85,7 @@ def register_script_tools(registry: ToolRegistry, gateway: LegacyScriptToolGatew
         parent_task_id: str | None = None,
         context: dict[str, Any] | None = None,
     ) -> str | ToolResult:
-        """Validate and atomically create Tasks from complete business contracts."""
+        """Resolve Planner-owned semantics and atomically create Tasks."""
 
         contracts = _structured_object_list(contracts, "contracts", max_items=50)
         return _json(
@@ -110,6 +110,7 @@ def register_script_tools(registry: ToolRegistry, gateway: LegacyScriptToolGatew
         validation_id: str | None = None,
         replacement_contract: dict[str, Any] | None = None,
         child_contracts: list[dict[str, Any]] | None = None,
+        selected_decision_ids: list[str] | None = None,
         context: dict[str, Any] | None = None,
     ) -> str | ToolResult:
         """Apply one phase-aware Planner decision after contract and boundary checks."""
@@ -137,6 +138,7 @@ def register_script_tools(registry: ToolRegistry, gateway: LegacyScriptToolGatew
             validation_id=validation_id,
             replacement_contract=replacement_contract,
             child_contracts=child_contracts,
+            selected_decision_ids=selected_decision_ids or [],
             context=context or {},
         )
         result_json = _json(result)
@@ -879,15 +881,15 @@ def _plan_script_tasks_schema() -> dict[str, Any]:
         "function": {
             "name": "plan_script_tasks",
             "description": (
-                "Create bounded Tasks. Every contracts item must be a complete "
-                "script-task-contract/v1 object; do not send preset or display fields."
+                "Create bounded Tasks from business semantics and accepted Decision IDs. "
+                "The Host derives artifact refs, digests, write scope, schema and budget."
             ),
             "parameters": {
                 "type": "object",
                 "properties": {
                     "contracts": {
                         "type": "array",
-                        "items": _task_contract_schema(),
+                        "items": _planner_task_input_schema(),
                         "minItems": 1,
                         "maxItems": 50,
                     },
@@ -906,8 +908,8 @@ def _decide_script_task_schema() -> dict[str, Any]:
         "function": {
             "name": "decide_script_task",
             "description": (
-                "Apply one validated Planner decision. Replacement and child contracts, "
-                "when required by the action, must be complete script-task-contract/v1 objects."
+                "Apply one Planner decision. Use selected_decision_ids to close Compose or "
+                "Portfolio; the Host derives every immutable adoption field."
             ),
             "parameters": {
                 "type": "object",
@@ -929,15 +931,25 @@ def _decide_script_task_schema() -> dict[str, Any]:
                     "reason": {"type": "string"},
                     "validation_id": {"type": ["string", "null"], "default": None},
                     "replacement_contract": {
-                        "oneOf": [_task_contract_schema(), {"type": "null"}],
+                        "oneOf": [
+                            _planner_task_input_schema(),
+                            _root_replacement_schema(),
+                            {"type": "null"},
+                        ],
                         "default": None,
                     },
                     "child_contracts": {
                         "type": "array",
-                        "items": _task_contract_schema(),
+                        "items": _planner_task_input_schema(),
                         "maxItems": 50,
                         "default": [],
                     },
+                    "selected_decision_ids": {
+                        "type": "array",
+                        "items": {"type": "string"},
+                        "uniqueItems": True,
+                        "default": [],
+                    },
                 },
                 "required": ["task_id", "action", "reason"],
                 "additionalProperties": False,
@@ -946,7 +958,7 @@ def _decide_script_task_schema() -> dict[str, Any]:
     }
 
 
-def _task_contract_schema() -> dict[str, Any]:
+def _planner_task_input_schema() -> dict[str, Any]:
     task_kinds = [
         "direction",
         "pattern-retrieval",
@@ -960,40 +972,9 @@ def _task_contract_schema() -> dict[str, Any]:
         "compose",
         "candidate-portfolio",
     ]
-    artifact_ref = {
-        "type": "object",
-        "properties": {
-            "uri": {"type": "string"},
-            "kind": {"type": "string"},
-            "version": {"type": ["string", "null"]},
-            "digest": {"type": ["string", "null"]},
-            "summary": {"type": ["string", "null"]},
-            "metadata": {"type": "object"},
-        },
-        "required": ["uri", "kind"],
-        "additionalProperties": False,
-    }
-    decision_ref = {
-        "type": "object",
-        "properties": {
-            "decision_id": {"type": "string"},
-            "artifact_ref": artifact_ref,
-            "scope_ref": {
-                "type": "string",
-                "description": "A script-build:// control URI from the accepted decision.",
-            },
-            "expected_task_kind": {"type": "string", "enum": task_kinds},
-        },
-        "required": ["decision_id", "artifact_ref", "scope_ref", "expected_task_kind"],
-        "additionalProperties": False,
-    }
     return {
         "type": "object",
         "properties": {
-            "schema_version": {
-                "type": "string",
-                "const": "script-task-contract/v1",
-            },
             "task_kind": {"type": "string", "enum": task_kinds},
             "scope_ref": {
                 "type": "string",
@@ -1012,34 +993,26 @@ def _task_contract_schema() -> dict[str, Any]:
                 ],
             },
             "objective": {"type": "string", "maxLength": 2000},
-            "input_decision_refs": {"type": "array", "items": decision_ref},
-            "base_artifact_ref": {
-                "oneOf": [artifact_ref, {"type": "null"}],
+            "input_decision_ids": {
+                "type": "array",
+                "items": {"type": "string"},
+                "uniqueItems": True,
+                "default": [],
             },
-            "write_scope": {
+            "base_decision_id": {"type": ["string", "null"], "default": None},
+            "comparison_decision_ids": {
                 "type": "array",
-                "items": {
-                    "type": "string",
-                    "description": "A bounded script-build:// control URI.",
-                },
+                "items": {"type": "string"},
+                "uniqueItems": True,
+                "default": [],
             },
-            "gap_ref": {"type": ["string", "null"]},
-            "output_schema": {
-                "type": "string",
-                "enum": [
-                    "script-direction/v1",
-                    "evidence-record/v1",
-                    "structure-artifact/v1",
-                    "paragraph-artifact/v1",
-                    "paragraph-patch/v1",
-                    "element-set-artifact/v1",
-                    "element-set-patch/v1",
-                    "comparison-artifact/v1",
-                    "structured-script/v1",
-                    "candidate-portfolio/v1",
-                ],
-                "description": "Must match task_kind; use evidence-record/v1 for retrieval.",
+            "supersedes_decision_ids": {
+                "type": "array",
+                "items": {"type": "string"},
+                "uniqueItems": True,
+                "default": [],
             },
+            "gap_ref": {"type": ["string", "null"]},
             "criteria": {
                 "type": "array",
                 "minItems": 1,
@@ -1055,36 +1028,6 @@ def _task_contract_schema() -> dict[str, Any]:
                     "additionalProperties": False,
                 },
             },
-            "budget": {
-                "type": "object",
-                "properties": {
-                    "max_attempts": {"type": "integer", "minimum": 1, "maximum": 4},
-                    "max_tokens": {
-                        "type": "integer",
-                        "minimum": 500000,
-                        "maximum": 1000000,
-                    },
-                    "max_seconds": {"type": "integer", "minimum": 1, "maximum": 900},
-                    "max_external_queries": {
-                        "type": "integer",
-                        "minimum": 1,
-                        "maximum": 40,
-                    },
-                    "max_no_improvement": {
-                        "type": "integer",
-                        "minimum": 1,
-                        "maximum": 3,
-                    },
-                },
-                "required": [
-                    "max_attempts",
-                    "max_tokens",
-                    "max_seconds",
-                    "max_external_queries",
-                    "max_no_improvement",
-                ],
-                "additionalProperties": False,
-            },
             "goal_ids": {
                 "type": "array",
                 "maxItems": 30,
@@ -1095,41 +1038,33 @@ def _task_contract_schema() -> dict[str, Any]:
                     "by this Task. Compose and Portfolio include every Goal."
                 ),
             },
-            "supersedes_decision_ids": {"type": "array", "items": {"type": "string"}},
-            "candidate_closure_decision_refs": {"type": "array", "items": decision_ref},
-            "adopted_decision_ids": {"type": "array", "items": {"type": "string"}},
-            "held_or_rejected_decision_ids": {
-                "type": "array",
-                "items": {"type": "string"},
-            },
-            "compose_order": {"type": "array", "items": {"type": "string"}},
-            "comparison_decision_refs": {"type": "array", "items": decision_ref},
         },
         "required": [
-            "schema_version",
             "task_kind",
             "scope_ref",
             "intent_class",
             "objective",
-            "input_decision_refs",
-            "base_artifact_ref",
-            "write_scope",
-            "gap_ref",
-            "output_schema",
             "criteria",
-            "budget",
             "goal_ids",
-            "supersedes_decision_ids",
-            "candidate_closure_decision_refs",
-            "adopted_decision_ids",
-            "held_or_rejected_decision_ids",
-            "compose_order",
-            "comparison_decision_refs",
+            "input_decision_ids",
         ],
         "additionalProperties": False,
     }
 
 
+def _root_replacement_schema() -> dict[str, Any]:
+    return {
+        "type": "object",
+        "properties": {
+            "objective": {"type": "string", "maxLength": 2000},
+            "acceptance_criteria": {"type": "array", "items": {"type": "object"}},
+            "context_refs": {"type": "array", "items": {"type": "string"}},
+        },
+        "required": ["objective", "acceptance_criteria", "context_refs"],
+        "additionalProperties": False,
+    }
+
+
 def _save_direction_candidate_schema() -> dict[str, Any]:
     constraint = {
         "type": "object",
@@ -1170,8 +1105,12 @@ def _save_direction_candidate_schema() -> dict[str, Any]:
                         "items": {
                             "type": "object",
                             "properties": {
-                                "goal_id": {"type": "string", "minLength": 1},
-                                "parent_goal_id": {"type": "string", "minLength": 1},
+                                "client_key": {"type": "string", "minLength": 1, "maxLength": 128},
+                                "parent_client_key": {
+                                    "type": ["string", "null"],
+                                    "minLength": 1,
+                                    "maxLength": 128,
+                                },
                                 "statement": {"type": "string", "minLength": 1},
                                 "rationale": {"type": "string", "minLength": 1},
                                 "success_criteria": {
@@ -1182,7 +1121,7 @@ def _save_direction_candidate_schema() -> dict[str, Any]:
                                 },
                             },
                             "required": [
-                                "goal_id",
+                                "client_key",
                                 "statement",
                                 "rationale",
                                 "success_criteria",
@@ -1290,8 +1229,18 @@ def _submit_validation_schema() -> dict[str, Any]:
                                     "enum": ["passed", "failed", "inconclusive"],
                                 },
                                 "reason": {"type": "string", "maxLength": 300},
+                                "evidence_refs": {
+                                    "type": "array",
+                                    "items": artifact_ref,
+                                    "maxItems": 64,
+                                },
                             },
-                            "required": ["criterion_id", "verdict", "reason"],
+                            "required": [
+                                "criterion_id",
+                                "verdict",
+                                "reason",
+                                "evidence_refs",
+                            ],
                             "additionalProperties": False,
                         },
                     },