millforge 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. millforge/__init__.py +1174 -0
  2. millforge/_forge/LICENSE +21 -0
  3. millforge/_forge/PROVENANCE.json +295 -0
  4. millforge/_forge/UPDATE_POLICY.md +24 -0
  5. millforge/_forge/__init__.py +14 -0
  6. millforge/_forge/adapter.py +2232 -0
  7. millforge/_forge/base_runner.py +121 -0
  8. millforge/_forge/clients/__init__.py +10 -0
  9. millforge/_forge/clients/base.py +200 -0
  10. millforge/_forge/context/__init__.py +23 -0
  11. millforge/_forge/context/manager.py +178 -0
  12. millforge/_forge/context/strategies.py +335 -0
  13. millforge/_forge/core/__init__.py +16 -0
  14. millforge/_forge/core/inference.py +433 -0
  15. millforge/_forge/core/messages.py +119 -0
  16. millforge/_forge/core/runner.py +479 -0
  17. millforge/_forge/core/steps.py +108 -0
  18. millforge/_forge/core/workflow.py +400 -0
  19. millforge/_forge/errors.py +222 -0
  20. millforge/_forge/guardrails/__init__.py +21 -0
  21. millforge/_forge/guardrails/error_tracker.py +71 -0
  22. millforge/_forge/guardrails/guardrails.py +194 -0
  23. millforge/_forge/guardrails/nudge.py +47 -0
  24. millforge/_forge/guardrails/response_validator.py +119 -0
  25. millforge/_forge/guardrails/step_enforcer.py +183 -0
  26. millforge/_forge/prompts/__init__.py +16 -0
  27. millforge/_forge/prompts/nudges.py +95 -0
  28. millforge/_forge/prompts/templates.py +285 -0
  29. millforge/_version.py +3 -0
  30. millforge/artifacts.py +570 -0
  31. millforge/base/__init__.py +97 -0
  32. millforge/base/composition.py +402 -0
  33. millforge/base/context.py +285 -0
  34. millforge/base/harness.py +138 -0
  35. millforge/base/identity.py +465 -0
  36. millforge/base/options.py +34 -0
  37. millforge/base/platform.py +17 -0
  38. millforge/base/prompt.py +317 -0
  39. millforge/base/runner.py +546 -0
  40. millforge/compiled_plan.py +970 -0
  41. millforge/compiler/__init__.py +231 -0
  42. millforge/compiler/artifact_validation.py +257 -0
  43. millforge/compiler/canonicalization.py +169 -0
  44. millforge/compiler/capabilities.py +66 -0
  45. millforge/compiler/catalogs.py +500 -0
  46. millforge/compiler/diagnostics.py +491 -0
  47. millforge/compiler/graph.py +678 -0
  48. millforge/compiler/lowering.py +198 -0
  49. millforge/compiler/output.py +692 -0
  50. millforge/compiler/parsing.py +1424 -0
  51. millforge/compiler/requests.py +1180 -0
  52. millforge/compiler/schema_validation.py +272 -0
  53. millforge/compiler/semantic.py +490 -0
  54. millforge/compiler/service.py +448 -0
  55. millforge/compiler/source.py +375 -0
  56. millforge/compiler/validators.py +184 -0
  57. millforge/connectors/__init__.py +95 -0
  58. millforge/connectors/admission.py +801 -0
  59. millforge/connectors/broker.py +202 -0
  60. millforge/connectors/contracts.py +1159 -0
  61. millforge/connectors/diagnostics.py +189 -0
  62. millforge/connectors/fake.py +66 -0
  63. millforge/connectors/runtime.py +236 -0
  64. millforge/contracts.py +2860 -0
  65. millforge/custom_tools/__init__.py +67 -0
  66. millforge/custom_tools/compiler.py +724 -0
  67. millforge/custom_tools/contracts.py +1093 -0
  68. millforge/custom_tools/diagnostics.py +205 -0
  69. millforge/eval_artifacts.py +952 -0
  70. millforge/eval_boundary.py +2435 -0
  71. millforge/eval_fixtures/__init__.py +1 -0
  72. millforge/eval_fixtures/default_pack/__init__.py +1 -0
  73. millforge/eval_fixtures/default_pack/fixtures/fixture.08a.bug_diagnosis.traceback.v1.json +52 -0
  74. millforge/eval_fixtures/default_pack/fixtures/fixture.08a.direct_edit.import_sort.v1.json +52 -0
  75. millforge/eval_fixtures/default_pack/fixtures/fixture.08a.evidence_discipline.no_source_change.v1.json +51 -0
  76. millforge/eval_fixtures/default_pack/fixtures/fixture.08a.false_closure.visible_green.v1.json +52 -0
  77. millforge/eval_fixtures/default_pack/fixtures/fixture.08a.multi_file.api_contract.v1.json +54 -0
  78. millforge/eval_fixtures/default_pack/fixtures/fixture.08a.recovery.malformed_artifact.v1.json +54 -0
  79. millforge/eval_fixtures/default_pack/manifest.json +12 -0
  80. millforge/eval_modes.py +1282 -0
  81. millforge/eval_presets.py +1398 -0
  82. millforge/eval_reports.py +2517 -0
  83. millforge/eval_suite.py +2429 -0
  84. millforge/eval_trials.py +2632 -0
  85. millforge/eval_workflow.py +794 -0
  86. millforge/exceptions.py +122 -0
  87. millforge/model_backend.py +2098 -0
  88. millforge/protocols.py +340 -0
  89. millforge/py.typed +0 -0
  90. millforge/runtime.py +1791 -0
  91. millforge/testing/__init__.py +1089 -0
  92. millforge/tools/__init__.py +83 -0
  93. millforge/tools/builtin_runtime.py +1339 -0
  94. millforge/tools/builtins.py +773 -0
  95. millforge/tools/execution.py +1545 -0
  96. millforge/tools/path_policy.py +155 -0
  97. millforge/tools/pi_compat/PI_LICENSE +21 -0
  98. millforge/tools/pi_compat/PROVENANCE.json +55 -0
  99. millforge/tools/pi_compat/UPDATE_POLICY.md +36 -0
  100. millforge/tools/pi_compat/__init__.py +34 -0
  101. millforge/tools/pi_compat/contracts.py +49 -0
  102. millforge/tools/pi_compat/editing.py +390 -0
  103. millforge/tools/pi_compat/mutations.py +57 -0
  104. millforge/tools/pi_compat/operations.py +401 -0
  105. millforge/tools/pi_compat/paths.py +155 -0
  106. millforge/tools/pi_compat/process.py +1375 -0
  107. millforge/tools/pi_compat/search.py +738 -0
  108. millforge/tools/pi_compat/truncation.py +267 -0
  109. millforge/tools/pi_compat_catalog.py +396 -0
  110. millforge/tools/pi_compat_runtime.py +460 -0
  111. millforge/tools/registry.py +553 -0
  112. millforge/tools/results.py +533 -0
  113. millforge-0.1.0.dist-info/METADATA +844 -0
  114. millforge-0.1.0.dist-info/RECORD +116 -0
  115. millforge-0.1.0.dist-info/WHEEL +4 -0
  116. millforge-0.1.0.dist-info/licenses/LICENSE +201 -0
@@ -0,0 +1,448 @@
1
+ """Default validated compiler service orchestration."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from collections.abc import Mapping
6
+ from typing import Protocol
7
+
8
+ from millforge import canonical_json_serialize, verify_compiled_plan_sha256
9
+ from millforge.compiled_plan import CompiledHarnessPlan
10
+ from millforge.compiled_plan import calculate_compiled_plan_sha256
11
+ from millforge.compiler.catalogs import (
12
+ ModelProfileCatalogSnapshot,
13
+ ToolCatalogSnapshot,
14
+ )
15
+ from millforge.compiler.canonicalization import source_sha256
16
+ from millforge.compiler.diagnostics import (
17
+ CompilerDiagnostic,
18
+ CompilerPhase,
19
+ DiagnosticField,
20
+ DiagnosticSeverity,
21
+ bound_diagnostics,
22
+ )
23
+ from millforge.compiler.lowering import (
24
+ CompiledPlanValidationError,
25
+ LoweringInvariantError,
26
+ SourceSemanticHashError,
27
+ lower_resolved_harness,
28
+ )
29
+ from millforge.compiler.output import persist_compile_outputs
30
+ from millforge.compiler.parsing import ParsedHarnessSource
31
+ from millforge.compiler.requests import (
32
+ CompileStatus,
33
+ DefaultHarnessCompileRequestAdmission,
34
+ HarnessCompileRequest,
35
+ HarnessCompileRequestAdmission,
36
+ HarnessCompileResult,
37
+ HarnessRequestAdmissionResult,
38
+ PlanCommitCertainty,
39
+ _post_parse_source_diagnostics,
40
+ )
41
+ from millforge.compiler.source import HarnessSource
42
+ from millforge.compiler.semantic import ResolvedHarness, compile_semantic_from_admission
43
+ from millforge.contracts import CapabilityEnvelope
44
+
45
+
46
+ class HarnessCompiler(Protocol):
47
+ """Public typed compiler service boundary."""
48
+
49
+ def compile(
50
+ self,
51
+ request: HarnessCompileRequest,
52
+ *,
53
+ tool_catalog: ToolCatalogSnapshot,
54
+ model_profile_catalog: ModelProfileCatalogSnapshot,
55
+ ) -> HarnessCompileResult:
56
+ """Compile an admitted harness request."""
57
+ ...
58
+
59
+
60
+ class InMemoryHarnessCompileError(Exception):
61
+ """Raised when a validated in-memory harness source cannot compile."""
62
+
63
+ diagnostics: tuple[CompilerDiagnostic, ...]
64
+
65
+ def __init__(self, diagnostics: tuple[CompilerDiagnostic, ...]) -> None:
66
+ self.diagnostics = tuple(
67
+ diagnostic.model_copy(update={"source_reference": None})
68
+ for diagnostic in bound_diagnostics(diagnostics)
69
+ )
70
+ super().__init__(
71
+ self.diagnostics[0].message
72
+ if self.diagnostics
73
+ else "in-memory harness compilation failed"
74
+ )
75
+
76
+
77
+ def compile(
78
+ request: HarnessCompileRequest,
79
+ *,
80
+ tool_catalog: ToolCatalogSnapshot,
81
+ model_profile_catalog: ModelProfileCatalogSnapshot,
82
+ ) -> HarnessCompileResult:
83
+ """Compile an admitted request through semantic validation, lowering, and output."""
84
+ return _compile_validated(
85
+ request,
86
+ tool_catalog=tool_catalog,
87
+ model_profile_catalog=model_profile_catalog,
88
+ )
89
+
90
+
91
+ def compile_harness_source_in_memory(
92
+ *,
93
+ request_id: str,
94
+ source: HarnessSource,
95
+ stage_kind_id: str,
96
+ legal_terminal_results: tuple[str, ...],
97
+ capability_envelope: CapabilityEnvelope,
98
+ tool_catalog: ToolCatalogSnapshot,
99
+ model_profile_catalog: ModelProfileCatalogSnapshot,
100
+ ) -> CompiledHarnessPlan:
101
+ """Compile a validated harness source without filesystem admission or publication."""
102
+ request = HarnessCompileRequest(
103
+ request_id=request_id,
104
+ source_path="in-memory",
105
+ source_root="/",
106
+ source_format="json",
107
+ output_dir="in-memory",
108
+ output_root="/",
109
+ expected_harness_id=source.harness_id,
110
+ stage_kind_id=stage_kind_id,
111
+ legal_terminal_results=legal_terminal_results,
112
+ capability_envelope=capability_envelope,
113
+ )
114
+ parsed_source = ParsedHarnessSource(
115
+ source=source,
116
+ source_document_sha256="0" * 64,
117
+ )
118
+ diagnostics = _post_parse_source_diagnostics(
119
+ request=request,
120
+ parsed=parsed_source,
121
+ )
122
+ if diagnostics:
123
+ raise InMemoryHarnessCompileError(diagnostics)
124
+
125
+ try:
126
+ outcome = _compile_post_parse(
127
+ HarnessRequestAdmissionResult(
128
+ request=request,
129
+ parsed_source=parsed_source,
130
+ ),
131
+ tool_catalog=tool_catalog,
132
+ model_profile_catalog=model_profile_catalog,
133
+ )
134
+ except Exception as exc:
135
+ raise InMemoryHarnessCompileError(
136
+ (
137
+ _diagnostic(
138
+ "MF-I001",
139
+ CompilerPhase.INTERNAL,
140
+ "Compiler service failed internally.",
141
+ fields={"error_type": type(exc).__name__},
142
+ ),
143
+ )
144
+ ) from exc
145
+ if isinstance(outcome, HarnessCompileResult):
146
+ raise InMemoryHarnessCompileError(outcome.diagnostics)
147
+ return outcome
148
+
149
+
150
+ def _compile_validated(
151
+ request: HarnessCompileRequest,
152
+ *,
153
+ tool_catalog: ToolCatalogSnapshot,
154
+ model_profile_catalog: ModelProfileCatalogSnapshot,
155
+ ) -> HarnessCompileResult:
156
+ """Private implementation for the public typed compiler entry point."""
157
+ try:
158
+ admission = DefaultHarnessCompileRequestAdmission().admit(
159
+ request.model_dump(mode="python")
160
+ )
161
+ return _compile_admitted(
162
+ admission,
163
+ tool_catalog=tool_catalog,
164
+ model_profile_catalog=model_profile_catalog,
165
+ )
166
+ except Exception as exc:
167
+ return _failed_result(
168
+ request=request,
169
+ phase=CompilerPhase.INTERNAL,
170
+ diagnostics=(
171
+ _diagnostic(
172
+ "MF-I001",
173
+ CompilerPhase.INTERNAL,
174
+ "Compiler service failed internally.",
175
+ fields={"error_type": type(exc).__name__},
176
+ ),
177
+ ),
178
+ )
179
+
180
+
181
+ def compile_raw(
182
+ raw_request: Mapping[str, object],
183
+ *,
184
+ tool_catalog: ToolCatalogSnapshot,
185
+ model_profile_catalog: ModelProfileCatalogSnapshot,
186
+ admission: HarnessCompileRequestAdmission | None = None,
187
+ ) -> HarnessCompileResult:
188
+ """Admit a raw request, then compile through the validated typed service."""
189
+ admitted = (admission or DefaultHarnessCompileRequestAdmission()).admit(raw_request)
190
+ if admitted.result is None and admitted.request is not None:
191
+ request = admitted.request
192
+ else:
193
+ request = HarnessCompileRequest.model_construct(
194
+ request_id="request.invalid",
195
+ source_path="invalid",
196
+ source_root="/",
197
+ source_format="json",
198
+ output_dir="invalid",
199
+ output_root="/",
200
+ expected_harness_id="millforge.invalid",
201
+ stage_kind_id="builder",
202
+ legal_terminal_results=("BLOCKED",),
203
+ capability_envelope={"grants": ()},
204
+ )
205
+ try:
206
+ return _compile_admitted(
207
+ admitted,
208
+ tool_catalog=tool_catalog,
209
+ model_profile_catalog=model_profile_catalog,
210
+ )
211
+ except Exception as exc:
212
+ return _failed_result(
213
+ request=request,
214
+ phase=CompilerPhase.INTERNAL,
215
+ diagnostics=(
216
+ _diagnostic(
217
+ "MF-I001",
218
+ CompilerPhase.INTERNAL,
219
+ "Compiler service failed internally.",
220
+ fields={"error_type": type(exc).__name__},
221
+ ),
222
+ ),
223
+ )
224
+
225
+
226
+ def _compile_admitted(
227
+ admission: HarnessRequestAdmissionResult,
228
+ *,
229
+ tool_catalog: ToolCatalogSnapshot,
230
+ model_profile_catalog: ModelProfileCatalogSnapshot,
231
+ ) -> HarnessCompileResult:
232
+ if admission.result is not None:
233
+ return admission.result
234
+ assert admission.request is not None
235
+ assert admission.parsed_source is not None
236
+ outcome = _compile_post_parse(
237
+ admission,
238
+ tool_catalog=tool_catalog,
239
+ model_profile_catalog=model_profile_catalog,
240
+ )
241
+ if isinstance(outcome, HarnessCompileResult):
242
+ return outcome
243
+ return persist_compile_outputs(
244
+ request=admission.request,
245
+ plan=outcome,
246
+ source_document_sha256=admission.parsed_source.source_document_sha256,
247
+ )
248
+
249
+
250
+ def _compile_post_parse(
251
+ admission: HarnessRequestAdmissionResult,
252
+ *,
253
+ tool_catalog: ToolCatalogSnapshot,
254
+ model_profile_catalog: ModelProfileCatalogSnapshot,
255
+ ) -> CompiledHarnessPlan | HarnessCompileResult:
256
+ """Run the shared semantic, lowering, and compiled-hash phases."""
257
+ assert admission.request is not None
258
+ assert admission.parsed_source is not None
259
+ source = admission.parsed_source.source
260
+ semantic = compile_semantic_from_admission(
261
+ admission,
262
+ source,
263
+ tool_snapshot=tool_catalog,
264
+ model_profile_snapshot=model_profile_catalog,
265
+ )
266
+ if semantic.frontend_result is not None:
267
+ return semantic.frontend_result
268
+ if semantic.resolved_harness is None or semantic.diagnostics:
269
+ return _failed_result(
270
+ request=admission.request,
271
+ phase=_failure_phase(semantic.diagnostics),
272
+ diagnostics=semantic.diagnostics
273
+ or (
274
+ _diagnostic(
275
+ "MF-I001",
276
+ CompilerPhase.INTERNAL,
277
+ "Semantic compilation returned no resolved harness.",
278
+ ),
279
+ ),
280
+ source_document_sha256=admission.parsed_source.source_document_sha256,
281
+ )
282
+
283
+ try:
284
+ plan = lower_resolved_harness(semantic.resolved_harness)
285
+ except SourceSemanticHashError as exc:
286
+ return _failed_result(
287
+ request=admission.request,
288
+ phase=CompilerPhase.LOWERING,
289
+ diagnostics=(
290
+ _diagnostic(
291
+ "MF-L003",
292
+ CompilerPhase.LOWERING,
293
+ "Source semantic hash calculation failed during lowering.",
294
+ fields={"error_type": type(exc).__name__},
295
+ ),
296
+ ),
297
+ source_document_sha256=admission.parsed_source.source_document_sha256,
298
+ )
299
+ except CompiledPlanValidationError as exc:
300
+ return _lowering_failed_result(
301
+ request=admission.request,
302
+ source_document_sha256=admission.parsed_source.source_document_sha256,
303
+ resolved=semantic.resolved_harness,
304
+ code="MF-L002",
305
+ message="Compiled plan model validation failed during lowering.",
306
+ error_type=type(exc).__name__,
307
+ )
308
+ except LoweringInvariantError as exc:
309
+ return _lowering_failed_result(
310
+ request=admission.request,
311
+ source_document_sha256=admission.parsed_source.source_document_sha256,
312
+ resolved=semantic.resolved_harness,
313
+ code="MF-L001",
314
+ message="Lowering invariant failed.",
315
+ error_type=type(exc).__name__,
316
+ )
317
+
318
+ hash_failure = _compiled_hash_failure(plan)
319
+ if hash_failure is not None:
320
+ return _failed_result(
321
+ request=admission.request,
322
+ phase=CompilerPhase.LOWERING,
323
+ diagnostics=(hash_failure,),
324
+ source_document_sha256=admission.parsed_source.source_document_sha256,
325
+ source_sha256=plan.source_sha256,
326
+ harness_id=plan.harness_id,
327
+ )
328
+
329
+ return plan
330
+
331
+
332
+ def _compiled_hash_failure(plan: object) -> CompilerDiagnostic | None:
333
+ try:
334
+ payload = plan.model_dump(mode="json") # type: ignore[attr-defined]
335
+ raw = canonical_json_serialize(payload)
336
+ computed = calculate_compiled_plan_sha256(payload)
337
+ if computed != plan.compiled_sha256: # type: ignore[attr-defined]
338
+ return _compiled_hash_diagnostic(computed_hash=computed)
339
+ verified, verified_computed, warnings, _restored = verify_compiled_plan_sha256(
340
+ raw,
341
+ expected_compiled_hash=plan.compiled_sha256, # type: ignore[attr-defined]
342
+ expected_harness_id=plan.harness_id, # type: ignore[attr-defined]
343
+ expected_harness_version=plan.harness_version, # type: ignore[attr-defined]
344
+ )
345
+ except Exception as exc:
346
+ return _compiled_hash_diagnostic(error_type=type(exc).__name__)
347
+ if verified and verified_computed == plan.compiled_sha256: # type: ignore[attr-defined]
348
+ return None
349
+ computed_hash = verified_computed if verified_computed else computed
350
+ return _compiled_hash_diagnostic(
351
+ warning_count=len(warnings),
352
+ computed_hash=computed_hash,
353
+ )
354
+
355
+
356
+ def _compiled_hash_diagnostic(
357
+ *,
358
+ warning_count: int | None = None,
359
+ computed_hash: str | None = None,
360
+ error_type: str | None = None,
361
+ ) -> CompilerDiagnostic:
362
+ fields: dict[str, str | int] = {}
363
+ if warning_count is not None:
364
+ fields["warning_count"] = warning_count
365
+ if computed_hash is not None:
366
+ fields["computed_hash"] = computed_hash
367
+ if error_type is not None:
368
+ fields["error_type"] = error_type
369
+ return _diagnostic(
370
+ "MF-L004",
371
+ CompilerPhase.LOWERING,
372
+ "Compiled plan canonical hash verification failed.",
373
+ fields=fields,
374
+ )
375
+
376
+
377
+ def _failed_result(
378
+ *,
379
+ request: HarnessCompileRequest,
380
+ phase: CompilerPhase,
381
+ diagnostics: tuple[CompilerDiagnostic, ...],
382
+ source_document_sha256: str | None = None,
383
+ source_sha256: str | None = None,
384
+ harness_id: str | None = None,
385
+ ) -> HarnessCompileResult:
386
+ return HarnessCompileResult(
387
+ request_id=request.request_id,
388
+ status=CompileStatus.FAILED,
389
+ plan_commit_certainty=PlanCommitCertainty.ABSENT,
390
+ failure_phase=phase,
391
+ source_document_sha256=source_document_sha256,
392
+ source_sha256=source_sha256,
393
+ harness_id=harness_id,
394
+ diagnostics=bound_diagnostics(diagnostics),
395
+ )
396
+
397
+
398
+ def _lowering_failed_result(
399
+ *,
400
+ request: HarnessCompileRequest,
401
+ source_document_sha256: str,
402
+ resolved: ResolvedHarness,
403
+ code: str,
404
+ message: str,
405
+ error_type: str,
406
+ ) -> HarnessCompileResult:
407
+ try:
408
+ semantic_hash = source_sha256(resolved)
409
+ except Exception:
410
+ semantic_hash = None
411
+ return _failed_result(
412
+ request=request,
413
+ phase=CompilerPhase.LOWERING,
414
+ diagnostics=(
415
+ _diagnostic(
416
+ code,
417
+ CompilerPhase.LOWERING,
418
+ message,
419
+ fields={"error_type": error_type},
420
+ ),
421
+ ),
422
+ source_document_sha256=source_document_sha256,
423
+ source_sha256=semantic_hash,
424
+ harness_id=resolved.source.harness_id,
425
+ )
426
+
427
+
428
+ def _failure_phase(diagnostics: tuple[CompilerDiagnostic, ...]) -> CompilerPhase:
429
+ return diagnostics[0].phase if diagnostics else CompilerPhase.INTERNAL
430
+
431
+
432
+ def _diagnostic(
433
+ code: str,
434
+ phase: CompilerPhase,
435
+ message: str,
436
+ *,
437
+ fields: Mapping[str, str | int] | None = None,
438
+ ) -> CompilerDiagnostic:
439
+ return CompilerDiagnostic(
440
+ code=code,
441
+ severity=DiagnosticSeverity.ERROR,
442
+ phase=phase,
443
+ message=message,
444
+ fields=tuple(
445
+ DiagnosticField(key=key, value=value)
446
+ for key, value in sorted((fields or {}).items())
447
+ ),
448
+ )