@miller-tech/uap 2.16.6 → 2.19.5
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.
- package/README.md +1 -1
- package/config/capacity-policy.json +33 -0
- package/config/model-profiles/qwen38.json +32 -33
- package/dist/.tsbuildinfo +1 -1
- package/dist/bin/cli.js +57 -0
- package/dist/bin/cli.js.map +1 -1
- package/dist/capacity/policy.d.ts +32 -1
- package/dist/capacity/policy.d.ts.map +1 -1
- package/dist/capacity/policy.js +123 -4
- package/dist/capacity/policy.js.map +1 -1
- package/dist/capacity/probe.d.ts +26 -0
- package/dist/capacity/probe.d.ts.map +1 -1
- package/dist/capacity/probe.js +84 -3
- package/dist/capacity/probe.js.map +1 -1
- package/dist/cli/inference.d.ts +4 -0
- package/dist/cli/inference.d.ts.map +1 -1
- package/dist/cli/inference.js +74 -8
- package/dist/cli/inference.js.map +1 -1
- package/dist/cli/merge-gate.d.ts +59 -0
- package/dist/cli/merge-gate.d.ts.map +1 -0
- package/dist/cli/merge-gate.js +238 -0
- package/dist/cli/merge-gate.js.map +1 -0
- package/dist/cli/merge-queue.d.ts +13 -0
- package/dist/cli/merge-queue.d.ts.map +1 -1
- package/dist/cli/merge-queue.js +48 -2
- package/dist/cli/merge-queue.js.map +1 -1
- package/dist/cli/mission.d.ts +25 -0
- package/dist/cli/mission.d.ts.map +1 -0
- package/dist/cli/mission.js +225 -0
- package/dist/cli/mission.js.map +1 -0
- package/dist/cli/orch.d.ts +27 -0
- package/dist/cli/orch.d.ts.map +1 -0
- package/dist/cli/orch.js +70 -0
- package/dist/cli/orch.js.map +1 -0
- package/dist/cli/systemd-services.d.ts.map +1 -1
- package/dist/cli/systemd-services.js +44 -0
- package/dist/cli/systemd-services.js.map +1 -1
- package/dist/delivery/merge-gate.d.ts +168 -0
- package/dist/delivery/merge-gate.d.ts.map +1 -0
- package/dist/delivery/merge-gate.js +309 -0
- package/dist/delivery/merge-gate.js.map +1 -0
- package/dist/inference/analysis.d.ts +69 -3
- package/dist/inference/analysis.d.ts.map +1 -1
- package/dist/inference/analysis.js +123 -7
- package/dist/inference/analysis.js.map +1 -1
- package/dist/inference/probe.d.ts +38 -1
- package/dist/inference/probe.d.ts.map +1 -1
- package/dist/inference/probe.js +303 -30
- package/dist/inference/probe.js.map +1 -1
- package/dist/inference/strata.d.ts +95 -0
- package/dist/inference/strata.d.ts.map +1 -0
- package/dist/inference/strata.js +167 -0
- package/dist/inference/strata.js.map +1 -0
- package/dist/mission/database.d.ts +29 -0
- package/dist/mission/database.d.ts.map +1 -0
- package/dist/mission/database.js +131 -0
- package/dist/mission/database.js.map +1 -0
- package/dist/mission/ledger.d.ts +109 -0
- package/dist/mission/ledger.d.ts.map +1 -0
- package/dist/mission/ledger.js +294 -0
- package/dist/mission/ledger.js.map +1 -0
- package/dist/mission/poll-cycle.d.ts +73 -0
- package/dist/mission/poll-cycle.d.ts.map +1 -0
- package/dist/mission/poll-cycle.js +100 -0
- package/dist/mission/poll-cycle.js.map +1 -0
- package/dist/mission/poll-executor.d.ts +91 -0
- package/dist/mission/poll-executor.d.ts.map +1 -0
- package/dist/mission/poll-executor.js +328 -0
- package/dist/mission/poll-executor.js.map +1 -0
- package/dist/models/types.d.ts.map +1 -1
- package/dist/models/types.js +33 -27
- package/dist/models/types.js.map +1 -1
- package/dist/self-tuning/profiles/qwen38.d.ts +13 -14
- package/dist/self-tuning/profiles/qwen38.d.ts.map +1 -1
- package/dist/self-tuning/profiles/qwen38.js +17 -18
- package/dist/self-tuning/profiles/qwen38.js.map +1 -1
- package/dist/types/mission.d.ts +80 -0
- package/dist/types/mission.d.ts.map +1 -0
- package/dist/types/mission.js +12 -0
- package/dist/types/mission.js.map +1 -0
- package/docs/architecture/adr/0003-mission-orchestrator.md +99 -0
- package/docs/architecture/adr/0004-deterministic-merge-gate.md +127 -0
- package/docs/guides/CAPACITY_POLICY.md +49 -0
- package/docs/guides/INFERENCE_HEALTH.md +65 -8
- package/docs/guides/MISSIONS.md +170 -0
- package/docs/guides/PROXY.md +2 -0
- package/docs/reports/2026-10-02-plane-admin-fail-closed.md +70 -0
- package/docs/reports/2026-10-02-plane-admin-protect-session.md +116 -0
- package/docs/visual/merge-gate.html +404 -0
- package/docs/visual/mission-orchestrator.html +472 -0
- package/package.json +2 -2
- package/src/policies/enforcers/__pycache__/_common.cpython-312.pyc +0 -0
- package/src/policies/enforcers/__pycache__/expert_review_required.cpython-312.pyc +0 -0
- package/src/policies/enforcers/__pycache__/quality_metrics_gate.cpython-312.pyc +0 -0
- package/src/policies/enforcers/plane_admin_protect.py +133 -0
- package/src/policies/schemas/policies/plane-admin-protect.md +55 -0
- package/templates/hooks/__pycache__/deliver_autoroute.cpython-312.pyc +0 -0
- package/templates/hooks/uap-policy-gate.sh +33 -0
- package/tools/agents/scripts/__pycache__/toolcall_path_normalizer.cpython-312.pyc +0 -0
- package/tools/agents/scripts/anthropic_proxy.py +522 -45
- package/tools/agents/tests/test_anthropic_proxy_streaming.py +171 -0
- package/tools/agents/tests/test_gate_failclosed_plane_admin.py +248 -0
- package/tools/agents/tests/test_plane_admin_protect.py +124 -0
- package/tools/agents/tests/test_repeat_call_guard.py +64 -0
- package/tools/agents/tests/test_stream_heartbeat.py +77 -0
|
@@ -107,5 +107,82 @@ class TestStreamHeartbeat(unittest.TestCase):
|
|
|
107
107
|
self.assertIn("kaboom", out)
|
|
108
108
|
|
|
109
109
|
|
|
110
|
+
class TestGuardedWaitProgressLog(unittest.TestCase):
|
|
111
|
+
"""Journal progress during the buffered wait (2026-10-04 incident).
|
|
112
|
+
|
|
113
|
+
A no-tool streaming turn served via the guarded path can buffer for
|
|
114
|
+
minutes (live: an 11,099-token client-compaction summary over 281 s) with
|
|
115
|
+
the journal silent from REQ to RESP — the proxy read as hung and the only
|
|
116
|
+
evidence was the RESP timestamp. `_heartbeat_then_buffered` now logs one
|
|
117
|
+
INFO line per PROXY_GUARDED_WAIT_LOG_SECS of waiting so a long buffered
|
|
118
|
+
generation is legible while it happens.
|
|
119
|
+
"""
|
|
120
|
+
|
|
121
|
+
def setUp(self):
|
|
122
|
+
self._hb = proxy.PROXY_STREAM_HEARTBEAT_SECS
|
|
123
|
+
self._log_secs = proxy.PROXY_GUARDED_WAIT_LOG_SECS
|
|
124
|
+
proxy.PROXY_STREAM_HEARTBEAT_SECS = 0.05
|
|
125
|
+
proxy.PROXY_GUARDED_WAIT_LOG_SECS = 0.06
|
|
126
|
+
|
|
127
|
+
def tearDown(self):
|
|
128
|
+
proxy.PROXY_STREAM_HEARTBEAT_SECS = self._hb
|
|
129
|
+
proxy.PROXY_GUARDED_WAIT_LOG_SECS = self._log_secs
|
|
130
|
+
|
|
131
|
+
@staticmethod
|
|
132
|
+
def _response():
|
|
133
|
+
return {
|
|
134
|
+
"id": "msg_z",
|
|
135
|
+
"model": "m",
|
|
136
|
+
"content": [{"type": "text", "text": "done"}],
|
|
137
|
+
"stop_reason": "end_turn",
|
|
138
|
+
"usage": {"output_tokens": 1},
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
def test_slow_produce_logs_wait_progress(self):
|
|
142
|
+
async def produce():
|
|
143
|
+
await asyncio.sleep(0.2) # > 2 log boundaries at 0.06s
|
|
144
|
+
return self._response()
|
|
145
|
+
|
|
146
|
+
with self.assertLogs("uap.anthropic_proxy", level="INFO") as cm:
|
|
147
|
+
out = "".join(asyncio.run(_collect(produce())))
|
|
148
|
+
self.assertIn("done", out) # stream still completes normally
|
|
149
|
+
wait_logs = [l for l in cm.output if "GUARDED-BUFFER WAIT" in l]
|
|
150
|
+
self.assertGreaterEqual(len(wait_logs), 2)
|
|
151
|
+
self.assertIn("still generating after", wait_logs[0])
|
|
152
|
+
self.assertIn("test-model", wait_logs[0])
|
|
153
|
+
|
|
154
|
+
def test_progress_logs_once_per_boundary_not_per_heartbeat(self):
|
|
155
|
+
async def produce():
|
|
156
|
+
await asyncio.sleep(0.22) # ~4 heartbeats, ~3 boundaries
|
|
157
|
+
return self._response()
|
|
158
|
+
|
|
159
|
+
with self.assertLogs("uap.anthropic_proxy", level="INFO") as cm:
|
|
160
|
+
asyncio.run(_collect(produce()))
|
|
161
|
+
wait_logs = [l for l in cm.output if "GUARDED-BUFFER WAIT" in l]
|
|
162
|
+
# 0.22s of waiting at 0.06s boundaries: 2-4 lines, one per boundary
|
|
163
|
+
# crossed — NOT one per 0.05s heartbeat.
|
|
164
|
+
self.assertGreaterEqual(len(wait_logs), 2)
|
|
165
|
+
self.assertLessEqual(len(wait_logs), 4)
|
|
166
|
+
|
|
167
|
+
def test_fast_produce_logs_no_wait_progress(self):
|
|
168
|
+
async def produce():
|
|
169
|
+
return self._response()
|
|
170
|
+
|
|
171
|
+
with self.assertNoLogs("uap.anthropic_proxy", level="INFO"):
|
|
172
|
+
out = "".join(asyncio.run(_collect(produce())))
|
|
173
|
+
self.assertIn("done", out)
|
|
174
|
+
|
|
175
|
+
def test_wait_progress_log_disabled(self):
|
|
176
|
+
proxy.PROXY_GUARDED_WAIT_LOG_SECS = 0.0
|
|
177
|
+
|
|
178
|
+
async def produce():
|
|
179
|
+
await asyncio.sleep(0.15)
|
|
180
|
+
return self._response()
|
|
181
|
+
|
|
182
|
+
with self.assertNoLogs("uap.anthropic_proxy", level="INFO"):
|
|
183
|
+
out = "".join(asyncio.run(_collect(produce())))
|
|
184
|
+
self.assertIn("done", out)
|
|
185
|
+
|
|
186
|
+
|
|
110
187
|
if __name__ == "__main__":
|
|
111
188
|
unittest.main()
|