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.
- millforge/__init__.py +1174 -0
- millforge/_forge/LICENSE +21 -0
- millforge/_forge/PROVENANCE.json +295 -0
- millforge/_forge/UPDATE_POLICY.md +24 -0
- millforge/_forge/__init__.py +14 -0
- millforge/_forge/adapter.py +2232 -0
- millforge/_forge/base_runner.py +121 -0
- millforge/_forge/clients/__init__.py +10 -0
- millforge/_forge/clients/base.py +200 -0
- millforge/_forge/context/__init__.py +23 -0
- millforge/_forge/context/manager.py +178 -0
- millforge/_forge/context/strategies.py +335 -0
- millforge/_forge/core/__init__.py +16 -0
- millforge/_forge/core/inference.py +433 -0
- millforge/_forge/core/messages.py +119 -0
- millforge/_forge/core/runner.py +479 -0
- millforge/_forge/core/steps.py +108 -0
- millforge/_forge/core/workflow.py +400 -0
- millforge/_forge/errors.py +222 -0
- millforge/_forge/guardrails/__init__.py +21 -0
- millforge/_forge/guardrails/error_tracker.py +71 -0
- millforge/_forge/guardrails/guardrails.py +194 -0
- millforge/_forge/guardrails/nudge.py +47 -0
- millforge/_forge/guardrails/response_validator.py +119 -0
- millforge/_forge/guardrails/step_enforcer.py +183 -0
- millforge/_forge/prompts/__init__.py +16 -0
- millforge/_forge/prompts/nudges.py +95 -0
- millforge/_forge/prompts/templates.py +285 -0
- millforge/_version.py +3 -0
- millforge/artifacts.py +570 -0
- millforge/base/__init__.py +97 -0
- millforge/base/composition.py +402 -0
- millforge/base/context.py +285 -0
- millforge/base/harness.py +138 -0
- millforge/base/identity.py +465 -0
- millforge/base/options.py +34 -0
- millforge/base/platform.py +17 -0
- millforge/base/prompt.py +317 -0
- millforge/base/runner.py +546 -0
- millforge/compiled_plan.py +970 -0
- millforge/compiler/__init__.py +231 -0
- millforge/compiler/artifact_validation.py +257 -0
- millforge/compiler/canonicalization.py +169 -0
- millforge/compiler/capabilities.py +66 -0
- millforge/compiler/catalogs.py +500 -0
- millforge/compiler/diagnostics.py +491 -0
- millforge/compiler/graph.py +678 -0
- millforge/compiler/lowering.py +198 -0
- millforge/compiler/output.py +692 -0
- millforge/compiler/parsing.py +1424 -0
- millforge/compiler/requests.py +1180 -0
- millforge/compiler/schema_validation.py +272 -0
- millforge/compiler/semantic.py +490 -0
- millforge/compiler/service.py +448 -0
- millforge/compiler/source.py +375 -0
- millforge/compiler/validators.py +184 -0
- millforge/connectors/__init__.py +95 -0
- millforge/connectors/admission.py +801 -0
- millforge/connectors/broker.py +202 -0
- millforge/connectors/contracts.py +1159 -0
- millforge/connectors/diagnostics.py +189 -0
- millforge/connectors/fake.py +66 -0
- millforge/connectors/runtime.py +236 -0
- millforge/contracts.py +2860 -0
- millforge/custom_tools/__init__.py +67 -0
- millforge/custom_tools/compiler.py +724 -0
- millforge/custom_tools/contracts.py +1093 -0
- millforge/custom_tools/diagnostics.py +205 -0
- millforge/eval_artifacts.py +952 -0
- millforge/eval_boundary.py +2435 -0
- millforge/eval_fixtures/__init__.py +1 -0
- millforge/eval_fixtures/default_pack/__init__.py +1 -0
- millforge/eval_fixtures/default_pack/fixtures/fixture.08a.bug_diagnosis.traceback.v1.json +52 -0
- millforge/eval_fixtures/default_pack/fixtures/fixture.08a.direct_edit.import_sort.v1.json +52 -0
- millforge/eval_fixtures/default_pack/fixtures/fixture.08a.evidence_discipline.no_source_change.v1.json +51 -0
- millforge/eval_fixtures/default_pack/fixtures/fixture.08a.false_closure.visible_green.v1.json +52 -0
- millforge/eval_fixtures/default_pack/fixtures/fixture.08a.multi_file.api_contract.v1.json +54 -0
- millforge/eval_fixtures/default_pack/fixtures/fixture.08a.recovery.malformed_artifact.v1.json +54 -0
- millforge/eval_fixtures/default_pack/manifest.json +12 -0
- millforge/eval_modes.py +1282 -0
- millforge/eval_presets.py +1398 -0
- millforge/eval_reports.py +2517 -0
- millforge/eval_suite.py +2429 -0
- millforge/eval_trials.py +2632 -0
- millforge/eval_workflow.py +794 -0
- millforge/exceptions.py +122 -0
- millforge/model_backend.py +2098 -0
- millforge/protocols.py +340 -0
- millforge/py.typed +0 -0
- millforge/runtime.py +1791 -0
- millforge/testing/__init__.py +1089 -0
- millforge/tools/__init__.py +83 -0
- millforge/tools/builtin_runtime.py +1339 -0
- millforge/tools/builtins.py +773 -0
- millforge/tools/execution.py +1545 -0
- millforge/tools/path_policy.py +155 -0
- millforge/tools/pi_compat/PI_LICENSE +21 -0
- millforge/tools/pi_compat/PROVENANCE.json +55 -0
- millforge/tools/pi_compat/UPDATE_POLICY.md +36 -0
- millforge/tools/pi_compat/__init__.py +34 -0
- millforge/tools/pi_compat/contracts.py +49 -0
- millforge/tools/pi_compat/editing.py +390 -0
- millforge/tools/pi_compat/mutations.py +57 -0
- millforge/tools/pi_compat/operations.py +401 -0
- millforge/tools/pi_compat/paths.py +155 -0
- millforge/tools/pi_compat/process.py +1375 -0
- millforge/tools/pi_compat/search.py +738 -0
- millforge/tools/pi_compat/truncation.py +267 -0
- millforge/tools/pi_compat_catalog.py +396 -0
- millforge/tools/pi_compat_runtime.py +460 -0
- millforge/tools/registry.py +553 -0
- millforge/tools/results.py +533 -0
- millforge-0.1.0.dist-info/METADATA +844 -0
- millforge-0.1.0.dist-info/RECORD +116 -0
- millforge-0.1.0.dist-info/WHEEL +4 -0
- millforge-0.1.0.dist-info/licenses/LICENSE +201 -0
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
"""Custom tool compiler diagnostic contracts."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from collections.abc import Mapping
|
|
6
|
+
from enum import Enum
|
|
7
|
+
from typing import Any
|
|
8
|
+
|
|
9
|
+
from pydantic import (
|
|
10
|
+
BaseModel,
|
|
11
|
+
ConfigDict,
|
|
12
|
+
Field,
|
|
13
|
+
StrictStr,
|
|
14
|
+
field_validator,
|
|
15
|
+
model_validator,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
from millforge.compiler.diagnostics import detect_secret_candidate
|
|
19
|
+
from millforge.compiler.validators import validate_lower_field_key, validate_utf8_size
|
|
20
|
+
from millforge.contracts import RedactionPolicy, redact_diagnostic_text
|
|
21
|
+
|
|
22
|
+
MAX_CUSTOM_TOOL_DIAGNOSTIC_MESSAGE_UTF8 = 1024
|
|
23
|
+
MAX_CUSTOM_TOOL_DIAGNOSTIC_EVIDENCE_UTF8 = 512
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class CustomToolDiagnosticSeverity(str, Enum):
|
|
27
|
+
"""Closed custom-tool diagnostic severity values."""
|
|
28
|
+
|
|
29
|
+
ERROR = "error"
|
|
30
|
+
WARNING = "warning"
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class CustomToolDiagnosticPhase(str, Enum):
|
|
34
|
+
"""Closed custom-tool diagnostic phase values."""
|
|
35
|
+
|
|
36
|
+
SOURCE = "source"
|
|
37
|
+
DECLARATION = "declaration"
|
|
38
|
+
POLICY = "policy"
|
|
39
|
+
COMPILATION = "compilation"
|
|
40
|
+
DIAGNOSTIC = "diagnostic"
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class CustomToolDiagnosticCode(str, Enum):
|
|
44
|
+
"""Stable custom-tool compiler diagnostic codes."""
|
|
45
|
+
|
|
46
|
+
SOURCE_MALFORMED = "MF-CT001_SOURCE_MALFORMED"
|
|
47
|
+
SECRET_MATERIAL = "MF-CT002_SECRET_MATERIAL"
|
|
48
|
+
RUNTIME_KIND_UNSUPPORTED = "MF-CT003_RUNTIME_KIND_UNSUPPORTED"
|
|
49
|
+
EXECUTABLE_MATERIAL = "MF-CT004_EXECUTABLE_MATERIAL"
|
|
50
|
+
DUPLICATE_TOOL = "MF-CT005_DUPLICATE_TOOL"
|
|
51
|
+
DUPLICATE_MODEL_TOOL_NAME = "MF-CT006_DUPLICATE_MODEL_TOOL_NAME"
|
|
52
|
+
DUPLICATE_IMPLEMENTATION_ID = "MF-CT007_DUPLICATE_IMPLEMENTATION_ID"
|
|
53
|
+
INPUT_SCHEMA_UNSUPPORTED = "MF-CT008_INPUT_SCHEMA_UNSUPPORTED"
|
|
54
|
+
OUTPUT_SCHEMA_UNSUPPORTED = "MF-CT009_OUTPUT_SCHEMA_UNSUPPORTED"
|
|
55
|
+
DESCRIPTION_UNSAFE = "MF-CT010_DESCRIPTION_UNSAFE"
|
|
56
|
+
CAPABILITY_MISSING = "MF-CT011_CAPABILITY_MISSING"
|
|
57
|
+
CAPABILITY_UNKNOWN = "MF-CT012_CAPABILITY_UNKNOWN"
|
|
58
|
+
ARTIFACT_POLICY_INVALID = "MF-CT013_ARTIFACT_POLICY_INVALID"
|
|
59
|
+
APPROVAL_POLICY_INVALID = "MF-CT014_APPROVAL_POLICY_INVALID"
|
|
60
|
+
FORBIDDEN_TOOL_COMPILED = "MF-CT015_FORBIDDEN_TOOL_COMPILED"
|
|
61
|
+
TIMEOUT_POLICY_INVALID = "MF-CT016_TIMEOUT_POLICY_INVALID"
|
|
62
|
+
OUTPUT_POLICY_INVALID = "MF-CT017_OUTPUT_POLICY_INVALID"
|
|
63
|
+
HASH_MISMATCH = "MF-CT018_HASH_MISMATCH"
|
|
64
|
+
DESCRIPTOR_PROJECTION_FAILED = "MF-CT019_DESCRIPTOR_PROJECTION_FAILED"
|
|
65
|
+
|
|
66
|
+
SOURCE_INVALID = SOURCE_MALFORMED
|
|
67
|
+
DECLARATION_INVALID = DESCRIPTOR_PROJECTION_FAILED
|
|
68
|
+
LIMIT_EXCEEDED = SOURCE_MALFORMED
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
class CustomToolDiagnosticEvidence(BaseModel):
|
|
72
|
+
"""Immutable redacted scalar evidence for custom-tool diagnostics."""
|
|
73
|
+
|
|
74
|
+
model_config = ConfigDict(frozen=True, extra="forbid")
|
|
75
|
+
|
|
76
|
+
key: StrictStr
|
|
77
|
+
value: StrictStr
|
|
78
|
+
|
|
79
|
+
@field_validator("key")
|
|
80
|
+
@classmethod
|
|
81
|
+
def _key_valid(cls, value: str) -> str:
|
|
82
|
+
return validate_lower_field_key(value)
|
|
83
|
+
|
|
84
|
+
@field_validator("value")
|
|
85
|
+
@classmethod
|
|
86
|
+
def _value_redacted(cls, value: str) -> str:
|
|
87
|
+
return redact_custom_tool_text(
|
|
88
|
+
value, maximum=MAX_CUSTOM_TOOL_DIAGNOSTIC_EVIDENCE_UTF8
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
class CustomToolDiagnostic(BaseModel):
|
|
93
|
+
"""Stable custom-tool diagnostic with redacted bounded evidence."""
|
|
94
|
+
|
|
95
|
+
model_config = ConfigDict(frozen=True, extra="forbid")
|
|
96
|
+
|
|
97
|
+
code: CustomToolDiagnosticCode
|
|
98
|
+
severity: CustomToolDiagnosticSeverity
|
|
99
|
+
phase: CustomToolDiagnosticPhase
|
|
100
|
+
location: StrictStr | None = None
|
|
101
|
+
path: StrictStr | None = None
|
|
102
|
+
message: StrictStr
|
|
103
|
+
evidence: tuple[CustomToolDiagnosticEvidence, ...] = Field(default_factory=tuple)
|
|
104
|
+
|
|
105
|
+
@field_validator("location", "path")
|
|
106
|
+
@classmethod
|
|
107
|
+
def _optional_location_valid(cls, value: str | None) -> str | None:
|
|
108
|
+
if value is None:
|
|
109
|
+
return None
|
|
110
|
+
return validate_utf8_size(value, "diagnostic location", 256)
|
|
111
|
+
|
|
112
|
+
@field_validator("message")
|
|
113
|
+
@classmethod
|
|
114
|
+
def _message_redacted(cls, value: str) -> str:
|
|
115
|
+
return redact_custom_tool_text(
|
|
116
|
+
value, maximum=MAX_CUSTOM_TOOL_DIAGNOSTIC_MESSAGE_UTF8
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
@model_validator(mode="after")
|
|
120
|
+
def _location_or_path_required(self) -> CustomToolDiagnostic:
|
|
121
|
+
if self.location is None and self.path is None:
|
|
122
|
+
raise ValueError("diagnostic requires location or path")
|
|
123
|
+
return self
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def custom_tool_diagnostic_sort_key(
|
|
127
|
+
diagnostic: CustomToolDiagnostic,
|
|
128
|
+
) -> tuple[str, str, str, str, str, str, tuple[tuple[str, str], ...]]:
|
|
129
|
+
"""Return the canonical ordering key for non-semantic diagnostic lists."""
|
|
130
|
+
return (
|
|
131
|
+
diagnostic.code.value,
|
|
132
|
+
diagnostic.severity.value,
|
|
133
|
+
diagnostic.phase.value,
|
|
134
|
+
diagnostic.path or "",
|
|
135
|
+
diagnostic.location or "",
|
|
136
|
+
diagnostic.message,
|
|
137
|
+
tuple((item.key, item.value) for item in diagnostic.evidence),
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def redact_custom_tool_text(value: Any, *, maximum: int) -> str:
|
|
142
|
+
"""Return bounded diagnostic text with secret-looking material redacted."""
|
|
143
|
+
text = str(value)
|
|
144
|
+
policy = RedactionPolicy()
|
|
145
|
+
if detect_secret_candidate(
|
|
146
|
+
field_path="/custom_tool_diagnostic",
|
|
147
|
+
field_name="custom_tool_diagnostic",
|
|
148
|
+
value=text,
|
|
149
|
+
policy=policy,
|
|
150
|
+
):
|
|
151
|
+
return policy.replacement
|
|
152
|
+
return validate_utf8_size(
|
|
153
|
+
redact_diagnostic_text(text, policy=policy), "diagnostic", maximum
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def custom_tool_diagnostic(
|
|
158
|
+
code: CustomToolDiagnosticCode,
|
|
159
|
+
*,
|
|
160
|
+
phase: CustomToolDiagnosticPhase,
|
|
161
|
+
message: str,
|
|
162
|
+
location: str | None = None,
|
|
163
|
+
path: str | None = None,
|
|
164
|
+
severity: CustomToolDiagnosticSeverity = CustomToolDiagnosticSeverity.ERROR,
|
|
165
|
+
evidence: Mapping[str, Any] | None = None,
|
|
166
|
+
) -> CustomToolDiagnostic:
|
|
167
|
+
"""Build a deterministic custom-tool diagnostic."""
|
|
168
|
+
fields = tuple(
|
|
169
|
+
CustomToolDiagnosticEvidence(key=str(key), value=str(value))
|
|
170
|
+
for key, value in sorted(
|
|
171
|
+
(evidence or {}).items(), key=lambda item: str(item[0])
|
|
172
|
+
)
|
|
173
|
+
)
|
|
174
|
+
return CustomToolDiagnostic(
|
|
175
|
+
code=code,
|
|
176
|
+
severity=severity,
|
|
177
|
+
phase=phase,
|
|
178
|
+
location=location,
|
|
179
|
+
path=path,
|
|
180
|
+
message=message,
|
|
181
|
+
evidence=fields,
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
def malformed_input_diagnostic(
|
|
186
|
+
*,
|
|
187
|
+
phase: CustomToolDiagnosticPhase,
|
|
188
|
+
model_name: str,
|
|
189
|
+
path: str = "/",
|
|
190
|
+
missing_field: str | None = None,
|
|
191
|
+
code: CustomToolDiagnosticCode = CustomToolDiagnosticCode.SOURCE_MALFORMED,
|
|
192
|
+
) -> CustomToolDiagnostic:
|
|
193
|
+
"""Represent malformed raw input without exposing validator exception text."""
|
|
194
|
+
evidence: dict[str, str] = {"model": model_name}
|
|
195
|
+
message = "Custom tool input is malformed."
|
|
196
|
+
if missing_field is not None:
|
|
197
|
+
message = "Custom tool input is missing a required field."
|
|
198
|
+
evidence["field"] = missing_field
|
|
199
|
+
return custom_tool_diagnostic(
|
|
200
|
+
code,
|
|
201
|
+
phase=phase,
|
|
202
|
+
path=path,
|
|
203
|
+
message=message,
|
|
204
|
+
evidence=evidence,
|
|
205
|
+
)
|