Repository navigation
Expand file tree
/
Copy pathworkflow.py
More file actions
298 lines (237 loc) · 6.94 KB
/
Copy pathworkflow.py
File metadata and controls
298 lines (237 loc) · 6.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
from __future__ import annotations
from dataclasses import dataclass
from typing import Callable
from crewai import Crew, Process, Task
from contract_agent import create_contract_agent
from intake_agent import create_intake_agent
from payment_agent import create_payment_agent
from review_agent import create_review_agent
from risk_agent import create_risk_agent
from valuation_agent import create_valuation_agent
@dataclass
class StageResult:
key: str
name: str
result: str
def _run_stage(
key: str,
name: str,
agent,
description: str,
status_callback: Callable[[str, str, int], None],
progress: int,
) -> StageResult:
status_callback(name, "Working", progress)
task = Task(
description=description,
expected_output=(
"Return a concise Markdown report. Clearly label VERIFIED FACTS, "
"CALCULATIONS, ASSUMPTIONS, EXCEPTIONS, and HUMAN CHECKS where applicable. "
"Never invent missing evidence."
),
agent=agent,
markdown=True,
)
crew = Crew(
agents=[agent],
tasks=[task],
process=Process.sequential,
verbose=False,
cache=True,
)
output = crew.kickoff()
status_callback(name, "Completed", progress)
return StageResult(key=key, name=name, result=str(output.raw))
def run_payment_review(
document_directory: str,
project_context: str,
status_callback: Callable[[str, str, int], None],
) -> list[StageResult]:
results: list[StageResult] = []
intake = _run_stage(
"intake",
"Intake & Evidence Agent",
create_intake_agent(),
f"""
You are the first stage of a construction payment review.
PROJECT CONTEXT:
{project_context}
DOCUMENT DIRECTORY:
{document_directory}
First use the Read project documents tool. Then create an evidence register:
- project/contract identifiers
- contractor/payee
- payment application/certificate number and period
- claimed gross value
- previous certified amount
- retention/deductions if stated
- schedule-of-values and key line items
- change orders/variations
- supporting records
- missing or unreadable information
Do not calculate or approve payment unless the source evidence supports it.
Use the Record audit event tool after completing your evidence extraction.
""",
status_callback,
10,
)
results.append(intake)
contract = _run_stage(
"contract",
"Contract Compliance Agent",
create_contract_agent(),
f"""
Review the construction payment application using the original documents and the Intake report below.
PROJECT CONTEXT:
{project_context}
DOCUMENT DIRECTORY:
{document_directory}
INTAKE REPORT:
{intake.result}
First use the Read project documents tool to verify the source evidence. Identify:
- payment prerequisites
- retainage rules
- approved change-order requirements
- required declarations/certificates/waivers
- notice or timing requirements
- contractual deductions
- conflicts between the contract and the application
Do not decide whether the payment should be approved. State what is supported, missing, or requires human interpretation.
Use the Record audit event tool.
""",
status_callback,
25,
)
results.append(contract)
valuation = _run_stage(
"valuation",
"Measurement & Valuation Agent",
create_valuation_agent(),
f"""
Validate quantities, rates and extensions for the payment application.
PROJECT CONTEXT:
{project_context}
DOCUMENT DIRECTORY:
{document_directory}
INTAKE REPORT:
{intake.result}
CONTRACT REPORT:
{contract.result}
First use the Read project documents tool. Compare schedule-of-values, claimed progress,
measurement/supporting records and approved changes where available.
Use the Calculate payment amount tool for arithmetic. Identify:
- arithmetic mismatches
- quantity/rate discrepancies
- unsupported progress claims
- change-order valuation issues
- items requiring human site/quantity verification
Never invent quantities or rates.
Use the Record audit event tool.
""",
status_callback,
40,
)
results.append(valuation)
payment = _run_stage(
"payment",
"Payment Reconciliation Agent",
create_payment_agent(),
f"""
Reconcile the payment application.
PROJECT CONTEXT:
{project_context}
DOCUMENT DIRECTORY:
{document_directory}
INTAKE REPORT:
{intake.result}
CONTRACT REPORT:
{contract.result}
VALUATION REPORT:
{valuation.result}
First use the Read project documents tool.
Determine, only from supported evidence:
- gross earned/current value
- less previous certified amount
- retention
- other deductions
- resulting net payment position
Use the Calculate payment amount tool for all arithmetic. If an input is unknown,
say UNKNOWN rather than assuming zero unless the source explicitly supports zero.
This is an analysis only. Do not authorize or execute payment.
Use the Record audit event tool.
""",
status_callback,
55,
)
results.append(payment)
risk = _run_stage(
"risk",
"Risk & Exceptions Agent",
create_risk_agent(),
f"""
Perform an independent controls review.
PROJECT CONTEXT:
{project_context}
DOCUMENT DIRECTORY:
{document_directory}
INTAKE:
{intake.result}
CONTRACT:
{contract.result}
VALUATION:
{valuation.result}
PAYMENT:
{payment.result}
First use the Read project documents tool. Use the Check required documents tool where useful.
Identify:
- missing required evidence
- conflicting figures
- duplicate or repeated billing indicators
- unsupported change orders
- unusual deductions or retention
- unresolved contract compliance issues
- items that require human/site verification
- any reason the automated analysis should not be relied upon without review
Do not label something fraudulent or non-compliant unless the evidence establishes that fact.
Use the Record audit event tool.
""",
status_callback,
70,
)
results.append(risk)
review = _run_stage(
"review",
"Human Review Briefing Agent",
create_review_agent(),
f"""
Prepare the final human review brief.
PROJECT CONTEXT:
{project_context}
INTAKE:
{intake.result}
CONTRACT:
{contract.result}
VALUATION:
{valuation.result}
PAYMENT:
{payment.result}
RISK:
{risk.result}
First use the Read project documents tool if any source fact needs verification.
Produce:
1. Executive summary
2. Evidence-backed payment position
3. Key calculations
4. Exceptions and missing evidence
5. Human verification checklist
6. Suggested next administrative action, expressed only as a workflow step (for example,
"human review required"), not as a payment approval or rejection
The human reviewer retains all decision authority. Never authorize, release, or execute payment.
Use the Record audit event tool.
""",
status_callback,
90,
)
results.append(review)
status_callback("Human Decision Gate", "Waiting for human decision", 100)
return results