@miller-tech/uap 1.42.5 → 1.43.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@miller-tech/uap",
3
- "version": "1.42.5",
3
+ "version": "1.43.0",
4
4
  "description": "Autonomous AI agent memory system with CLAUDE.md protocol enforcement",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -6,8 +6,9 @@ non-trivial coding work goes through the `uap deliver` convergence loop (which
6
6
  drives a model to verified completion against the real gates) rather than
7
7
  ad-hoc hand edits.
8
8
 
9
- SAFETY — default mode is ADVISORY (always allows, logs a nudge), so installing
10
- this policy never breaks editing. Strict enforcement is opt-in:
9
+ DEFAULT mode is BLOCK: substantive source edits must route through `uap deliver`
10
+ (set UAP_ENFORCE_DELIVERY=advisory to relax to a logged nudge). Escape hatches
11
+ (UAP_DELIVER_ACTIVE / UAP_DELIVER_BYPASS) are always honored:
11
12
 
12
13
  UAP_ENFORCE_DELIVERY=block # direct source edits outside a deliver context
13
14
  # are blocked (exit 2)
@@ -84,13 +85,13 @@ def main() -> None:
84
85
  "manual edit."
85
86
  )
86
87
 
87
- mode = os.environ.get("UAP_ENFORCE_DELIVERY", "advisory").lower()
88
+ mode = os.environ.get("UAP_ENFORCE_DELIVERY", "block").lower()
88
89
  if mode == "block":
89
90
  emit(False, msg)
90
91
 
91
- # Advisory (default): never blocks. Surface the nudge, then allow.
92
+ # Advisory (opt-out): never blocks. Surface the nudge, then allow.
92
93
  print(f"[delivery-enforcement advisory] {msg}", file=sys.stderr)
93
- emit(True, "advisory: nudge logged (set UAP_ENFORCE_DELIVERY=block to enforce)")
94
+ emit(True, "advisory: nudge logged (block is the default; UAP_ENFORCE_DELIVERY=advisory relaxes)")
94
95
 
95
96
 
96
97
  if __name__ == "__main__":
@@ -32,13 +32,13 @@ the expectation explicit and, when a team opts in, enforces it.
32
32
 
33
33
  Python enforcer `delivery_enforcement.py`.
34
34
 
35
- **Default mode is ADVISORY** — it always allows the edit and logs a one-line
36
- nudge toward `uap deliver`. Installing the policy therefore never breaks normal
37
- editing.
35
+ **Default mode is BLOCK** — a direct source edit outside a deliver context is
36
+ blocked (exit 2) until the work is routed through `uap deliver` (or
37
+ `UAP_DELIVER_ACTIVE`/`UAP_DELIVER_BYPASS` is set).
38
38
 
39
- **Strict mode is opt-in** via `UAP_ENFORCE_DELIVERY=block`: a direct source
40
- edit outside a deliver context is then blocked (exit 2) until the work is routed
41
- through `uap deliver` or `UAP_DELIVER_BYPASS=1` is set.
39
+ **Advisory mode is opt-out** via `UAP_ENFORCE_DELIVERY=advisory` it then
40
+ always allows the edit and logs a one-line nudge toward `uap deliver` instead
41
+ of blocking.
42
42
 
43
43
  Exempt by construction: non-source files; `docs/`, `scripts/`, `policies/`,
44
44
  `src/policies/`, test files (deliver protects those itself); and tooling
@@ -37,26 +37,35 @@ logger = logging.getLogger(__name__)
37
37
  # --------------------------------------------------------------------------- #
38
38
 
39
39
 
40
- def _make_opencode_config(api_endpoint: str) -> dict:
40
+ def _make_opencode_config(
41
+ api_endpoint: str, model_ref: str = "llama.cpp/qwen35-a3b-iq4xs"
42
+ ) -> dict:
43
+ # model_ref is the harbor `-m` value, e.g. "llama.cpp/qwen3.6-a3b-iq4xs".
44
+ # Derive the provider + model id so opencode registers EXACTLY the model
45
+ # harbor selects (avoids ProviderModelNotFoundError when the local model
46
+ # changes, e.g. Qwen3.5 -> Qwen3.6).
47
+ provider_id, sep, model_id = model_ref.partition("/")
48
+ if not sep:
49
+ provider_id, model_id = "llama.cpp", model_ref
41
50
  return {
42
51
  "$schema": "https://opencode.ai/config.json",
43
52
  "provider": {
44
- "llama.cpp": {
53
+ provider_id: {
45
54
  "npm": "@ai-sdk/openai-compatible",
46
- "name": "llama-server (local Qwen3.5)",
55
+ "name": "llama-server (local)",
47
56
  "options": {
48
57
  "baseURL": api_endpoint,
49
- "apiKey": "sk-qwen35b",
58
+ "apiKey": "sk-local",
50
59
  },
51
60
  "models": {
52
- "qwen35-a3b-iq4xs": {
53
- "name": "Qwen3.5 35B A3B (IQ4_XS)",
61
+ model_id: {
62
+ "name": model_id,
54
63
  "limit": {"context": 262144, "output": 81920},
55
64
  }
56
65
  },
57
66
  }
58
67
  },
59
- "model": "llama.cpp/qwen35-a3b-iq4xs",
68
+ "model": f"{provider_id}/{model_id}",
60
69
  }
61
70
 
62
71
 
@@ -998,7 +1007,10 @@ class OpenCodeBaseline(BaseInstalledAgent):
998
1007
  if version:
999
1008
  variables["version"] = version
1000
1009
  variables["opencode_config"] = json.dumps(
1001
- _make_opencode_config(self._api_endpoint), indent=2
1010
+ _make_opencode_config(
1011
+ self._api_endpoint, self.model_name or "llama.cpp/qwen35-a3b-iq4xs"
1012
+ ),
1013
+ indent=2,
1002
1014
  )
1003
1015
  variables["api_endpoint"] = self._api_endpoint
1004
1016
  return variables
@@ -1081,11 +1093,20 @@ class OpenCodeUAP(BaseInstalledAgent):
1081
1093
  version = self.version()
1082
1094
  if version:
1083
1095
  variables["version"] = version
1084
- # Layer 1: opencode.json points to proxy at localhost:11435
1085
- # The proxy forwards to the real LLM endpoint and injects tool_choice="required"
1086
- proxy_endpoint = "http://127.0.0.1:11435/v1"
1096
+ # Modern local models (Qwen3.6+) emit native OpenAI tool calls; the
1097
+ # deprecated GBNF-forcing tool-choice proxy (Layer 1) breaks them. Point
1098
+ # opencode at the model endpoint directly by default; set
1099
+ # UAP_BENCH_PROXY=1 to restore the qwen3.5-era proxy path (port 11435).
1100
+ endpoint = (
1101
+ "http://127.0.0.1:11435/v1"
1102
+ if os.environ.get("UAP_BENCH_PROXY") == "1"
1103
+ else self._api_endpoint
1104
+ )
1087
1105
  variables["opencode_config"] = json.dumps(
1088
- _make_opencode_config(proxy_endpoint), indent=2
1106
+ _make_opencode_config(
1107
+ endpoint, self.model_name or "llama.cpp/qwen35-a3b-iq4xs"
1108
+ ),
1109
+ indent=2,
1089
1110
  )
1090
1111
  variables["api_endpoint"] = self._api_endpoint
1091
1112
  # NOTE: CLAUDE.md is now built dynamically per-task in create_run_agent_commands