Spaces:
Sleeping
Sleeping
Rajan Sharma
commited on
Update pipeline/run_two_phase.py
Browse files- pipeline/run_two_phase.py +25 -22
pipeline/run_two_phase.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
| 1 |
"""
|
| 2 |
Reference pipeline orchestrator.
|
| 3 |
-
|
| 4 |
"""
|
| 5 |
|
| 6 |
from pathlib import Path
|
|
@@ -12,12 +12,8 @@ from ..graders.rule_grader import grade
|
|
| 12 |
from .io_utils import load_json
|
| 13 |
|
| 14 |
# -------------------------
|
| 15 |
-
#
|
| 16 |
def call_model(system_prompt: str, user_prompt: str, temperature: float = 0.2, top_p: float = 0.9) -> str:
|
| 17 |
-
"""
|
| 18 |
-
Stub for LLM call. Should return the model's raw text output.
|
| 19 |
-
In production: plug into your provider (OpenAI, Azure, Anthropic, etc.)
|
| 20 |
-
"""
|
| 21 |
raise NotImplementedError("call_model must be implemented in your environment.")
|
| 22 |
# -------------------------
|
| 23 |
|
|
@@ -39,55 +35,62 @@ def run_clarityops(pack_dir: str) -> Tuple[Dict[str, Any], Any]:
|
|
| 39 |
inputs = load_json(pack / "inputs.json")
|
| 40 |
constraints = load_json(pack / "constraints.json")
|
| 41 |
schema_cfg = load_json(pack / "schema.json")
|
| 42 |
-
rubric = load_json(pack / "rubric.json")
|
| 43 |
-
expected = load_json(pack / "expected.json")
|
| 44 |
|
| 45 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 46 |
context_block = inputs.get("context", "No context provided.")
|
| 47 |
data_block = json.dumps(inputs.get("data_inputs", {}), ensure_ascii=False, indent=2)
|
| 48 |
constraints_block = json.dumps(constraints, ensure_ascii=False, indent=2)
|
| 49 |
|
| 50 |
# ---- Phase 1: Clarification Questions
|
| 51 |
user_prompt_phase1 = build_user_prompt(user_template, context_block, data_block, constraints_block)
|
| 52 |
-
# Tell the model explicitly: generate Phase 1 only
|
| 53 |
user_prompt_phase1 += "\n\n[INSTRUCTION TO MODEL] Produce **Phase 1** only. Do not produce Phase 2 yet."
|
| 54 |
-
|
| 55 |
clarif_raw = call_model(system_prompt, user_prompt_phase1)
|
| 56 |
-
# Expect clarif_raw to contain either "No clarifications required" or a numbered list of questions.
|
| 57 |
|
| 58 |
-
#
|
| 59 |
clarif_answers_path = pack / "clarifications.json"
|
| 60 |
if clarif_answers_path.exists():
|
| 61 |
clarif_answers = load_json(clarif_answers_path)
|
|
|
|
|
|
|
|
|
|
| 62 |
else:
|
| 63 |
-
|
| 64 |
-
raise RuntimeError("Clarification answers required. Provide packs/<scenario>/clarifications.json or implement an interactive flow.")
|
| 65 |
|
| 66 |
# Merge clarifications into inputs for Phase 2
|
| 67 |
merged_inputs = inputs.copy()
|
| 68 |
merged_inputs["clarifications"] = clarif_answers
|
| 69 |
|
| 70 |
# ---- Phase 2: Structured Analysis
|
| 71 |
-
user_prompt_phase2 = build_user_prompt(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 72 |
user_prompt_phase2 += "\n\n[INSTRUCTION TO MODEL] Produce **Phase 2** only (final structured analysis), using clarified inputs."
|
| 73 |
-
|
| 74 |
final_raw = call_model(system_prompt, user_prompt_phase2)
|
| 75 |
|
| 76 |
-
#
|
| 77 |
try:
|
| 78 |
-
# naive parse: assume JSON
|
| 79 |
output = json.loads(final_raw)
|
| 80 |
except Exception as e:
|
| 81 |
raise ValueError(f"Failed to parse model output as JSON. Raw:\n{final_raw}") from e
|
| 82 |
|
| 83 |
-
# Validators
|
| 84 |
schema_validator.assert_valid(output, str(root / "schemas" / "analysis_output.schema.json"))
|
| 85 |
unit_validator.assert_valid(output, str(root / "core" / "policy_global.json"))
|
| 86 |
math_validator.assert_valid(output)
|
| 87 |
policy_validator.assert_valid(output, str(pack / "constraints.json"))
|
| 88 |
|
| 89 |
-
#
|
| 90 |
-
grader_result = grade(output, str(
|
| 91 |
output["_grader"] = grader_result
|
|
|
|
| 92 |
|
| 93 |
return output, clarif_raw
|
|
|
|
| 1 |
"""
|
| 2 |
Reference pipeline orchestrator.
|
| 3 |
+
Wire into your LLM runner. Supports packs built from free-form scenarios.
|
| 4 |
"""
|
| 5 |
|
| 6 |
from pathlib import Path
|
|
|
|
| 12 |
from .io_utils import load_json
|
| 13 |
|
| 14 |
# -------------------------
|
| 15 |
+
# REPLACE with your actual LLM runner
|
| 16 |
def call_model(system_prompt: str, user_prompt: str, temperature: float = 0.2, top_p: float = 0.9) -> str:
|
|
|
|
|
|
|
|
|
|
|
|
|
| 17 |
raise NotImplementedError("call_model must be implemented in your environment.")
|
| 18 |
# -------------------------
|
| 19 |
|
|
|
|
| 35 |
inputs = load_json(pack / "inputs.json")
|
| 36 |
constraints = load_json(pack / "constraints.json")
|
| 37 |
schema_cfg = load_json(pack / "schema.json")
|
|
|
|
|
|
|
| 38 |
|
| 39 |
+
# Optional — only required if you want grading
|
| 40 |
+
rubric_path = pack / "rubric.json"
|
| 41 |
+
expected_path = pack / "expected.json"
|
| 42 |
+
rubric = load_json(rubric_path) if rubric_path.exists() else {"set_equals": [], "must_contain": [], "numeric_equals": []}
|
| 43 |
+
expected = load_json(expected_path) if expected_path.exists() else {"note": "No expected gold provided."}
|
| 44 |
+
|
| 45 |
+
# Build Phase 1 user prompt
|
| 46 |
context_block = inputs.get("context", "No context provided.")
|
| 47 |
data_block = json.dumps(inputs.get("data_inputs", {}), ensure_ascii=False, indent=2)
|
| 48 |
constraints_block = json.dumps(constraints, ensure_ascii=False, indent=2)
|
| 49 |
|
| 50 |
# ---- Phase 1: Clarification Questions
|
| 51 |
user_prompt_phase1 = build_user_prompt(user_template, context_block, data_block, constraints_block)
|
|
|
|
| 52 |
user_prompt_phase1 += "\n\n[INSTRUCTION TO MODEL] Produce **Phase 1** only. Do not produce Phase 2 yet."
|
|
|
|
| 53 |
clarif_raw = call_model(system_prompt, user_prompt_phase1)
|
|
|
|
| 54 |
|
| 55 |
+
# ---- Collect answers
|
| 56 |
clarif_answers_path = pack / "clarifications.json"
|
| 57 |
if clarif_answers_path.exists():
|
| 58 |
clarif_answers = load_json(clarif_answers_path)
|
| 59 |
+
# If the file is still the placeholder, raise to force operator to fill it
|
| 60 |
+
if clarif_answers.get("_note"):
|
| 61 |
+
raise RuntimeError(f"Clarification answers required. Edit and remove _note in: {clarif_answers_path}")
|
| 62 |
else:
|
| 63 |
+
raise RuntimeError(f"Clarification answers file missing: {clarif_answers_path}")
|
|
|
|
| 64 |
|
| 65 |
# Merge clarifications into inputs for Phase 2
|
| 66 |
merged_inputs = inputs.copy()
|
| 67 |
merged_inputs["clarifications"] = clarif_answers
|
| 68 |
|
| 69 |
# ---- Phase 2: Structured Analysis
|
| 70 |
+
user_prompt_phase2 = build_user_prompt(
|
| 71 |
+
user_template,
|
| 72 |
+
context_block,
|
| 73 |
+
json.dumps(merged_inputs, ensure_ascii=False, indent=2),
|
| 74 |
+
constraints_block
|
| 75 |
+
)
|
| 76 |
user_prompt_phase2 += "\n\n[INSTRUCTION TO MODEL] Produce **Phase 2** only (final structured analysis), using clarified inputs."
|
|
|
|
| 77 |
final_raw = call_model(system_prompt, user_prompt_phase2)
|
| 78 |
|
| 79 |
+
# Parse final output JSON
|
| 80 |
try:
|
|
|
|
| 81 |
output = json.loads(final_raw)
|
| 82 |
except Exception as e:
|
| 83 |
raise ValueError(f"Failed to parse model output as JSON. Raw:\n{final_raw}") from e
|
| 84 |
|
| 85 |
+
# Validators (hard guardrails)
|
| 86 |
schema_validator.assert_valid(output, str(root / "schemas" / "analysis_output.schema.json"))
|
| 87 |
unit_validator.assert_valid(output, str(root / "core" / "policy_global.json"))
|
| 88 |
math_validator.assert_valid(output)
|
| 89 |
policy_validator.assert_valid(output, str(pack / "constraints.json"))
|
| 90 |
|
| 91 |
+
# Optional grading
|
| 92 |
+
grader_result = grade(output, str(rubric_path)) if rubric_path.exists() else {"score": 0, "max_score": 0, "notes": ["No rubric."]}
|
| 93 |
output["_grader"] = grader_result
|
| 94 |
+
output["_clarifications_summary"] = clarif_raw
|
| 95 |
|
| 96 |
return output, clarif_raw
|