Rajan Sharma commited on
Commit
4b221eb
·
verified ·
1 Parent(s): 820b3f9

Create run_two_phase.py

Browse files
Files changed (1) hide show
  1. pipeline/run_two_phase.py +93 -0
pipeline/run_two_phase.py ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Reference pipeline orchestrator.
3
+ This module shows how to wire the two-phase flow. Replace `call_model` with your LLM runner.
4
+ """
5
+
6
+ from pathlib import Path
7
+ from typing import Tuple, Dict, Any
8
+ import json
9
+
10
+ from ..validators import schema_validator, unit_validator, math_validator, policy_validator
11
+ from ..graders.rule_grader import grade
12
+ from .io_utils import load_json
13
+
14
+ # -------------------------
15
+ # Replace this with your LLM runner.
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
+
24
+ def build_user_prompt(template_text: str, context: str, data_inputs: str, constraints: str) -> str:
25
+ return (
26
+ template_text
27
+ .replace("{CONTEXT}", context)
28
+ .replace("{DATA_INPUTS}", data_inputs)
29
+ .replace("{CONSTRAINTS}", constraints)
30
+ )
31
+
32
+ def run_clarityops(pack_dir: str) -> Tuple[Dict[str, Any], Any]:
33
+ pack = Path(pack_dir)
34
+ root = pack.parents[1]
35
+
36
+ system_prompt = (root / "prompts" / "system_two_phase.txt").read_text(encoding="utf-8")
37
+ user_template = (root / "prompts" / "user_template.txt").read_text(encoding="utf-8")
38
+
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
+ # Build the human-readable blocks
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
+ # Option A: automated answers for CI (if provided)
59
+ clarif_answers_path = pack / "clarifications.json"
60
+ if clarif_answers_path.exists():
61
+ clarif_answers = load_json(clarif_answers_path)
62
+ else:
63
+ # Option B: interactive collection (replace as needed)
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(user_template, context_block, json.dumps(merged_inputs, ensure_ascii=False, indent=2), constraints_block)
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
+ # Expect final_raw to be JSON or parseable. If your model returns markdown, strip code fences first.
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
+ # Grading (optional): compare to expected
90
+ grader_result = grade(output, str(pack / "rubric.json"))
91
+ output["_grader"] = grader_result
92
+
93
+ return output, clarif_raw