1010 create_engine ,
1111 get_decision_state ,
1212 get_policy_items ,
13+ get_premise_value ,
1314 is_clarify ,
1415)
1516from context_compiler .engine import Engine
1617
1718EMPLOYEE_ACCESS = "employee_hr_access"
1819MANAGER_ACCESS = "manager_hr_access"
20+ LEAVE_CASE_PREMISE = "case concerns leave eligibility after a parental leave request"
21+ GENERAL_HANDBOOK_PREMISE = (
22+ "case concerns general employee handbook expectations for a new hire"
23+ )
24+ STAFFING_CASE_PREMISE = "case concerns staffing approval for a team reorganization"
1925
2026
2127class PolicyDocument (TypedDict ):
2228 document_id : str
2329 title : str
2430 audience : Literal ["employee" , "manager" , "executive" ]
2531 keywords : list [str ]
32+ relevance_tags : list [str ]
2633 content : str
2734
2835
@@ -39,22 +46,35 @@ class RetrievalTurnResult(TypedDict):
3946 retrieval_result : RetrievalResult
4047
4148
49+ CaseContext = Literal ["general_handbook_case" , "leave_case" , "staffing_case" ]
50+
51+
4252@dataclass
4353class HRPolicyRetriever :
4454 """Host-owned retrieval implementation with deterministic filtering."""
4555
4656 documents : list [PolicyDocument ] = field (default_factory = list )
4757
48- def search (self , query : str , * , allowed_audiences : set [str ]) -> RetrievalResult :
58+ def search (
59+ self ,
60+ query : str ,
61+ * ,
62+ allowed_audiences : set [str ],
63+ case_context : CaseContext | None ,
64+ ) -> RetrievalResult :
4965 eligible_documents = [
5066 document
5167 for document in self .documents
5268 if document ["audience" ] in allowed_audiences
5369 ]
70+ relevance_filtered_documents = filter_documents_by_case_context (
71+ eligible_documents ,
72+ case_context ,
73+ )
5474 normalized_query_terms = set (query .lower ().split ())
5575 returned_documents = [
5676 document
57- for document in eligible_documents
77+ for document in relevance_filtered_documents
5878 if normalized_query_terms & set (document ["keywords" ])
5979 ]
6080
@@ -77,20 +97,31 @@ def example_documents() -> list[PolicyDocument]:
7797 "title" : "Employee Handbook" ,
7898 "audience" : "employee" ,
7999 "keywords" : ["employee" , "handbook" , "benefits" , "leave" ],
100+ "relevance_tags" : ["general_handbook_case" , "general_hr" ],
80101 "content" : "General HR policy, leave policy, and workplace expectations." ,
81102 },
103+ {
104+ "document_id" : "leave_of_absence_policy" ,
105+ "title" : "Leave of Absence Policy" ,
106+ "audience" : "employee" ,
107+ "keywords" : ["leave" , "eligibility" , "parental" ],
108+ "relevance_tags" : ["leave_case" ],
109+ "content" : "Leave eligibility, parental leave steps, and required documentation." ,
110+ },
82111 {
83112 "document_id" : "manager_handbook" ,
84113 "title" : "Manager Handbook" ,
85114 "audience" : "manager" ,
86115 "keywords" : ["manager" , "handbook" , "approvals" , "staffing" ],
116+ "relevance_tags" : ["general_handbook_case" , "staffing_case" ],
87117 "content" : "Manager escalation guidance, staffing policy, and approvals." ,
88118 },
89119 {
90120 "document_id" : "executive_compensation_policy" ,
91121 "title" : "Executive Compensation Policy" ,
92122 "audience" : "executive" ,
93123 "keywords" : ["executive" , "compensation" , "bonus" , "board" ],
124+ "relevance_tags" : ["executive_only" ],
94125 "content" : "Executive compensation bands, board review, and bonus structure." ,
95126 },
96127 ]
@@ -130,6 +161,56 @@ def allowed_audiences_from_state(state: State) -> set[str]:
130161 return set ()
131162
132163
164+ def classify_premise_as_case_context (premise : str | None ) -> CaseContext | None :
165+ """Map saved HR case facts to a host-owned retrieval relevance context."""
166+
167+ if premise is None :
168+ return None
169+
170+ normalized_premise = premise .casefold ()
171+ if (
172+ "general employee handbook" in normalized_premise
173+ and "new hire" in normalized_premise
174+ ):
175+ return "general_handbook_case"
176+
177+ if (
178+ "leave eligibility" in normalized_premise
179+ and "parental leave" in normalized_premise
180+ ):
181+ return "leave_case"
182+
183+ if (
184+ "staffing approval" in normalized_premise
185+ and "team reorganization" in normalized_premise
186+ ):
187+ return "staffing_case"
188+
189+ return None
190+
191+
192+ def filter_documents_by_case_context (
193+ documents : list [PolicyDocument ],
194+ case_context : CaseContext | None ,
195+ ) -> list [PolicyDocument ]:
196+ """Limit relevance only within the already eligible document set."""
197+
198+ if case_context is None :
199+ return [
200+ document
201+ for document in documents
202+ if "general_handbook_case" in document ["relevance_tags" ]
203+ ]
204+
205+ relevant_documents = [
206+ document for document in documents if case_context in document ["relevance_tags" ]
207+ ]
208+ if relevant_documents :
209+ return relevant_documents
210+
211+ return []
212+
213+
133214def retrieve_hr_documents (
134215 query : str ,
135216 * ,
@@ -138,9 +219,11 @@ def retrieve_hr_documents(
138219) -> RetrievalResult :
139220 """Retrieve only documents the host deems eligible from compiler state."""
140221
222+ premise = get_premise_value (state )
141223 return retriever .search (
142224 query ,
143225 allowed_audiences = allowed_audiences_from_state (state ),
226+ case_context = classify_premise_as_case_context (premise ),
144227 )
145228
146229
0 commit comments