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,202 @@
1
+ """Connector-scoped broker contracts for runtime invocation."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from collections.abc import Mapping
6
+ from types import MappingProxyType
7
+ from typing import Any, Protocol
8
+
9
+ from pydantic import (
10
+ BaseModel,
11
+ ConfigDict,
12
+ Field,
13
+ StrictBool,
14
+ StrictFloat,
15
+ StrictStr,
16
+ field_validator,
17
+ model_validator,
18
+ )
19
+
20
+ from millforge import (
21
+ IdempotencyClass,
22
+ SideEffectCertainty,
23
+ ToolExecutionStatus,
24
+ )
25
+ from millforge.compiler.validators import validate_nonblank, validate_sha256
26
+ from millforge.connectors.contracts import MAX_CONNECTOR_ID_UTF8
27
+ from millforge.tools.results import ToolExecutionErrorCode
28
+
29
+
30
+ class ConnectorInvocationRequest(BaseModel):
31
+ """Narrow runtime request passed to connector brokers."""
32
+
33
+ model_config = ConfigDict(frozen=True, extra="forbid", arbitrary_types_allowed=True)
34
+
35
+ connector_id: StrictStr
36
+ provider_tool_name: StrictStr
37
+ tool_id: StrictStr
38
+ tool_version: int = Field(ge=1)
39
+ descriptor_sha256: StrictStr
40
+ connector_identity_sha256: StrictStr
41
+ discovery_snapshot_sha256: StrictStr
42
+ raw_tool_sha256: StrictStr
43
+ arguments: Mapping[str, Any]
44
+ request_id: StrictStr
45
+ run_id: StrictStr
46
+ stage_plane: StrictStr
47
+ stage_kind_id: StrictStr
48
+ stage_node_id: StrictStr
49
+ timeout_seconds: StrictFloat
50
+ deadline_remaining_seconds: StrictFloat
51
+ cancellation_requested: StrictBool
52
+ cancellation_id: StrictStr
53
+ idempotency_key: StrictStr | None = None
54
+
55
+ @field_validator("arguments", mode="before")
56
+ @classmethod
57
+ def _arguments_frozen(cls, value: Any) -> MappingProxyType[str, Any]:
58
+ if not isinstance(value, Mapping):
59
+ raise ValueError("arguments must be a JSON object")
60
+ return MappingProxyType(dict(value))
61
+
62
+ @model_validator(mode="after")
63
+ def _request_valid(self) -> ConnectorInvocationRequest:
64
+ self._validate_strings()
65
+ return self
66
+
67
+ @classmethod
68
+ def from_runtime(
69
+ cls,
70
+ *,
71
+ connector_id: str,
72
+ provider_tool_name: str,
73
+ tool_id: str,
74
+ tool_version: int,
75
+ descriptor_sha256: str,
76
+ connector_identity_sha256: str,
77
+ discovery_snapshot_sha256: str,
78
+ raw_tool_sha256: str,
79
+ arguments: Mapping[str, Any],
80
+ request_id: str,
81
+ run_id: str,
82
+ stage_plane: str,
83
+ stage_kind_id: str,
84
+ stage_node_id: str,
85
+ timeout_seconds: float,
86
+ deadline_remaining_seconds: float,
87
+ cancellation_requested: bool,
88
+ cancellation_id: str,
89
+ idempotency_key: str | None,
90
+ ) -> ConnectorInvocationRequest:
91
+ """Build a broker request from runtime-owned values only."""
92
+ return cls(
93
+ connector_id=connector_id,
94
+ provider_tool_name=provider_tool_name,
95
+ tool_id=tool_id,
96
+ tool_version=tool_version,
97
+ descriptor_sha256=descriptor_sha256,
98
+ connector_identity_sha256=connector_identity_sha256,
99
+ discovery_snapshot_sha256=discovery_snapshot_sha256,
100
+ raw_tool_sha256=raw_tool_sha256,
101
+ arguments=MappingProxyType(dict(arguments)),
102
+ request_id=request_id,
103
+ run_id=run_id,
104
+ stage_plane=stage_plane,
105
+ stage_kind_id=stage_kind_id,
106
+ stage_node_id=stage_node_id,
107
+ timeout_seconds=timeout_seconds,
108
+ deadline_remaining_seconds=deadline_remaining_seconds,
109
+ cancellation_requested=cancellation_requested,
110
+ cancellation_id=cancellation_id,
111
+ idempotency_key=idempotency_key,
112
+ )
113
+
114
+ def _validate_strings(self) -> None:
115
+ validate_nonblank(self.connector_id, "connector_id")
116
+ validate_nonblank(self.provider_tool_name, "provider_tool_name")
117
+ validate_nonblank(self.tool_id, "tool_id")
118
+ validate_nonblank(self.request_id, "request_id")
119
+ validate_nonblank(self.run_id, "run_id")
120
+ validate_nonblank(self.stage_plane, "stage_plane")
121
+ validate_nonblank(self.stage_kind_id, "stage_kind_id")
122
+ validate_nonblank(self.stage_node_id, "stage_node_id")
123
+ validate_nonblank(self.cancellation_id, "cancellation_id")
124
+ validate_sha256(self.descriptor_sha256, "descriptor_sha256")
125
+ validate_sha256(self.connector_identity_sha256, "connector_identity_sha256")
126
+ validate_sha256(self.discovery_snapshot_sha256, "discovery_snapshot_sha256")
127
+ validate_sha256(self.raw_tool_sha256, "raw_tool_sha256")
128
+ if len(self.connector_id.encode("utf-8")) > MAX_CONNECTOR_ID_UTF8:
129
+ raise ValueError("connector_id exceeds connector limit")
130
+ if self.idempotency_key is not None:
131
+ validate_nonblank(self.idempotency_key, "idempotency_key")
132
+
133
+
134
+ class ConnectorBrokerOutcome(BaseModel):
135
+ """Deterministic broker result before executor output validation."""
136
+
137
+ model_config = ConfigDict(frozen=True, extra="forbid")
138
+
139
+ status: ToolExecutionStatus
140
+ summary: StrictStr
141
+ structured_data: Any = Field(default_factory=dict)
142
+ error_code: ToolExecutionErrorCode | None = None
143
+ side_effect_certainty: SideEffectCertainty = SideEffectCertainty.CONFIRMED_ABSENT
144
+ retryable: StrictBool = False
145
+
146
+
147
+ class ConnectorProviderToolEvidence(BaseModel):
148
+ """Broker-exposed provider evidence checked before connector entry."""
149
+
150
+ model_config = ConfigDict(frozen=True, extra="forbid")
151
+
152
+ connector_id: StrictStr
153
+ provider_tool_name: StrictStr
154
+ connector_identity_sha256: StrictStr
155
+ discovery_snapshot_sha256: StrictStr
156
+ raw_tool_sha256: StrictStr
157
+ input_schema_sha256: StrictStr
158
+ output_schema_sha256: StrictStr | None = None
159
+ provider_description_sha256: StrictStr | None = None
160
+
161
+ @model_validator(mode="after")
162
+ def _evidence_valid(self) -> ConnectorProviderToolEvidence:
163
+ validate_nonblank(self.connector_id, "connector_id")
164
+ validate_nonblank(self.provider_tool_name, "provider_tool_name")
165
+ validate_sha256(self.connector_identity_sha256, "connector_identity_sha256")
166
+ validate_sha256(self.discovery_snapshot_sha256, "discovery_snapshot_sha256")
167
+ validate_sha256(self.raw_tool_sha256, "raw_tool_sha256")
168
+ validate_sha256(self.input_schema_sha256, "input_schema_sha256")
169
+ if self.output_schema_sha256 is not None:
170
+ validate_sha256(self.output_schema_sha256, "output_schema_sha256")
171
+ if self.provider_description_sha256 is not None:
172
+ validate_sha256(
173
+ self.provider_description_sha256,
174
+ "provider_description_sha256",
175
+ )
176
+ return self
177
+
178
+
179
+ class ConnectorBroker(Protocol):
180
+ """Connector broker interface keyed by connector and provider tool identity."""
181
+
182
+ def has_provider_tool(self, connector_id: str, provider_tool_name: str) -> bool:
183
+ """Return whether the scoped provider tool is available."""
184
+
185
+ def provider_tool_evidence(
186
+ self,
187
+ connector_id: str,
188
+ provider_tool_name: str,
189
+ ) -> ConnectorProviderToolEvidence | None:
190
+ """Return current provider evidence without invoking the provider tool."""
191
+
192
+ def invoke(self, request: ConnectorInvocationRequest) -> ConnectorBrokerOutcome:
193
+ """Invoke the scoped provider tool without receiving runtime internals."""
194
+
195
+
196
+ def connector_idempotency_key(
197
+ *, idempotency: IdempotencyClass, call_id: str
198
+ ) -> str | None:
199
+ """Return a broker idempotency key only for key-scoped descriptors."""
200
+ if idempotency is IdempotencyClass.IDEMPOTENT_WITH_KEY:
201
+ return call_id
202
+ return None