@miller-tech/uap 1.136.2 → 1.137.2

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 (139) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/benchmarks/paired/report.d.ts +13 -0
  3. package/dist/benchmarks/paired/report.d.ts.map +1 -1
  4. package/dist/benchmarks/paired/report.js +29 -3
  5. package/dist/benchmarks/paired/report.js.map +1 -1
  6. package/dist/benchmarks/paired/types.d.ts +59 -0
  7. package/dist/benchmarks/paired/types.d.ts.map +1 -1
  8. package/dist/benchmarks/paired/types.js +60 -0
  9. package/dist/benchmarks/paired/types.js.map +1 -1
  10. package/dist/bin/cli.js +30 -0
  11. package/dist/bin/cli.js.map +1 -1
  12. package/dist/cli/deliver.d.ts.map +1 -1
  13. package/dist/cli/deliver.js +111 -7
  14. package/dist/cli/deliver.js.map +1 -1
  15. package/dist/cli/react.d.ts.map +1 -1
  16. package/dist/cli/react.js +18 -0
  17. package/dist/cli/react.js.map +1 -1
  18. package/dist/cli/self-tuning.d.ts +33 -0
  19. package/dist/cli/self-tuning.d.ts.map +1 -0
  20. package/dist/cli/self-tuning.js +139 -0
  21. package/dist/cli/self-tuning.js.map +1 -0
  22. package/dist/cli/tune-adapter.d.ts +8 -0
  23. package/dist/cli/tune-adapter.d.ts.map +1 -0
  24. package/dist/cli/tune-adapter.js +26 -0
  25. package/dist/cli/tune-adapter.js.map +1 -0
  26. package/dist/config/settings-registry.d.ts.map +1 -1
  27. package/dist/config/settings-registry.js +10 -0
  28. package/dist/config/settings-registry.js.map +1 -1
  29. package/dist/coordination/adaptation-signal.d.ts +19 -0
  30. package/dist/coordination/adaptation-signal.d.ts.map +1 -0
  31. package/dist/coordination/adaptation-signal.js +36 -0
  32. package/dist/coordination/adaptation-signal.js.map +1 -0
  33. package/dist/delivery/agentic-executor.d.ts +16 -1
  34. package/dist/delivery/agentic-executor.d.ts.map +1 -1
  35. package/dist/delivery/agentic-executor.js +45 -4
  36. package/dist/delivery/agentic-executor.js.map +1 -1
  37. package/dist/delivery/decompose.d.ts +27 -0
  38. package/dist/delivery/decompose.d.ts.map +1 -1
  39. package/dist/delivery/decompose.js +31 -1
  40. package/dist/delivery/decompose.js.map +1 -1
  41. package/dist/delivery/repair-escalation.d.ts +49 -0
  42. package/dist/delivery/repair-escalation.d.ts.map +1 -0
  43. package/dist/delivery/repair-escalation.js +83 -0
  44. package/dist/delivery/repair-escalation.js.map +1 -0
  45. package/dist/delivery/verifier-ladder.d.ts +47 -0
  46. package/dist/delivery/verifier-ladder.d.ts.map +1 -1
  47. package/dist/delivery/verifier-ladder.js +87 -1
  48. package/dist/delivery/verifier-ladder.js.map +1 -1
  49. package/dist/self-harness/mods.d.ts +20 -1
  50. package/dist/self-harness/mods.d.ts.map +1 -1
  51. package/dist/self-harness/mods.js +41 -0
  52. package/dist/self-harness/mods.js.map +1 -1
  53. package/dist/self-harness/orchestrator.js +4 -0
  54. package/dist/self-harness/orchestrator.js.map +1 -1
  55. package/dist/self-harness/transfer.d.ts.map +1 -1
  56. package/dist/self-harness/transfer.js +2 -0
  57. package/dist/self-harness/transfer.js.map +1 -1
  58. package/dist/self-tuning/flag-writer.d.ts +48 -0
  59. package/dist/self-tuning/flag-writer.d.ts.map +1 -0
  60. package/dist/self-tuning/flag-writer.js +102 -0
  61. package/dist/self-tuning/flag-writer.js.map +1 -0
  62. package/dist/self-tuning/flags.d.ts +88 -0
  63. package/dist/self-tuning/flags.d.ts.map +1 -0
  64. package/dist/self-tuning/flags.js +189 -0
  65. package/dist/self-tuning/flags.js.map +1 -0
  66. package/dist/self-tuning/index.d.ts +25 -0
  67. package/dist/self-tuning/index.d.ts.map +1 -0
  68. package/dist/self-tuning/index.js +25 -0
  69. package/dist/self-tuning/index.js.map +1 -0
  70. package/dist/self-tuning/judge.d.ts +66 -0
  71. package/dist/self-tuning/judge.d.ts.map +1 -0
  72. package/dist/self-tuning/judge.js +145 -0
  73. package/dist/self-tuning/judge.js.map +1 -0
  74. package/dist/self-tuning/llm-tuner.d.ts +83 -0
  75. package/dist/self-tuning/llm-tuner.d.ts.map +1 -0
  76. package/dist/self-tuning/llm-tuner.js +191 -0
  77. package/dist/self-tuning/llm-tuner.js.map +1 -0
  78. package/dist/self-tuning/orchestrator.d.ts +90 -0
  79. package/dist/self-tuning/orchestrator.d.ts.map +1 -0
  80. package/dist/self-tuning/orchestrator.js +126 -0
  81. package/dist/self-tuning/orchestrator.js.map +1 -0
  82. package/dist/self-tuning/paired-validator.d.ts +50 -0
  83. package/dist/self-tuning/paired-validator.d.ts.map +1 -0
  84. package/dist/self-tuning/paired-validator.js +78 -0
  85. package/dist/self-tuning/paired-validator.js.map +1 -0
  86. package/dist/self-tuning/profiles/index.d.ts +11 -0
  87. package/dist/self-tuning/profiles/index.d.ts.map +1 -0
  88. package/dist/self-tuning/profiles/index.js +15 -0
  89. package/dist/self-tuning/profiles/index.js.map +1 -0
  90. package/dist/self-tuning/profiles/opus48.d.ts +11 -0
  91. package/dist/self-tuning/profiles/opus48.d.ts.map +1 -0
  92. package/dist/self-tuning/profiles/opus48.js +27 -0
  93. package/dist/self-tuning/profiles/opus48.js.map +1 -0
  94. package/dist/self-tuning/profiles/qwen36.d.ts +11 -0
  95. package/dist/self-tuning/profiles/qwen36.d.ts.map +1 -0
  96. package/dist/self-tuning/profiles/qwen36.js +33 -0
  97. package/dist/self-tuning/profiles/qwen36.js.map +1 -0
  98. package/dist/self-tuning/quality-scorer.d.ts +90 -0
  99. package/dist/self-tuning/quality-scorer.d.ts.map +1 -0
  100. package/dist/self-tuning/quality-scorer.js +180 -0
  101. package/dist/self-tuning/quality-scorer.js.map +1 -0
  102. package/dist/self-tuning/realtime-adaptor.d.ts +78 -0
  103. package/dist/self-tuning/realtime-adaptor.d.ts.map +1 -0
  104. package/dist/self-tuning/realtime-adaptor.js +127 -0
  105. package/dist/self-tuning/realtime-adaptor.js.map +1 -0
  106. package/dist/self-tuning/run.d.ts +61 -0
  107. package/dist/self-tuning/run.d.ts.map +1 -0
  108. package/dist/self-tuning/run.js +122 -0
  109. package/dist/self-tuning/run.js.map +1 -0
  110. package/dist/self-tuning/search-reducer.d.ts +76 -0
  111. package/dist/self-tuning/search-reducer.d.ts.map +1 -0
  112. package/dist/self-tuning/search-reducer.js +349 -0
  113. package/dist/self-tuning/search-reducer.js.map +1 -0
  114. package/dist/self-tuning/tuning-profile.d.ts +72 -0
  115. package/dist/self-tuning/tuning-profile.d.ts.map +1 -0
  116. package/dist/self-tuning/tuning-profile.js +134 -0
  117. package/dist/self-tuning/tuning-profile.js.map +1 -0
  118. package/dist/telemetry/session-telemetry.d.ts +25 -0
  119. package/dist/telemetry/session-telemetry.d.ts.map +1 -1
  120. package/dist/telemetry/session-telemetry.js +32 -0
  121. package/dist/telemetry/session-telemetry.js.map +1 -1
  122. package/dist/types/config.d.ts +13 -0
  123. package/dist/types/config.d.ts.map +1 -1
  124. package/dist/types/config.js +3 -0
  125. package/dist/types/config.js.map +1 -1
  126. package/docs/INDEX.md +7 -4
  127. package/docs/design/LLM_SELF_TUNING_ANALYSIS.md +617 -0
  128. package/docs/guides/AUTOMATIC_FEATURES.md +8 -0
  129. package/docs/guides/DROIDS_AND_SKILLS.md +1 -1
  130. package/docs/guides/SELF_TUNING.md +137 -0
  131. package/docs/reference/CLI.md +262 -1
  132. package/docs/reference/CONFIGURATION_REFERENCE.md +24 -0
  133. package/docs/reference/FEATURES.md +20 -5
  134. package/package.json +1 -1
  135. package/src/policies/enforcers/__pycache__/_common.cpython-312.pyc +0 -0
  136. package/tools/agents/scripts/__pycache__/toolcall_path_normalizer.cpython-312.pyc +0 -0
  137. package/tools/agents/scripts/anthropic_proxy.py +355 -29
  138. package/tools/agents/scripts/confidence_escalation.py +60 -4
  139. package/tools/agents/tests/test_confidence_escalation.py +77 -0
@@ -0,0 +1,145 @@
1
+ /**
2
+ * LLM Self-Tuning — the shared judge/tuner LLM client seam.
3
+ *
4
+ * Both the Quality Scorer (P0) and the LLM Tuner (P1) need to make a REAL call
5
+ * to a stronger "judge" model given a prompt and get text back. This module is
6
+ * the single, injectable seam for that:
7
+ *
8
+ * - `JudgeClient` is a tiny interface (id + complete) so every consumer is
9
+ * testable with a deterministic stub and never hard-wires the network.
10
+ * - `resolveJudgeClient` builds a production client over `OpenAICompatClient`
11
+ * + `ModelPresets`, resolving the judge model from an explicit id, the
12
+ * `recipes.judge.model` config field, or an Opus fallback — the same
13
+ * construction the `uap verify` acceptance judge uses (src/cli/verify.ts).
14
+ * - `parseJsonLenient` recovers a JSON object from a completion even when the
15
+ * model wraps it in prose / ``` fences (the local-model reality), while the
16
+ * `x-uap-json-response` grammar keeps the happy path deterministic.
17
+ *
18
+ * The recipe/confidence-escalation engine that consumes `recipes.judge.model`
19
+ * at serving time lives in the Python proxy; this is the TypeScript-side judge
20
+ * call the offline tuning loop uses. See docs/design/LLM_SELF_TUNING_ANALYSIS.md.
21
+ */
22
+ import { loadUapConfigRaw } from '../utils/config-loader.js';
23
+ /**
24
+ * Resolve a judge model id into a concrete `ModelConfig`. Order of preference:
25
+ * 1. an exact `ModelPresets` key,
26
+ * 2. a preset whose `apiModel` equals the id (accepts wire ids like `claude-opus-4-8`),
27
+ * 3. a synthesized Anthropic-style config using the id verbatim as the apiModel.
28
+ */
29
+ export function resolveJudgeModelConfig(id, presets) {
30
+ if (presets[id])
31
+ return presets[id];
32
+ const byApiModel = Object.values(presets).find((m) => m.apiModel === id);
33
+ if (byApiModel)
34
+ return byApiModel;
35
+ // Synthesize: treat the id as an OpenAI/Anthropic-compatible apiModel. The
36
+ // endpoint (and thus provider translation) is the proxy's concern.
37
+ return {
38
+ id,
39
+ name: id,
40
+ provider: id.startsWith('claude') ? 'anthropic' : 'custom',
41
+ apiModel: id,
42
+ apiKeyEnvVar: id.startsWith('claude') ? 'ANTHROPIC_API_KEY' : undefined,
43
+ maxContextTokens: 128000,
44
+ capabilities: [],
45
+ };
46
+ }
47
+ /**
48
+ * Build a production `JudgeClient`, or null when no judge model can be resolved
49
+ * and `requireExplicit`/no-fallback is in effect. Lazily imports the model layer
50
+ * so callers that never score/tune don't pay for it.
51
+ */
52
+ export async function resolveJudgeClient(opts = {}) {
53
+ let id = opts.judgeModel;
54
+ if (!id && opts.cwd !== undefined) {
55
+ const raw = loadUapConfigRaw(opts.cwd);
56
+ const configured = raw?.recipes?.judge?.model;
57
+ if (typeof configured === 'string' && configured.trim())
58
+ id = configured.trim();
59
+ }
60
+ if (!id) {
61
+ if (opts.requireExplicit)
62
+ return null;
63
+ id = opts.fallbackPreset ?? 'opus-4.8';
64
+ }
65
+ const { OpenAICompatClient } = await import('../models/openai-compat-client.js');
66
+ const { ModelPresets } = await import('../models/types.js');
67
+ const base = resolveJudgeModelConfig(id, ModelPresets);
68
+ const model = opts.endpoint ? { ...base, endpoint: opts.endpoint } : base;
69
+ const client = new OpenAICompatClient();
70
+ return {
71
+ id: model.apiModel,
72
+ async complete(prompt, o = {}) {
73
+ const r = await client.complete(model, prompt, {
74
+ temperature: o.temperature ?? 0.1,
75
+ jsonResponse: o.json,
76
+ ...(o.maxTokens ? { maxTokens: o.maxTokens } : {}),
77
+ });
78
+ return r.content;
79
+ },
80
+ };
81
+ }
82
+ /**
83
+ * Extract the first well-formed JSON object/array from a model completion.
84
+ * Tolerates ``` fences, a `<think>` preamble, and leading/trailing prose — the
85
+ * failure modes a local model produces even under the JSON grammar. Returns the
86
+ * parsed value, or null if no balanced JSON literal is found.
87
+ */
88
+ export function parseJsonLenient(text) {
89
+ if (!text)
90
+ return null;
91
+ // Fast path: the whole thing parses.
92
+ const trimmed = text.trim();
93
+ try {
94
+ return JSON.parse(trimmed);
95
+ }
96
+ catch {
97
+ /* fall through to scan */
98
+ }
99
+ // Strip a leading <think>…</think> block if present.
100
+ const afterThink = trimmed.replace(/^[\s\S]*?<\/think>/i, '').trim();
101
+ // Strip ``` fences.
102
+ const unfenced = afterThink.replace(/```(?:json)?/gi, '');
103
+ // Scan for the first balanced {...} or [...] literal.
104
+ for (const [open, close] of [['{', '}'], ['[', ']']]) {
105
+ const start = unfenced.indexOf(open);
106
+ if (start < 0)
107
+ continue;
108
+ let depth = 0;
109
+ let inStr = false;
110
+ let esc = false;
111
+ for (let i = start; i < unfenced.length; i++) {
112
+ const ch = unfenced[i];
113
+ if (esc) {
114
+ esc = false;
115
+ continue;
116
+ }
117
+ if (ch === '\\') {
118
+ esc = true;
119
+ continue;
120
+ }
121
+ if (ch === '"') {
122
+ inStr = !inStr;
123
+ continue;
124
+ }
125
+ if (inStr)
126
+ continue;
127
+ if (ch === open)
128
+ depth++;
129
+ else if (ch === close) {
130
+ depth--;
131
+ if (depth === 0) {
132
+ const candidate = unfenced.slice(start, i + 1);
133
+ try {
134
+ return JSON.parse(candidate);
135
+ }
136
+ catch {
137
+ break; // malformed; give up on this bracket type
138
+ }
139
+ }
140
+ }
141
+ }
142
+ }
143
+ return null;
144
+ }
145
+ //# sourceMappingURL=judge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"judge.js","sourceRoot":"","sources":["../../src/self-tuning/judge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * LLM Self-Tuning — the LLM Tuner (P1): LLM-guided flag-space exploration.
3
+ *
4
+ * The tuner is the "LLM as tuner, not executor" principle (design §3.1): a
5
+ * stronger model reasons over the quality history + flag interactions and
6
+ * proposes the next configuration; the small model then executes under it and
7
+ * the paired bench validates. Two production paths:
8
+ *
9
+ * - LLM path (a judge model configured): the tuner sends the active flag
10
+ * domains, the current config, and the past (config → quality) attempts, and
11
+ * asks for a small, interpretable change set with a rationale. Every
12
+ * proposed change is validated against the flag domain + dependency graph
13
+ * before it can reach the flag-writer — a hallucinated key or out-of-range
14
+ * value is dropped, never applied.
15
+ * - GP path (no judge, or the LLM proposes nothing usable): the Gaussian-
16
+ * process Bayesian optimizer (`search-reducer`) picks the next config by
17
+ * Expected Improvement. This is the deterministic, network-free fallback.
18
+ *
19
+ * Both return the same `TuningProposal`, so the orchestrator is agnostic to how
20
+ * the next config was chosen.
21
+ */
22
+ import type { JudgeClient } from './judge.js';
23
+ import { FlagChange, FlagConfig } from './flags.js';
24
+ import { Observation, SearchPhase } from './search-reducer.js';
25
+ export interface TuningProposal {
26
+ /** The flags to change and their new values (validated, ≤ maxChanges). */
27
+ changes: FlagChange[];
28
+ /** Why (LLM rationale, or a GP summary). */
29
+ rationale: string;
30
+ /** Expected composite-quality improvement (LLM estimate or GP mean gain). */
31
+ expectedDelta: number;
32
+ /** Confidence in the proposal, 0-1. */
33
+ confidence: number;
34
+ /** Model family this proposal is optimized for. */
35
+ targetModel: string;
36
+ /** Benchmark suites the orchestrator should validate against. */
37
+ validationSuites: string[];
38
+ /** How the proposal was produced. */
39
+ source: 'llm' | 'gp' | 'gp-fallback';
40
+ }
41
+ export interface TuningContext {
42
+ /** Executor model family being tuned. */
43
+ model: string;
44
+ /** The configuration currently in effect. */
45
+ currentConfig: FlagConfig;
46
+ /** Past (config, quality) trials — the GP conditioning set + LLM history. */
47
+ observations: Observation[];
48
+ /** Cross-model transfer priors (good configs from other models). */
49
+ priors?: FlagConfig[];
50
+ /** Suites to stamp on the proposal for validation. */
51
+ validationSuites?: string[];
52
+ }
53
+ export interface TunerOptions {
54
+ /** A resolved judge/tuner client. When null/omitted, the GP path is used. */
55
+ judge?: JudgeClient | null;
56
+ /** Max flags to change per proposal (interpretability bound). Default 4. */
57
+ maxChanges?: number;
58
+ /** Search phase (biases the GP candidate generation + the LLM guidance). */
59
+ phase?: SearchPhase;
60
+ /** RNG seed for the GP path. Default 1. */
61
+ seed?: number;
62
+ }
63
+ /** Compact human/LLM-readable description of the ACTIVE flag domains. */
64
+ export declare function describeActiveFlags(cfg: FlagConfig): string;
65
+ /** Build the tuner prompt (design §Phase 1). */
66
+ export declare function buildTunerPrompt(ctx: TuningContext, opts: TunerOptions): string;
67
+ /**
68
+ * Validate raw LLM-proposed changes into a clean `FlagChange[]`: keep only
69
+ * tunable keys, coerce each value into its domain, drop no-ops and changes to a
70
+ * flag whose parent won't be active after the change set is applied, and cap to
71
+ * `maxChanges`.
72
+ */
73
+ export declare function sanitizeChanges(currentConfig: FlagConfig, raw: Array<{
74
+ key?: unknown;
75
+ to?: unknown;
76
+ }>, maxChanges: number): FlagChange[];
77
+ /**
78
+ * Propose the next configuration to try. Uses the judge (LLM) when available and
79
+ * it returns usable changes; otherwise the Gaussian-process optimizer. Never
80
+ * throws — an LLM/parse failure degrades to the GP path.
81
+ */
82
+ export declare function proposeTuning(ctx: TuningContext, opts?: TunerOptions): Promise<TuningProposal>;
83
+ //# sourceMappingURL=llm-tuner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llm-tuner.d.ts","sourceRoot":"","sources":["../../src/self-tuning/llm-tuner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,OAAO,EACL,UAAU,EACV,UAAU,EAQX,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,WAAW,EACX,WAAW,EAEZ,MAAM,qBAAqB,CAAC;AAE7B,MAAM,WAAW,cAAc;IAC7B,0EAA0E;IAC1E,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,4CAA4C;IAC5C,SAAS,EAAE,MAAM,CAAC;IAClB,6EAA6E;IAC7E,aAAa,EAAE,MAAM,CAAC;IACtB,uCAAuC;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,mDAAmD;IACnD,WAAW,EAAE,MAAM,CAAC;IACpB,iEAAiE;IACjE,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,qCAAqC;IACrC,MAAM,EAAE,KAAK,GAAG,IAAI,GAAG,aAAa,CAAC;CACtC;AAED,MAAM,WAAW,aAAa;IAC5B,yCAAyC;IACzC,KAAK,EAAE,MAAM,CAAC;IACd,6CAA6C;IAC7C,aAAa,EAAE,UAAU,CAAC;IAC1B,6EAA6E;IAC7E,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,oEAAoE;IACpE,MAAM,CAAC,EAAE,UAAU,EAAE,CAAC;IACtB,sDAAsD;IACtD,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,YAAY;IAC3B,6EAA6E;IAC7E,KAAK,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IAC3B,4EAA4E;IAC5E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,4EAA4E;IAC5E,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,2CAA2C;IAC3C,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAQD,yEAAyE;AACzE,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,UAAU,GAAG,MAAM,CAc3D;AAeD,gDAAgD;AAChD,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,aAAa,EAAE,IAAI,EAAE,YAAY,GAAG,MAAM,CAwB/E;AASD;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,aAAa,EAAE,UAAU,EACzB,GAAG,EAAE,KAAK,CAAC;IAAE,GAAG,CAAC,EAAE,OAAO,CAAC;IAAC,EAAE,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,EAC3C,UAAU,EAAE,MAAM,GACjB,UAAU,EAAE,CAoBd;AAqCD;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,GAAG,EAAE,aAAa,EAAE,IAAI,GAAE,YAAiB,GAAG,OAAO,CAAC,cAAc,CAAC,CA+BxG"}
@@ -0,0 +1,191 @@
1
+ /**
2
+ * LLM Self-Tuning — the LLM Tuner (P1): LLM-guided flag-space exploration.
3
+ *
4
+ * The tuner is the "LLM as tuner, not executor" principle (design §3.1): a
5
+ * stronger model reasons over the quality history + flag interactions and
6
+ * proposes the next configuration; the small model then executes under it and
7
+ * the paired bench validates. Two production paths:
8
+ *
9
+ * - LLM path (a judge model configured): the tuner sends the active flag
10
+ * domains, the current config, and the past (config → quality) attempts, and
11
+ * asks for a small, interpretable change set with a rationale. Every
12
+ * proposed change is validated against the flag domain + dependency graph
13
+ * before it can reach the flag-writer — a hallucinated key or out-of-range
14
+ * value is dropped, never applied.
15
+ * - GP path (no judge, or the LLM proposes nothing usable): the Gaussian-
16
+ * process Bayesian optimizer (`search-reducer`) picks the next config by
17
+ * Expected Improvement. This is the deterministic, network-free fallback.
18
+ *
19
+ * Both return the same `TuningProposal`, so the orchestrator is agnostic to how
20
+ * the next config was chosen.
21
+ */
22
+ import { parseJsonLenient } from './judge.js';
23
+ import { TUNABLE_FLAGS, applyChanges, coerceToDomain, diffConfigs, flagValue, getTunableFlag, isFlagActive, } from './flags.js';
24
+ import { proposeNext, } from './search-reducer.js';
25
+ /** The current best-known quality (from observations), for delta estimates. */
26
+ function currentQuality(ctx) {
27
+ if (ctx.observations.length === 0)
28
+ return 0;
29
+ return ctx.observations.reduce((a, o) => Math.max(a, o.quality), 0);
30
+ }
31
+ /** Compact human/LLM-readable description of the ACTIVE flag domains. */
32
+ export function describeActiveFlags(cfg) {
33
+ const lines = [];
34
+ for (const f of TUNABLE_FLAGS) {
35
+ if (!isFlagActive(f, cfg))
36
+ continue;
37
+ const d = f.domain;
38
+ const dom = d.kind === 'bool'
39
+ ? 'true|false'
40
+ : d.kind === 'enum'
41
+ ? d.values.join('|')
42
+ : `${d.min}..${d.max}${d.int ? ' (int)' : ''}`;
43
+ lines.push(`- ${f.key} = ${JSON.stringify(flagValue(cfg, f.key))} [${dom}]`);
44
+ }
45
+ return lines.join('\n');
46
+ }
47
+ function historyForPrompt(observations, limit = 8) {
48
+ if (!observations.length)
49
+ return '(none yet)';
50
+ return observations
51
+ .slice(-limit)
52
+ .map((o, i) => {
53
+ const changed = TUNABLE_FLAGS.filter((f) => isFlagActive(f, o.config))
54
+ .map((f) => `${f.key}=${flagValue(o.config, f.key)}`)
55
+ .join(', ');
56
+ return `#${i + 1} quality=${o.quality.toFixed(1)} :: ${changed.slice(0, 240)}`;
57
+ })
58
+ .join('\n');
59
+ }
60
+ /** Build the tuner prompt (design §Phase 1). */
61
+ export function buildTunerPrompt(ctx, opts) {
62
+ const maxChanges = opts.maxChanges ?? 4;
63
+ return [
64
+ 'You are a configuration optimizer for the Universal Agent Protocol (UAP).',
65
+ `Your goal: raise the composite quality (0-100) of the executor model by tuning UAP flags.`,
66
+ '',
67
+ `EXECUTOR MODEL: ${ctx.model}`,
68
+ `PHASE: ${opts.phase ?? 'combinatorial'} (coarse=toggle enablers, medium=enums, fine=numbers, combinatorial=interactions)`,
69
+ '',
70
+ 'ACTIVE FLAGS (key = current value [domain]):',
71
+ describeActiveFlags(ctx.currentConfig),
72
+ '',
73
+ 'PAST ATTEMPTS (most recent last):',
74
+ historyForPrompt(ctx.observations),
75
+ '',
76
+ 'RULES:',
77
+ `- Change only ${maxChanges} or fewer flags (keep it interpretable).`,
78
+ '- Only use keys from ACTIVE FLAGS above; respect each domain.',
79
+ '- Prefer changes that plausibly lift quality given the history.',
80
+ '- A dependent flag (e.g. recipes.fusionN) only helps if its parent is enabled.',
81
+ '',
82
+ 'Respond with ONLY this JSON, no prose:',
83
+ '{"changes":[{"key":"<flag>","to":<value>}],"rationale":"<why>","expectedDelta":<number>,"confidence":<0-1>}',
84
+ ].join('\n');
85
+ }
86
+ /**
87
+ * Validate raw LLM-proposed changes into a clean `FlagChange[]`: keep only
88
+ * tunable keys, coerce each value into its domain, drop no-ops and changes to a
89
+ * flag whose parent won't be active after the change set is applied, and cap to
90
+ * `maxChanges`.
91
+ */
92
+ export function sanitizeChanges(currentConfig, raw, maxChanges) {
93
+ const cleaned = [];
94
+ for (const c of raw) {
95
+ if (typeof c?.key !== 'string')
96
+ continue;
97
+ const flag = getTunableFlag(c.key);
98
+ if (!flag)
99
+ continue;
100
+ if (c.to === undefined || c.to === null)
101
+ continue;
102
+ const to = coerceToDomain(c.key, c.to);
103
+ if (to === null)
104
+ continue;
105
+ const from = flagValue(currentConfig, c.key) ?? null;
106
+ if (to === from)
107
+ continue; // no-op
108
+ cleaned.push({ key: c.key, from, to, category: flag.category });
109
+ if (cleaned.length >= maxChanges)
110
+ break;
111
+ }
112
+ // Drop changes to a flag whose dependencies aren't satisfied by the RESULT.
113
+ const result = applyChanges(currentConfig, cleaned);
114
+ return cleaned.filter((c) => {
115
+ const flag = getTunableFlag(c.key);
116
+ return isFlagActive(flag, result);
117
+ });
118
+ }
119
+ /** GP-path proposal: next config by Expected Improvement. */
120
+ function gpProposal(ctx, opts, source) {
121
+ const suggestion = proposeNext(ctx.observations, {
122
+ seed: opts.seed,
123
+ phase: opts.phase,
124
+ priors: ctx.priors,
125
+ seedConfig: ctx.currentConfig,
126
+ });
127
+ const base = currentQuality(ctx);
128
+ if (!suggestion) {
129
+ return {
130
+ changes: [],
131
+ rationale: 'no candidates to explore (empty search space or no observations)',
132
+ expectedDelta: 0,
133
+ confidence: 0,
134
+ targetModel: ctx.model,
135
+ validationSuites: ctx.validationSuites ?? [],
136
+ source,
137
+ };
138
+ }
139
+ const changes = diffConfigs(ctx.currentConfig, suggestion.config).slice(0, opts.maxChanges ?? 4);
140
+ const expectedDelta = Number.isFinite(suggestion.mean) ? suggestion.mean - base : 0;
141
+ // Confidence from predictive certainty: tighter std → higher confidence.
142
+ const confidence = suggestion.std > 0 ? Math.max(0, Math.min(1, 1 - suggestion.std / 50)) : 0.5;
143
+ return {
144
+ changes,
145
+ rationale: `GP-BO: EI=${Number.isFinite(suggestion.ei) ? suggestion.ei.toFixed(3) : '∞'}, predicted quality ${suggestion.mean.toFixed(1)}±${suggestion.std.toFixed(1)}`,
146
+ expectedDelta,
147
+ confidence,
148
+ targetModel: ctx.model,
149
+ validationSuites: ctx.validationSuites ?? [],
150
+ source,
151
+ };
152
+ }
153
+ /**
154
+ * Propose the next configuration to try. Uses the judge (LLM) when available and
155
+ * it returns usable changes; otherwise the Gaussian-process optimizer. Never
156
+ * throws — an LLM/parse failure degrades to the GP path.
157
+ */
158
+ export async function proposeTuning(ctx, opts = {}) {
159
+ const maxChanges = opts.maxChanges ?? 4;
160
+ if (!opts.judge)
161
+ return gpProposal(ctx, opts, 'gp');
162
+ let raw = null;
163
+ try {
164
+ const text = await opts.judge.complete(buildTunerPrompt(ctx, opts), { json: true, temperature: 0.2 });
165
+ raw = parseJsonLenient(text);
166
+ }
167
+ catch {
168
+ raw = null;
169
+ }
170
+ if (!raw || !Array.isArray(raw.changes))
171
+ return gpProposal(ctx, opts, 'gp-fallback');
172
+ const changes = sanitizeChanges(ctx.currentConfig, raw.changes, maxChanges);
173
+ if (changes.length === 0)
174
+ return gpProposal(ctx, opts, 'gp-fallback');
175
+ const expectedDelta = typeof raw.expectedDelta === 'number' && Number.isFinite(raw.expectedDelta)
176
+ ? raw.expectedDelta
177
+ : 0;
178
+ const confidence = typeof raw.confidence === 'number' && Number.isFinite(raw.confidence)
179
+ ? Math.max(0, Math.min(1, raw.confidence))
180
+ : 0.5;
181
+ return {
182
+ changes,
183
+ rationale: typeof raw.rationale === 'string' ? raw.rationale.slice(0, 400) : 'LLM tuner proposal',
184
+ expectedDelta,
185
+ confidence,
186
+ targetModel: ctx.model,
187
+ validationSuites: ctx.validationSuites ?? [],
188
+ source: 'llm',
189
+ };
190
+ }
191
+ //# sourceMappingURL=llm-tuner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llm-tuner.js","sourceRoot":"","sources":["../../src/self-tuning/llm-tuner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * LLM Self-Tuning — the closed-loop orchestrator (P2).
3
+ *
4
+ * One tuning iteration: propose → apply → validate → decide → learn.
5
+ *
6
+ * 1. PROPOSE the next config (LLM tuner, or GP-BO fallback).
7
+ * 2. APPLY the change set onto the current config (in-memory here; the
8
+ * committing loop in run.ts persists it via the flag-writer).
9
+ * 3. VALIDATE it with the INJECTED paired-bench validator — it runs the
10
+ * candidate config against the current config over the validation
11
+ * (and held-out) suites and returns the quality-scored comparison.
12
+ * 4. DECIDE accept iff the composite-QUALITY delta clears a hysteresis band,
13
+ * is statistically supported, and the held-out suite doesn't
14
+ * regress — the "conservative validation preventing regressions"
15
+ * rule, keyed to quality rather than raw correctness.
16
+ * 5. LEARN accepted configs advance the model's TuningProfile; the loop's
17
+ * observations feed the GP so the next proposal is better-informed.
18
+ *
19
+ * The validator is injected so the loop is unit-testable without a live model,
20
+ * exactly like the self-harness orchestrator.
21
+ */
22
+ import type { Comparison } from '../benchmarks/paired/report.js';
23
+ import { FlagChange, FlagConfig } from './flags.js';
24
+ import { TuningContext, TunerOptions, TuningProposal } from './llm-tuner.js';
25
+ import type { Observation, SearchPhase } from './search-reducer.js';
26
+ /** The paired-bench result for a candidate config vs the current config. */
27
+ export interface TuningValidationOutcome {
28
+ validation: Comparison;
29
+ /** Held-out comparison; null when the held-out suite was skipped. */
30
+ heldout: Comparison | null;
31
+ /** Measured composite quality of the candidate arm (for the observation set). */
32
+ candidateQuality: number;
33
+ }
34
+ /**
35
+ * Runs a candidate config against the current config and returns the scored
36
+ * comparison. The real implementation (run.ts) applies the candidate via the
37
+ * flag-writer, runs the paired bench with quality scoring, and reverts; tests
38
+ * inject a deterministic stub.
39
+ */
40
+ export type TuningValidator = (candidate: FlagConfig, current: FlagConfig) => Promise<TuningValidationOutcome>;
41
+ export interface TuningDecisionOptions {
42
+ /**
43
+ * Minimum composite-quality improvement (points, 0-100) required to accept — a
44
+ * hysteresis band that stops the config oscillating on noise (design §6). The
45
+ * delta must ALSO be statistically significant. Default 2.
46
+ */
47
+ minQualityGain?: number;
48
+ /** Tolerated held-out quality regression before rejecting. Default 2. */
49
+ heldoutRegressionTolerance?: number;
50
+ }
51
+ export type TuningVerdict = 'accept' | 'reject';
52
+ export interface TuningDecision {
53
+ verdict: TuningVerdict;
54
+ reason: string;
55
+ qualityDelta: number;
56
+ heldoutQualityDelta: number | null;
57
+ }
58
+ /**
59
+ * Accept a candidate iff its validation quality delta clears the hysteresis band
60
+ * AND is significant AND the held-out suite shows no significant quality
61
+ * regression. Falls back to the correctness delta when quality scores are
62
+ * absent (a bench run without scoring).
63
+ */
64
+ export declare function decideTuning(validation: Comparison, heldout: Comparison | null, opts?: TuningDecisionOptions): TuningDecision;
65
+ export interface TuningIterationOptions {
66
+ ctx: TuningContext;
67
+ validate: TuningValidator;
68
+ tuner?: TunerOptions;
69
+ decision?: TuningDecisionOptions;
70
+ phase?: SearchPhase;
71
+ log?: (msg: string) => void;
72
+ }
73
+ export interface TuningIterationResult {
74
+ proposal: TuningProposal;
75
+ /** The config that would be adopted if accepted. */
76
+ candidateConfig: FlagConfig;
77
+ decision: TuningDecision | null;
78
+ accepted: boolean;
79
+ /** New best config after this iteration (candidate if accepted, else current). */
80
+ config: FlagConfig;
81
+ /** Observation appended for the GP (the candidate's measured quality). */
82
+ observation: Observation | null;
83
+ outcome: 'accepted' | 'rejected' | 'plateau' | 'error';
84
+ error?: string;
85
+ }
86
+ /** Run ONE tuning iteration (propose → validate → decide). Never throws. */
87
+ export declare function runTuningIteration(opts: TuningIterationOptions): Promise<TuningIterationResult>;
88
+ /** Convert an accepted proposal's changes into a compact one-line audit string. */
89
+ export declare function describeChanges(changes: FlagChange[]): string;
90
+ //# sourceMappingURL=orchestrator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../../src/self-tuning/orchestrator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAgB,MAAM,YAAY,CAAC;AAClE,OAAO,EACL,aAAa,EACb,YAAY,EACZ,cAAc,EAEf,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEpE,4EAA4E;AAC5E,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,UAAU,CAAC;IACvB,qEAAqE;IACrE,OAAO,EAAE,UAAU,GAAG,IAAI,CAAC;IAC3B,iFAAiF;IACjF,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;GAKG;AACH,MAAM,MAAM,eAAe,GAAG,CAC5B,SAAS,EAAE,UAAU,EACrB,OAAO,EAAE,UAAU,KAChB,OAAO,CAAC,uBAAuB,CAAC,CAAC;AAEtC,MAAM,WAAW,qBAAqB;IACpC;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,yEAAyE;IACzE,0BAA0B,CAAC,EAAE,MAAM,CAAC;CACrC;AAED,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAEhD,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,aAAa,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;CACpC;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAC1B,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,UAAU,GAAG,IAAI,EAC1B,IAAI,GAAE,qBAA0B,GAC/B,cAAc,CAyChB;AAED,MAAM,WAAW,sBAAsB;IACrC,GAAG,EAAE,aAAa,CAAC;IACnB,QAAQ,EAAE,eAAe,CAAC;IAC1B,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,QAAQ,CAAC,EAAE,qBAAqB,CAAC;IACjC,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7B;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,cAAc,CAAC;IACzB,oDAAoD;IACpD,eAAe,EAAE,UAAU,CAAC;IAC5B,QAAQ,EAAE,cAAc,GAAG,IAAI,CAAC;IAChC,QAAQ,EAAE,OAAO,CAAC;IAClB,kFAAkF;IAClF,MAAM,EAAE,UAAU,CAAC;IACnB,0EAA0E;IAC1E,WAAW,EAAE,WAAW,GAAG,IAAI,CAAC;IAChC,OAAO,EAAE,UAAU,GAAG,UAAU,GAAG,SAAS,GAAG,OAAO,CAAC;IACvD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,4EAA4E;AAC5E,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,sBAAsB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CA0DrG;AAED,mFAAmF;AACnF,wBAAgB,eAAe,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,MAAM,CAE7D"}