@miller-tech/uap 1.137.2 → 1.137.3
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/docs/INDEX.md +2 -1
- package/docs/guides/DELIVER.md +91 -10
- package/docs/guides/LOCAL_MODELS.md +4 -0
- package/docs/guides/PROXY.md +202 -0
- package/package.json +1 -1
- package/src/policies/enforcers/__pycache__/_common.cpython-312.pyc +0 -0
- package/tools/agents/scripts/__pycache__/toolcall_path_normalizer.cpython-312.pyc +0 -0
package/docs/INDEX.md
CHANGED
|
@@ -20,7 +20,7 @@ UAP is organized like a delivery line. If you know which part of the pipeline yo
|
|
|
20
20
|
| **Intake** — understand the work | Amnesiac sessions, invented scope | [Memory](guides/MEMORY.md) · [Reactor](design/UAP_REACTOR.md) |
|
|
21
21
|
| **Prep / routing** — right job, right station | Wrong approach or wrong-sized model | [Multi-Model Routing](guides/MULTI_MODEL.md) · [Patterns](reference/PATTERNS.md) · [Droids & Skills](guides/DROIDS_AND_SKILLS.md) |
|
|
22
22
|
| **Isolation** — a bench per job | Editing `main`, clobbering files | [Worktree Workflow](guides/WORKTREE_WORKFLOW.md) |
|
|
23
|
-
| **Build** — make the thing | Plausible-but-wrong code, stubs, empty output | [`uap deliver`](guides/DELIVER.md) · [Local Models](guides/LOCAL_MODELS.md) |
|
|
23
|
+
| **Build** — make the thing | Plausible-but-wrong code, stubs, empty output | [`uap deliver`](guides/DELIVER.md) · [Local Models](guides/LOCAL_MODELS.md) · [Inference Proxy](guides/PROXY.md) |
|
|
24
24
|
| **QC / verify** — prove it runs | "Done" on code that never ran | [`uap deliver`](guides/DELIVER.md) · [Policies](guides/POLICIES.md) |
|
|
25
25
|
| **Coordination** — many workers, one floor | Parallel agents colliding | [Coordination](guides/COORDINATION.md) · [Deploy Batching](guides/DEPLOY_BATCHING.md) |
|
|
26
26
|
| **Shipping** — out the door safely | Regressions, red CI, skipped bumps | [Worktree Workflow](guides/WORKTREE_WORKFLOW.md) · [Policies](guides/POLICIES.md) |
|
|
@@ -60,6 +60,7 @@ Full map: **[The UAP Delivery Pipeline](guides/DELIVERY_PIPELINE.md)**.
|
|
|
60
60
|
| [Deploy Batching](guides/DEPLOY_BATCHING.md) | Conflict-free batched git/deploy actions |
|
|
61
61
|
| [Coordination](guides/COORDINATION.md) | Multi-agent overlap detection |
|
|
62
62
|
| [Local Models](guides/LOCAL_MODELS.md) | Running agents against local llama.cpp / Qwen models |
|
|
63
|
+
| [Inference Proxy](guides/PROXY.md) | The Anthropic↔local gateway: `uap proxy` lifecycle, reliability guardrails, security, serving recipes |
|
|
63
64
|
| [Qwen3.6 on llama.cpp by VRAM](guides/QWEN36_LLAMACPP.md) | Tiered 8/12/16/24/32 GB setup; how `uap deliver` uplifts small local models |
|
|
64
65
|
| [**LLM Self-Tuning**](guides/SELF_TUNING.md) | `uap tune` — raise a small model toward Opus by tuning UAP's flag surface with a benchmark-validated LLM/GP-BO loop; quality scoring, model profiles, auto-on real-time adaptation ⭐ |
|
|
65
66
|
|
package/docs/guides/DELIVER.md
CHANGED
|
@@ -51,6 +51,22 @@ local or frontier — runs the build to 100% without stopping. See
|
|
|
51
51
|
|
|
52
52
|
---
|
|
53
53
|
|
|
54
|
+
## Big builds: decompose → orchestrate → epics → contracts-first
|
|
55
|
+
|
|
56
|
+
For a mission too large to hold in one context, `deliver` scales down the context each turn actually needs — this is what lets a small-context local model compose a system it could never see all at once.
|
|
57
|
+
|
|
58
|
+
- **`--decompose`** splits the mission into sequential phases, each converged by its own loop (auto for long, complex instructions; `--no-decompose` forbids it).
|
|
59
|
+
- **`--orchestrate`** runs those phases through the **blackboard orchestrator** with *minimal* per-task context — each task sees only its goal + its direct-dependency outputs. Implies `--decompose`.
|
|
60
|
+
- **`--epics`** runs a massive mission as a sequence of **epics, each a fresh session** — only prior epics' summaries are injected, never their full code — looped until each is accepted (auto for very long missions; `--no-epics` disables).
|
|
61
|
+
|
|
62
|
+
**Contracts-first** (on by default inside epic/decompose runs; `UAP_DELIVER_CONTRACTS=0` disables): the first epic plans the shared types, interfaces, and registry APIs the rest build against. Once accepted, its files are **locked read-only** so later epics build against frozen signatures and can't drift them. The public surface is *extracted and verified against emitted source* — only names proven present are recorded — which is what makes cross-module composition reliable without holding every module in context.
|
|
63
|
+
|
|
64
|
+
**Scaffold-then-fill** (on by default in phased runs; `UAP_DELIVER_SCAFFOLD=0` disables): a large phase is split into a **scaffold** phase that emits the compiling skeleton (complete public signatures, wired imports/exports, stub bodies — build/typecheck must pass) and a **fill** phase that implements the logic *without changing any signature*. The skeleton keeps the build green while the details land.
|
|
65
|
+
|
|
66
|
+
Interrupted a long run? **`--resume <id|latest>`** picks up a durable run from `.uap/deliver-runs` where it left off.
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
54
70
|
## Auto-optimization
|
|
55
71
|
|
|
56
72
|
By default every task is **classified by complexity** and the matching convergence aids turn on automatically (`auto-optimizer.ts`). You don't have to tune anything for the common case. To control it explicitly:
|
|
@@ -103,41 +119,106 @@ uap deliver "add the orders endpoint" --until-deployed
|
|
|
103
119
|
|
|
104
120
|
---
|
|
105
121
|
|
|
122
|
+
## Beyond build & test: proving it runs
|
|
123
|
+
|
|
124
|
+
Green gates prove code *compiles and tests pass* — not that the artifact actually **runs**. `deliver` adds gates for that:
|
|
125
|
+
|
|
126
|
+
- **Execution gate** — auto-synthesized as a ladder rung whenever a runnable artifact is detected: it actually *runs* the thing (headless browser / vm-dom / child-process) and fails the turn on a runtime error, a blank canvas, or a static frame. Catches "declared done but never ran."
|
|
127
|
+
- **Acceptance judge** (`--acceptance`) — after the objective gates pass, an LLM judges the spec's *behavioral completeness* from the code + runtime evidence and feeds any unmet requirements back so the loop finishes the spec. Pair it with **`--evaluator-model <preset>`** to have a *different* model judge than the one that implemented (separate generator from evaluator — the "barbell" strategy).
|
|
128
|
+
- **Self-gate** — when a project has **no** detectable gates, `deliver` authors a task-specific acceptance gate as a fallback so there is always something to converge against (on by default; `--no-self-gate` disables, `--force-self-gate` authors one even when project gates exist).
|
|
129
|
+
|
|
130
|
+
## Resilience: baseline-delta, migrations & repair escalation
|
|
131
|
+
|
|
132
|
+
Long autonomous runs fail in predictable ways; `deliver` has a guard for each:
|
|
133
|
+
|
|
134
|
+
- **Baseline-delta gating** — the full ladder is run **once at mission start**. Any required gate that is *already red at baseline* (a pre-existing failure the mission didn't cause) is demoted to non-blocking and annotated; only **new** regressions (green→red) block delivery. So a pre-existing broken lint or flaky test can't consume every attempt. On by default (`UAP_DELIVER_BASELINE_DELTA=0` or `.uap.json` `deliver.baselineDelta:false` to disable).
|
|
135
|
+
- **Migration-validation gate** — when a `migrations/` dir with `.sql` files exists, a ladder rung runs the migrations against an **ephemeral throwaway Postgres container** before they can ship broken. Skips cleanly (never fails) when Docker/`sqlx-cli` isn't available.
|
|
136
|
+
- **Repair escalation** — a circuit breaker for the compile-error death spiral: when the compile-error count *grows* across consecutive turns, the loop stops mission work and runs **one narrow "make it compile, change nothing else" pass** — in a fresh focused session, on the `--escalate-model` when configured — then resumes.
|
|
137
|
+
|
|
106
138
|
## Options
|
|
107
139
|
|
|
140
|
+
**Loop & termination**
|
|
141
|
+
|
|
108
142
|
| Flag | Purpose |
|
|
109
143
|
|---|---|
|
|
110
144
|
| `--max-turns <n>` | Maximum execute→verify iterations before until-delivered extension (default `5`) |
|
|
111
145
|
| `--no-until-delivered` | Disable loop-until-delivered (ON by default: extends past `--max-turns` to the ceiling, stopping on stagnation) |
|
|
112
146
|
| `--ceiling <n>` | Hard turn ceiling for until-delivered (1–50, default `30`) |
|
|
147
|
+
| `--no-lazy` | Skip the lazy bare first attempt (by default one bare turn runs before the convergence aids engage) |
|
|
148
|
+
| `--resume <id>` | Resume an interrupted durable run: a run id or `latest` (`.uap/deliver-runs`) |
|
|
149
|
+
|
|
150
|
+
**Executor**
|
|
151
|
+
|
|
152
|
+
| Flag | Purpose |
|
|
153
|
+
|---|---|
|
|
154
|
+
| `--executor <mode>` | Per-turn executor: `blind` (one completion), `agentic` (tool-using read/list/bash/write loop), or `auto` (agentic when there's repo context/gates to inspect) — default `auto` |
|
|
155
|
+
| `--allow-bash` | Permit the agentic executor's `run_bash` tool when NOT under `uap sandbox` (off by default; auto-enabled under sandbox) |
|
|
156
|
+
|
|
157
|
+
**Models & routing**
|
|
158
|
+
|
|
159
|
+
| Flag | Purpose |
|
|
160
|
+
|---|---|
|
|
113
161
|
| `-m, --model <preset>` | Model preset (default `$UAP_DELIVER_MODEL` or `qwen35-a3b`) |
|
|
162
|
+
| `--routing <preset>` | Pick the executor per task complexity from a routing preset (e.g. `cost-tiered`, `speed-tiered`); ignored when `--model` is set (`$UAP_DELIVER_ROUTING`) |
|
|
114
163
|
| `--endpoint <url>` | Override the model endpoint (OpenAI-compatible `/v1`) |
|
|
115
|
-
| `--escalate-model <preset>` | Stronger model for escalation (default `$UAP_ESCALATE_MODEL`) |
|
|
164
|
+
| `--escalate-model <preset>` | Stronger model for the escalation/repair ladder (default `$UAP_ESCALATE_MODEL`) |
|
|
116
165
|
| `--temperature <t>` | Sampling temperature (default: execution-profile value) |
|
|
166
|
+
|
|
167
|
+
**Gates & acceptance**
|
|
168
|
+
|
|
169
|
+
| Flag | Purpose |
|
|
170
|
+
|---|---|
|
|
117
171
|
| `--gates <ids>` | Gate subset: `build,typecheck,test,lint` |
|
|
118
|
-
| `--
|
|
172
|
+
| `--acceptance` | After objective gates pass, judge spec behavioral completeness (LLM) and feed unmet requirements back |
|
|
173
|
+
| `--evaluator-model <preset>` / `--evaluator-endpoint <url>` | Judge the acceptance gate with a DIFFERENT model than the implementer (generator≠evaluator) |
|
|
174
|
+
| `--no-self-gate` | Disable the self-authored acceptance-gate fallback (on by default when no project gates are detected) |
|
|
175
|
+
| `--force-self-gate` | Author a task-specific acceptance gate even when project gates exist |
|
|
176
|
+
| `--keep-best` | Never regress: snapshot first, roll back if the run ends with a worse required-gate score |
|
|
177
|
+
|
|
178
|
+
**Tiers & CI/deploy feedback**
|
|
179
|
+
|
|
180
|
+
| Flag | Purpose |
|
|
181
|
+
|---|---|
|
|
182
|
+
| `--tiers <list>` | Explicit local tiers, e.g. `fast,integration,deploy-dev` (overrides auto-detection) |
|
|
119
183
|
| `--integration` / `--no-integration` | Run the integration tier (on by default when a suite is detected) |
|
|
120
184
|
| `--deploy-dev` / `--no-deploy-dev` | Run a local dev deploy + smoke tier (compose up → smoke → teardown) |
|
|
121
|
-
| `--watch-ci` | After local-green, commit + push the worktree branch and watch CI; re-converge on failure |
|
|
185
|
+
| `--watch-ci` | After local-green, commit + push the worktree branch and watch CI; re-converge on failure (never pushes master/main) |
|
|
122
186
|
| `--until-deployed` | Imply `--watch-ci` and require CI + staging/prod deploy jobs green before exiting 0 |
|
|
123
187
|
| `--ci-passes <n>` | Max CI re-converge passes on failure (1–10, default `2`) |
|
|
124
188
|
| `--ci-timeout <minutes>` | CI watch budget in minutes (1–120, default `20`) |
|
|
189
|
+
|
|
190
|
+
**Big builds (decompose → orchestrate → epics)**
|
|
191
|
+
|
|
192
|
+
| Flag | Purpose |
|
|
193
|
+
|---|---|
|
|
194
|
+
| `--decompose` / `--no-decompose` | Split the mission into sequential phases, each converged by its own loop (auto for long complex tasks) |
|
|
195
|
+
| `--orchestrate` / `--no-orchestrate` | Run decomposed tasks through the blackboard orchestrator with MINIMAL per-task context (implies `--decompose`) |
|
|
196
|
+
| `--epics` / `--no-epics` | Run a massive mission as a sequence of fresh-session epics until each is accepted (auto for very long missions) |
|
|
197
|
+
|
|
198
|
+
**Exploration & quality aids**
|
|
199
|
+
|
|
200
|
+
| Flag | Purpose |
|
|
201
|
+
|---|---|
|
|
125
202
|
| `--candidates <n>` | Best-of-N exploration: candidates per turn (2–8) |
|
|
126
|
-
| `--critic` | Structured critique of failed turns |
|
|
203
|
+
| `--critic` | Structured critique of failed turns (extra model call per failure) |
|
|
127
204
|
| `--practices` / `--no-semantic` | Inject/record best-practice cards (keyword retrieval with `--no-semantic`) |
|
|
128
|
-
| `--escalate` | Escalation ladder on stagnation |
|
|
205
|
+
| `--escalate` | Escalation ladder on stagnation (widen exploration → critic → stronger model) |
|
|
129
206
|
| `--ideate` / `--ideate-project <name>` | Divergent ideation strategy seeds |
|
|
130
|
-
| `--halo` | Emit HALO spans (analyze with `uap harness analyze`) |
|
|
131
|
-
| `--coordinate` | Register the run with the coordination layer |
|
|
132
|
-
| `--deploy` | On success, queue a commit of applied files into the deploy batcher |
|
|
133
207
|
| `--optimize` | Enable every convergence aid |
|
|
134
|
-
| `--no-auto` | Disable dynamic optimization |
|
|
208
|
+
| `--no-auto` | Disable dynamic optimization (aids are auto-selected by task complexity by default) |
|
|
209
|
+
|
|
210
|
+
**Integration & run control**
|
|
211
|
+
|
|
212
|
+
| Flag | Purpose |
|
|
213
|
+
|---|---|
|
|
135
214
|
| `--no-protect-tests` | Allow the model to modify pre-existing test files (protected by default) |
|
|
136
215
|
| `--guidance-file <path>` | Poll a file each turn for live operator guidance |
|
|
216
|
+
| `--halo` | Emit HALO spans (analyze with `uap harness analyze`) |
|
|
217
|
+
| `--coordinate` | Register the run with the coordination layer (announce, heartbeat, overlap detection) |
|
|
218
|
+
| `--deploy` | On success, queue a commit of applied files into the deploy batcher |
|
|
137
219
|
| `--project-root <path>` | Project whose gates define delivery (default: cwd) |
|
|
138
220
|
| `--dry-run` | Show detected gates and plan without calling the model |
|
|
139
221
|
| `--json` | Emit a JSON result |
|
|
140
|
-
| `--keep-best` | Never regress: snapshot the project first, roll back if the run ends with a worse required-gate score |
|
|
141
222
|
|
|
142
223
|
### `--keep-best` snapshots
|
|
143
224
|
|
|
@@ -162,6 +162,10 @@ The client then talks the Anthropic protocol to the proxy, which forwards
|
|
|
162
162
|
OpenAI requests to llama.cpp. The proxy supports streaming and tool-call
|
|
163
163
|
translation.
|
|
164
164
|
|
|
165
|
+
For the full picture — the `uap proxy` lifecycle, the reliability guardrails
|
|
166
|
+
that keep a small model from wedging, security, and serving recipes — see the
|
|
167
|
+
**[Inference Proxy guide](PROXY.md)**.
|
|
168
|
+
|
|
165
169
|
## Related
|
|
166
170
|
|
|
167
171
|
- [Deploy Batching](./DEPLOY_BATCHING.md) — what `uap deliver --deploy` queues.
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
# The Inference Proxy
|
|
2
|
+
|
|
3
|
+
UAP ships a local **inference proxy** — an Anthropic-Messages-compatible gateway
|
|
4
|
+
that sits in front of a local llama.cpp/Qwen backend, translates between the
|
|
5
|
+
Anthropic wire format and llama's OpenAI-compatible API, and applies a layer of
|
|
6
|
+
**reliability guardrails** on the way through. It's what lets a Claude-native
|
|
7
|
+
harness (Claude Code, Factory, …) drive a local model, and it's where most of
|
|
8
|
+
the "keep a small model from wedging" logic lives.
|
|
9
|
+
|
|
10
|
+
> Code: [`tools/agents/scripts/anthropic_proxy.py`](../../tools/agents/scripts/anthropic_proxy.py)
|
|
11
|
+
> (the server), `tools/agents/scripts/confidence_escalation.py` (serving
|
|
12
|
+
> recipes), and `src/cli/proxy.ts` / `src/cli/proxy-lifecycle.ts` (lifecycle).
|
|
13
|
+
> Related: [Local Models](LOCAL_MODELS.md) · [Configuration Reference](../reference/CONFIGURATION_REFERENCE.md).
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## What it does
|
|
18
|
+
|
|
19
|
+
- **Protocol translation** — accepts Anthropic `POST /v1/messages` and forwards
|
|
20
|
+
OpenAI-style requests to the local rail (`LLAMA_CPP_BASE`, e.g.
|
|
21
|
+
`http://localhost:8080/v1`), streaming and tool-calls included.
|
|
22
|
+
- **Reliability guardrails** — detects and breaks the failure modes a small
|
|
23
|
+
local model falls into (act/review loops, "I'm stuck" spirals, endless
|
|
24
|
+
exploration with no deliverable) so a run terminates instead of burning turns.
|
|
25
|
+
- **Context management** — scales token counts so the client compacts *before*
|
|
26
|
+
the local rail overflows, and prunes as a backstop.
|
|
27
|
+
- **Graceful degradation under load** — pool saturation returns a proper
|
|
28
|
+
Anthropic `529 overloaded_error` with `retry-after` rather than failing hard.
|
|
29
|
+
- **Serving recipes** — optional confidence/fusion escalation to a stronger
|
|
30
|
+
judge model, plus per-request routing from the reactor and the self-tuning
|
|
31
|
+
real-time adaptor.
|
|
32
|
+
|
|
33
|
+
### Endpoints
|
|
34
|
+
|
|
35
|
+
| Route | Purpose |
|
|
36
|
+
|---|---|
|
|
37
|
+
| `POST /v1/messages` (+ `/anthropic/v1/messages`) | Main Anthropic Messages endpoint (local model + guardrails) |
|
|
38
|
+
| `POST /v1/messages/count_tokens` | Token counting, scaled so the client compacts before the local rail overflows |
|
|
39
|
+
| `POST /v1/chat/completions` | OpenAI-compatible surface |
|
|
40
|
+
| `GET /v1/models` | Model list (honors the `__local_only__` passthrough sentinel) |
|
|
41
|
+
| `GET /health` | Liveness (probes the upstream; stays unauthenticated) |
|
|
42
|
+
| `GET /v1/context` | Per-session token-usage / utilization / guardrail telemetry (dashboards & debug) |
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## Lifecycle: `uap proxy`
|
|
47
|
+
|
|
48
|
+
The proxy is **reference-counted and session-scoped**. Hooks call `ensure` when a
|
|
49
|
+
session starts and `release` when it ends, so it starts on demand and stops when
|
|
50
|
+
the last session leaves — but it **never** kills a proxy that systemd manages or
|
|
51
|
+
that other sessions are still using.
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
uap proxy [ensure | release | status | start | stop | restart | enable | disable]
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
| Subcommand | What it does |
|
|
58
|
+
|---|---|
|
|
59
|
+
| `ensure` | Start the proxy if none is running, or **adopt** a running one; register this session as a client |
|
|
60
|
+
| `release` | Deregister this session; stop the proxy **only if** we spawned it as a plain process and no other client remains |
|
|
61
|
+
| `status` | Report whether it's running, how (systemd vs spawned), the port, and client count (`--json` for machine-readable) |
|
|
62
|
+
| `start` / `stop` / `restart` | Explicit control (e.g. `restart` after changing `PROXY_*` in `.uap/proxy.env`) |
|
|
63
|
+
| `enable` / `disable` | Toggle `.uap.json` `proxy.autostart` so hooks auto-start it (or not) |
|
|
64
|
+
|
|
65
|
+
| Flag | Purpose |
|
|
66
|
+
|---|---|
|
|
67
|
+
| `--client <id>` | Client/session id (defaults to the session env or parent pid) |
|
|
68
|
+
| `--client-pid <n>` | Long-lived agent pid for liveness (hooks pass `$PPID`) |
|
|
69
|
+
| `--port <n>` | Proxy port (default `4000` / `$PROXY_PORT`) |
|
|
70
|
+
| `--if-enabled` | No-op unless `.uap.json` `proxy.autostart` is `true` (hook-safe) |
|
|
71
|
+
| `--quiet` / `--json` | Suppress output (hooks) / machine-readable status |
|
|
72
|
+
|
|
73
|
+
**How it's managed.** When available, the proxy runs as the systemd unit
|
|
74
|
+
`uap-anthropic-proxy.service`, reading its environment from
|
|
75
|
+
`~/.config/uap/anthropic-proxy.env`; a plain spawned proxy seeds the same file
|
|
76
|
+
for parity. The proxy also loads project-local `.uap/proxy.env` at startup
|
|
77
|
+
(real environment always wins). PID reuse is defended with a `/proc/<pid>`
|
|
78
|
+
start-time token so `release` never kills an unrelated process that inherited an
|
|
79
|
+
old pid. Everything hook-driven **fails open** — if the proxy won't start, the
|
|
80
|
+
agent just runs without it.
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
uap proxy status --json
|
|
84
|
+
uap proxy restart # pick up new PROXY_* values from .uap/proxy.env
|
|
85
|
+
uap proxy enable # let session hooks autostart it
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## Security
|
|
91
|
+
|
|
92
|
+
- **Loopback by default.** The proxy binds `127.0.0.1` (`PROXY_HOST`). This is
|
|
93
|
+
deliberate: an unauthenticated `0.0.0.0` listener would let any host on your
|
|
94
|
+
LAN drive the local model — and reach any cloud passthrough — so local-only is
|
|
95
|
+
the safe default.
|
|
96
|
+
- **Shared-secret auth for LAN exposure.** To run it as a shared service, set
|
|
97
|
+
`PROXY_HOST=0.0.0.0` **and** a `PROXY_AUTH_TOKEN`. With a token set, every model
|
|
98
|
+
route requires `Authorization: Bearer <token>` (or `X-Uap-Proxy-Token`), checked
|
|
99
|
+
in constant time; `/health` stays open. Never expose it beyond loopback without
|
|
100
|
+
a token.
|
|
101
|
+
- **Passthrough credentials.** For requests routed to the cloud, the proxy
|
|
102
|
+
forwards the client's OAuth `Authorization: Bearer` verbatim and does not also
|
|
103
|
+
attach an `x-api-key` (Anthropic rejects both).
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## Reliability guardrails
|
|
108
|
+
|
|
109
|
+
These are the heart of the proxy — the logic that keeps a weaker model from
|
|
110
|
+
wedging. Most are **on by default** and tuned via `PROXY_*` env vars (persisted
|
|
111
|
+
in `.uap/proxy.env` or the systemd EnvironmentFile). The high-signal knobs are in
|
|
112
|
+
the [Configuration Reference](../reference/CONFIGURATION_REFERENCE.md); the full
|
|
113
|
+
set is below.
|
|
114
|
+
|
|
115
|
+
### Termination breakers (on by default)
|
|
116
|
+
|
|
117
|
+
| Guardrail | Env (default) | Behavior |
|
|
118
|
+
|---|---|---|
|
|
119
|
+
| **Loop-breaker** | `PROXY_LOOP_BREAKER` (on) | Detects act/review cycles + no-progress streaks and releases `tool_choice` to `auto` so the model can actually terminate |
|
|
120
|
+
| **Stuck-break** | `PROXY_STUCK_BREAK` (on) | When the model self-reports "stuck in a loop" or hammers a rate-limited host, forces a terminal turn |
|
|
121
|
+
| **Deferral-break** | `PROXY_DEFERRAL_BREAK` (on) | The inverse: a no-tool turn that *defers* work ("I need more exploration cycles") is forced to act on the next turn |
|
|
122
|
+
| **Recon-convergence** | `PROXY_RECON_CONVERGENCE_THRESHOLD` (40) | After N tool-using turns with **no** write/deliverable, inject "stop exploring, produce the deliverable"; escalates to stripping tools if it persists (0 disables) |
|
|
123
|
+
| **Hard-finalize** | `PROXY_HARD_FINALIZE_TURNS` (40) | Absolute turn cap before a forced finalize |
|
|
124
|
+
| **MANDATE-DELIVER** | `PROXY_MANDATE_DELIVER` (on) | On the delivery-enforcer block marker, pin `tool_choice` to `deliver` so the next turn *must* route through the gated path — makes routing binding for weak models |
|
|
125
|
+
|
|
126
|
+
### Context & compaction
|
|
127
|
+
|
|
128
|
+
| Env (default) | Behavior |
|
|
129
|
+
|---|---|
|
|
130
|
+
| `PROXY_CONTEXT_WINDOW` (0 = auto) | Explicit local context window; 0 derives it from the live rail |
|
|
131
|
+
| `PROXY_COUNT_TOKENS_SCALE` (auto) | Scales the reported token count so the client auto-compacts before the local rail overflows |
|
|
132
|
+
| `PROXY_CONTEXT_PRUNE_THRESHOLD` (0.85) / `PROXY_CONTEXT_PRUNE_TARGET_FRACTION` (0.50) | Backstop pruning: prune at 85% of the window, land the session at ~50% |
|
|
133
|
+
|
|
134
|
+
### Connection health & backpressure
|
|
135
|
+
|
|
136
|
+
| Env (default) | Behavior |
|
|
137
|
+
|---|---|
|
|
138
|
+
| `PROXY_MAX_CONNECTIONS` (20) | httpx pool size; a large pool + 529 backoff absorbs connection churn gracefully |
|
|
139
|
+
| **529 backpressure** (no toggle) | A pool timeout returns HTTP **529 `overloaded_error`** with `retry-after` — pure graceful degradation, not a hard failure |
|
|
140
|
+
| `PROXY_CLOSEWAIT_REAP_INTERVAL` (0 = **off**) | Opt-in CLOSE-WAIT reaper (pool self-heal); off by default because pool-swap churn can harm a saturated upstream |
|
|
141
|
+
| `PROXY_TOOL_NARROWING` (**off**) | Opt-in: drop cycling/banned tools from the set on loops — always keeps the Bash/WebFetch/Agent escape hatch + write tools (a floor invariant that never strands the agent) |
|
|
142
|
+
|
|
143
|
+
> **Off-by-default knobs to know:** `PROXY_TOOL_NARROWING`, the CLOSE-WAIT reaper
|
|
144
|
+
> (`PROXY_CLOSEWAIT_REAP_INTERVAL=0`), `PROXY_POOL_SWAP_ON_SATURATION`, and the
|
|
145
|
+
> serving recipes (`PROXY_CONFIDENCE_ESCALATE`). Everything else above is on.
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## Serving recipes & escalation
|
|
150
|
+
|
|
151
|
+
The proxy can run a bounded **micro-agent recipe** in front of the local model —
|
|
152
|
+
escalating low-confidence or hard turns to a stronger **judge** model — behind
|
|
153
|
+
the same single model API. It is **off by default and fails open**.
|
|
154
|
+
|
|
155
|
+
| Env (default) | Meaning |
|
|
156
|
+
|---|---|
|
|
157
|
+
| `PROXY_CONFIDENCE_ESCALATE` (off) | Master switch for serving recipes |
|
|
158
|
+
| `PROXY_RECIPE` (auto) | `single \| confidence \| fusion` (+ `ratings \| remom`); `auto` routes by signal |
|
|
159
|
+
| `PROXY_CONFIDENCE_THRESHOLD` (0.5) | Below this confidence, escalate the turn to the judge |
|
|
160
|
+
| `PROXY_FUSION_N` (3) | Candidates the fusion recipe samples before the judge picks/merges (2–6) |
|
|
161
|
+
| `PROXY_ESCALATE_MODEL` / `PROXY_ESCALATE_ENDPOINT` / `PROXY_ESCALATE_API_KEY` | The stronger judge backend |
|
|
162
|
+
|
|
163
|
+
A judge-dependent recipe requires a judge **distinct from** the primary model —
|
|
164
|
+
a same-model "qwen judging qwen" setup downgrades to `single` unless
|
|
165
|
+
`PROXY_ALLOW_SELF_JUDGE=1`. The judge model id is configured on the harness side
|
|
166
|
+
via `recipes.judge.model` (see the [recipes settings](../reference/CONFIGURATION_REFERENCE.md));
|
|
167
|
+
`uap setup` / `uap config` seed the `PROXY_ESCALATE_*` triple into the proxy env.
|
|
168
|
+
|
|
169
|
+
### Cross-process signals
|
|
170
|
+
|
|
171
|
+
Because the proxy freezes its `PROXY_*` env at startup and has no reload
|
|
172
|
+
endpoint, two features steer it **per request** via small signal files (each a
|
|
173
|
+
best-effort read, TTL ~180s, never fatal):
|
|
174
|
+
|
|
175
|
+
- **Recipe signal** — the harness [Reactor](../design/UAP_REACTOR.md) writes its
|
|
176
|
+
per-prompt routing decision to `~/.cache/uap/recipe-signals/`; the proxy prefers
|
|
177
|
+
that fresh signal over re-deriving complexity itself.
|
|
178
|
+
- **Adaptation signal** — the [LLM self-tuning](SELF_TUNING.md) real-time adaptor
|
|
179
|
+
writes per-session adjustments (escalate / recipe / recon threshold / force
|
|
180
|
+
synthesis) to `~/.cache/uap/adaptation-signals/`. Consumed when
|
|
181
|
+
`PROXY_REALTIME_ADAPT` is on (**auto-on**; opt out with `0`).
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## Configuration
|
|
186
|
+
|
|
187
|
+
Proxy settings are `PROXY_*` environment variables. Persist them with
|
|
188
|
+
`uap config set` (which writes `.uap/proxy.env`) and `uap proxy restart` to apply:
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
uap config set PROXY_RECON_CONVERGENCE_THRESHOLD 30
|
|
192
|
+
uap config set PROXY_AUTH_TOKEN "$(openssl rand -hex 16)"
|
|
193
|
+
uap proxy restart
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
The curated high-impact subset is documented in the
|
|
197
|
+
[Configuration Reference](../reference/CONFIGURATION_REFERENCE.md#proxy);
|
|
198
|
+
the exhaustive list lives as module-level constants in `anthropic_proxy.py`.
|
|
199
|
+
|
|
200
|
+
> **Note:** the upstream backend default in the checked-in scripts
|
|
201
|
+
> (`LLAMA_CPP_BASE`) points at a specific host/port — always set it (or your
|
|
202
|
+
> model's `endpoint`) to your own llama.cpp/Qwen server.
|
package/package.json
CHANGED
|
Binary file
|