@claudexor/harness-claude 3.0.4 → 3.1.1
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/dist/context-signals.d.ts +52 -0
- package/dist/context-signals.d.ts.map +1 -0
- package/dist/context-signals.js +167 -0
- package/dist/context-signals.js.map +1 -0
- package/dist/effort-probe.d.ts +144 -0
- package/dist/effort-probe.d.ts.map +1 -0
- package/dist/effort-probe.js +339 -0
- package/dist/effort-probe.js.map +1 -0
- package/dist/index.d.ts +17 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +68 -50
- package/dist/index.js.map +1 -1
- package/dist/parse.d.ts.map +1 -1
- package/dist/parse.js +33 -36
- package/dist/parse.js.map +1 -1
- package/package.json +5 -5
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { HarnessEvent } from "@claudexor/schema";
|
|
2
|
+
/**
|
|
3
|
+
* D-16c: claude 2.1.165 typed context / rate-limit signal mapping, extracted
|
|
4
|
+
* from the main stream parser so each concern stays a small, testable owner.
|
|
5
|
+
* These map FIXTURE-PROVEN vendor frames onto typed HarnessEvents — no prose
|
|
6
|
+
* matching. Context signals are a sibling of the transient-retry taxonomy and
|
|
7
|
+
* NEVER enter the transient_retry loop.
|
|
8
|
+
*/
|
|
9
|
+
type Json = any;
|
|
10
|
+
/**
|
|
11
|
+
* `system/compact_boundary` → a typed compaction context event. The boundary is
|
|
12
|
+
* the COMPLETION of a compaction; `trigger` (auto|manual) and `pre_tokens` ride
|
|
13
|
+
* through as evidence. The frame states no cause, so cause stays `unknown`.
|
|
14
|
+
*/
|
|
15
|
+
export declare function claudeCompactBoundaryEvents(obj: Json, sessionId: string, ts: string): HarnessEvent[];
|
|
16
|
+
/**
|
|
17
|
+
* QA-015: the top-level typed `rate_limit_event` heartbeat. Always RECOGNIZED
|
|
18
|
+
* (never a dropped event). The routine `allowed` heartbeat surfaces NOTHING
|
|
19
|
+
* (arming a rate_limit signal on it would falsely trip the rotation predicate);
|
|
20
|
+
* only a limiting status arms the TYPED `rate_limit` signal the budget layer
|
|
21
|
+
* reads. Returns `[]` for the benign heartbeat.
|
|
22
|
+
*/
|
|
23
|
+
export declare function claudeRateLimitEvents(obj: Json, sessionId: string, ts: string): HarnessEvent[];
|
|
24
|
+
/**
|
|
25
|
+
* Map the FIXTURE-PROVEN result `terminal_reason` values onto a typed
|
|
26
|
+
* context-exhaustion event (or null for `completed`/unrecognized). No prose
|
|
27
|
+
* matching — only the typed vendor enum. `prompt_too_long` is an irreducible-
|
|
28
|
+
* packet exhaustion (NOT continuation-eligible); `rapid_refill_breaker` is the
|
|
29
|
+
* SDK's repeated-refill breaker (the continuation-eligible cause).
|
|
30
|
+
*/
|
|
31
|
+
export declare function claudeTerminalContextEvent(terminalReason: unknown, sessionId: string, ts: string): HarnessEvent | null;
|
|
32
|
+
/**
|
|
33
|
+
* D-16c side_tool: a `{work_report}`-ONLY structured_output (no `output` key) is
|
|
34
|
+
* the claude StructuredOutput-tool WorkReport envelope — the report rides the
|
|
35
|
+
* tool while the markdown final message stays the deliverable. Returns the raw
|
|
36
|
+
* work_report value, or undefined when the structured_output is a full
|
|
37
|
+
* `{work_report, output}` envelope / a plain caller-schema answer (both of
|
|
38
|
+
* which surface AS the final message).
|
|
39
|
+
*/
|
|
40
|
+
/**
|
|
41
|
+
* The final-message events a `result` frame emits (D-16c). Precedence:
|
|
42
|
+
* - a full `{work_report, output}` envelope / plain structured answer surfaces
|
|
43
|
+
* AS the final message (`structured_output` finality);
|
|
44
|
+
* - otherwise the markdown `result` is the final message (side_tool rides its
|
|
45
|
+
* WorkReport on the message payload);
|
|
46
|
+
* - a side_tool report with no deliverable text still surfaces (rare).
|
|
47
|
+
* Finality is stamped only for a success result.
|
|
48
|
+
*/
|
|
49
|
+
export declare function claudeResultMessageEvents(obj: Json, successResult: boolean, sessionId: string, ts: string): HarnessEvent[];
|
|
50
|
+
export declare function claudeSideToolReport(structuredOutput: unknown): unknown;
|
|
51
|
+
export {};
|
|
52
|
+
//# sourceMappingURL=context-signals.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-signals.d.ts","sourceRoot":"","sources":["../src/context-signals.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD;;;;;;GAMG;AACH,KAAK,IAAI,GAAG,GAAG,CAAC;AAMhB;;;;GAIG;AACH,wBAAgB,2BAA2B,CACzC,GAAG,EAAE,IAAI,EACT,SAAS,EAAE,MAAM,EACjB,EAAE,EAAE,MAAM,GACT,YAAY,EAAE,CAkBhB;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,YAAY,EAAE,CAiB9F;AAED;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CACxC,cAAc,EAAE,OAAO,EACvB,SAAS,EAAE,MAAM,EACjB,EAAE,EAAE,MAAM,GACT,YAAY,GAAG,IAAI,CA8BrB;AAED;;;;;;;GAOG;AACH;;;;;;;;GAQG;AACH,wBAAgB,yBAAyB,CACvC,GAAG,EAAE,IAAI,EACT,aAAa,EAAE,OAAO,EACtB,SAAS,EAAE,MAAM,EACjB,EAAE,EAAE,MAAM,GACT,YAAY,EAAE,CAiDhB;AAED,wBAAgB,oBAAoB,CAAC,gBAAgB,EAAE,OAAO,GAAG,OAAO,CAWvE"}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
function numberOrNull(v) {
|
|
2
|
+
return typeof v === "number" ? v : null;
|
|
3
|
+
}
|
|
4
|
+
/**
|
|
5
|
+
* `system/compact_boundary` → a typed compaction context event. The boundary is
|
|
6
|
+
* the COMPLETION of a compaction; `trigger` (auto|manual) and `pre_tokens` ride
|
|
7
|
+
* through as evidence. The frame states no cause, so cause stays `unknown`.
|
|
8
|
+
*/
|
|
9
|
+
export function claudeCompactBoundaryEvents(obj, sessionId, ts) {
|
|
10
|
+
const meta = obj.compact_metadata && typeof obj.compact_metadata === "object" ? obj.compact_metadata : {};
|
|
11
|
+
const trigger = meta.trigger;
|
|
12
|
+
return [
|
|
13
|
+
{
|
|
14
|
+
type: "context",
|
|
15
|
+
session_id: sessionId,
|
|
16
|
+
ts,
|
|
17
|
+
context: {
|
|
18
|
+
kind: "compaction_completed",
|
|
19
|
+
cause: "unknown",
|
|
20
|
+
native_code: null,
|
|
21
|
+
trigger: trigger === "manual" || trigger === "auto" ? trigger : null,
|
|
22
|
+
pre_tokens: numberOrNull(meta.pre_tokens),
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
];
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* QA-015: the top-level typed `rate_limit_event` heartbeat. Always RECOGNIZED
|
|
29
|
+
* (never a dropped event). The routine `allowed` heartbeat surfaces NOTHING
|
|
30
|
+
* (arming a rate_limit signal on it would falsely trip the rotation predicate);
|
|
31
|
+
* only a limiting status arms the TYPED `rate_limit` signal the budget layer
|
|
32
|
+
* reads. Returns `[]` for the benign heartbeat.
|
|
33
|
+
*/
|
|
34
|
+
export function claudeRateLimitEvents(obj, sessionId, ts) {
|
|
35
|
+
const info = obj.rate_limit_info && typeof obj.rate_limit_info === "object" ? obj.rate_limit_info : null;
|
|
36
|
+
const status = info ? info.status : undefined;
|
|
37
|
+
if (status !== "allowed_warning" && status !== "rejected" && status !== "blocked")
|
|
38
|
+
return [];
|
|
39
|
+
const resetsRaw = info ? info.resetsAt : undefined;
|
|
40
|
+
const resetsAt = typeof resetsRaw === "number" ? new Date(resetsRaw * 1000).toISOString() : null;
|
|
41
|
+
return [
|
|
42
|
+
{
|
|
43
|
+
type: "status",
|
|
44
|
+
session_id: sessionId,
|
|
45
|
+
ts,
|
|
46
|
+
text: `rate_limit_event: ${String(status)}`,
|
|
47
|
+
rate_limit: { resets_at: resetsAt, retry_delay_ms: null },
|
|
48
|
+
payload: { rate_limit_event: true },
|
|
49
|
+
},
|
|
50
|
+
];
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Map the FIXTURE-PROVEN result `terminal_reason` values onto a typed
|
|
54
|
+
* context-exhaustion event (or null for `completed`/unrecognized). No prose
|
|
55
|
+
* matching — only the typed vendor enum. `prompt_too_long` is an irreducible-
|
|
56
|
+
* packet exhaustion (NOT continuation-eligible); `rapid_refill_breaker` is the
|
|
57
|
+
* SDK's repeated-refill breaker (the continuation-eligible cause).
|
|
58
|
+
*/
|
|
59
|
+
export function claudeTerminalContextEvent(terminalReason, sessionId, ts) {
|
|
60
|
+
if (terminalReason === "prompt_too_long") {
|
|
61
|
+
return {
|
|
62
|
+
type: "context",
|
|
63
|
+
session_id: sessionId,
|
|
64
|
+
ts,
|
|
65
|
+
context: {
|
|
66
|
+
kind: "capacity_exhausted",
|
|
67
|
+
cause: "prompt_too_long",
|
|
68
|
+
native_code: "prompt_too_long",
|
|
69
|
+
trigger: null,
|
|
70
|
+
pre_tokens: null,
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
if (terminalReason === "rapid_refill_breaker") {
|
|
75
|
+
return {
|
|
76
|
+
type: "context",
|
|
77
|
+
session_id: sessionId,
|
|
78
|
+
ts,
|
|
79
|
+
context: {
|
|
80
|
+
kind: "capacity_exhausted",
|
|
81
|
+
cause: "repeated_refill",
|
|
82
|
+
native_code: "rapid_refill_breaker",
|
|
83
|
+
trigger: null,
|
|
84
|
+
pre_tokens: null,
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* D-16c side_tool: a `{work_report}`-ONLY structured_output (no `output` key) is
|
|
92
|
+
* the claude StructuredOutput-tool WorkReport envelope — the report rides the
|
|
93
|
+
* tool while the markdown final message stays the deliverable. Returns the raw
|
|
94
|
+
* work_report value, or undefined when the structured_output is a full
|
|
95
|
+
* `{work_report, output}` envelope / a plain caller-schema answer (both of
|
|
96
|
+
* which surface AS the final message).
|
|
97
|
+
*/
|
|
98
|
+
/**
|
|
99
|
+
* The final-message events a `result` frame emits (D-16c). Precedence:
|
|
100
|
+
* - a full `{work_report, output}` envelope / plain structured answer surfaces
|
|
101
|
+
* AS the final message (`structured_output` finality);
|
|
102
|
+
* - otherwise the markdown `result` is the final message (side_tool rides its
|
|
103
|
+
* WorkReport on the message payload);
|
|
104
|
+
* - a side_tool report with no deliverable text still surfaces (rare).
|
|
105
|
+
* Finality is stamped only for a success result.
|
|
106
|
+
*/
|
|
107
|
+
export function claudeResultMessageEvents(obj, successResult, sessionId, ts) {
|
|
108
|
+
const so = obj.structured_output;
|
|
109
|
+
const sideToolReport = claudeSideToolReport(so);
|
|
110
|
+
if (so !== undefined && so !== null && sideToolReport === undefined) {
|
|
111
|
+
return [
|
|
112
|
+
{
|
|
113
|
+
type: "message",
|
|
114
|
+
session_id: sessionId,
|
|
115
|
+
ts,
|
|
116
|
+
text: JSON.stringify(so),
|
|
117
|
+
...(successResult ? { final: true } : {}),
|
|
118
|
+
payload: {
|
|
119
|
+
structured_output: true,
|
|
120
|
+
...(successResult ? { final_source: "structured_output" } : {}),
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
];
|
|
124
|
+
}
|
|
125
|
+
if (typeof obj.result === "string" && obj.result.trim()) {
|
|
126
|
+
return [
|
|
127
|
+
{
|
|
128
|
+
type: "message",
|
|
129
|
+
session_id: sessionId,
|
|
130
|
+
ts,
|
|
131
|
+
text: obj.result,
|
|
132
|
+
...(successResult ? { final: true } : {}),
|
|
133
|
+
...(successResult || sideToolReport !== undefined
|
|
134
|
+
? {
|
|
135
|
+
payload: {
|
|
136
|
+
...(successResult ? { final_source: "result" } : {}),
|
|
137
|
+
...(sideToolReport !== undefined ? { work_report_side_tool: sideToolReport } : {}),
|
|
138
|
+
},
|
|
139
|
+
}
|
|
140
|
+
: {}),
|
|
141
|
+
},
|
|
142
|
+
];
|
|
143
|
+
}
|
|
144
|
+
if (sideToolReport !== undefined) {
|
|
145
|
+
return [
|
|
146
|
+
{
|
|
147
|
+
type: "status",
|
|
148
|
+
session_id: sessionId,
|
|
149
|
+
ts,
|
|
150
|
+
text: "work_report (side_tool, no deliverable text)",
|
|
151
|
+
payload: { work_report_side_tool: sideToolReport },
|
|
152
|
+
},
|
|
153
|
+
];
|
|
154
|
+
}
|
|
155
|
+
return [];
|
|
156
|
+
}
|
|
157
|
+
export function claudeSideToolReport(structuredOutput) {
|
|
158
|
+
if (structuredOutput &&
|
|
159
|
+
typeof structuredOutput === "object" &&
|
|
160
|
+
!Array.isArray(structuredOutput) &&
|
|
161
|
+
"work_report" in structuredOutput &&
|
|
162
|
+
!("output" in structuredOutput)) {
|
|
163
|
+
return structuredOutput.work_report;
|
|
164
|
+
}
|
|
165
|
+
return undefined;
|
|
166
|
+
}
|
|
167
|
+
//# sourceMappingURL=context-signals.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-signals.js","sourceRoot":"","sources":["../src/context-signals.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Effort discovery for the INSTALLED claude CLI.
|
|
3
|
+
*
|
|
4
|
+
* Claude Code's effort ladder is a property of the binary on this machine, not
|
|
5
|
+
* of Claudexor: 2.1.89 advertises `low, medium, high, max` while 2.1.165
|
|
6
|
+
* advertises `low, medium, high, xhigh, max`. Hardcoding either one means one
|
|
7
|
+
* installed version gets silently clamped, which is exactly the defect this
|
|
8
|
+
* replaces. So we read the ladder out of the binary's own `--help`.
|
|
9
|
+
*
|
|
10
|
+
* The help line looks like:
|
|
11
|
+
* --effort <level> Effort level for the current session (low, medium, high, xhigh, max)
|
|
12
|
+
* with the parenthesized list possibly wrapped onto following lines — and HOW FAR
|
|
13
|
+
* it wraps depends on the terminal width, so the parse reads the flag's whole
|
|
14
|
+
* block rather than a fixed number of lines.
|
|
15
|
+
*
|
|
16
|
+
* On a missing binary, an unparseable help text, or a `--help` that stops
|
|
17
|
+
* documenting the values, the recorded snapshot fills in and the run proceeds.
|
|
18
|
+
*/
|
|
19
|
+
import type { HarnessEvent, HarnessRunSpec } from "@claudexor/schema";
|
|
20
|
+
import { EffortHint } from "@claudexor/schema";
|
|
21
|
+
export declare const BIN: string;
|
|
22
|
+
/**
|
|
23
|
+
* Recorded fallback, captured from `claude --help` on the CLI version stamped
|
|
24
|
+
* below. Used ONLY when the live parse cannot answer.
|
|
25
|
+
*/
|
|
26
|
+
export declare const CLAUDE_EFFORT_SNAPSHOT: readonly EffortHint[];
|
|
27
|
+
/** Vendor CLI version `CLAUDE_EFFORT_SNAPSHOT` was captured from. */
|
|
28
|
+
export declare const CLAUDE_EFFORT_SNAPSHOT_VERIFIED_AGAINST = "2.1.165";
|
|
29
|
+
/**
|
|
30
|
+
* Whether the recorded snapshot may be TRUSTED for arg emission against the
|
|
31
|
+
* installed binary (INV-105). The snapshot is another `--help`'s recorded
|
|
32
|
+
* answer, so it is only that binary's truth on the exact CLI version it was
|
|
33
|
+
* captured from: 2.1.165 advertises `xhigh`, 2.1.89 rejects it, and a 2.1.89
|
|
34
|
+
* install whose live parse failed used to be handed the 2.1.165 ladder anyway
|
|
35
|
+
* — `--effort xhigh` then went to a CLI that refuses the flag.
|
|
36
|
+
*
|
|
37
|
+
* The installed version string is whatever `claude --version` printed
|
|
38
|
+
* (e.g. `2.1.165 (Claude Code)`), so the comparison extracts the full dotted
|
|
39
|
+
* numeric token and requires it to EQUAL the snapshot stamp exactly. An
|
|
40
|
+
* unknown or unparseable version can never vouch for the snapshot.
|
|
41
|
+
*/
|
|
42
|
+
export declare function claudeSnapshotTrustedForVersion(installedVersion: string | null): boolean;
|
|
43
|
+
/**
|
|
44
|
+
* The effort ladder the RUN may resolve `--effort` against, version-gating
|
|
45
|
+
* snapshot trust (INV-105):
|
|
46
|
+
*
|
|
47
|
+
* - a LIVE parse is the installed binary's own answer — trusted on any version;
|
|
48
|
+
* - the snapshot FALLBACK is trusted only when the installed version equals
|
|
49
|
+
* `CLAUDE_EFFORT_SNAPSHOT_VERIFIED_AGAINST` (same binary, same ladder);
|
|
50
|
+
* - a fallback on ANY OTHER version (mismatch, unknown, unparseable) yields an
|
|
51
|
+
* EMPTY ladder: the normalizer then sends no `--effort` flag at all, and the
|
|
52
|
+
* existing drop seam (`claudeEffortIgnoredEvent`) discloses it — the run
|
|
53
|
+
* proceeds at the vendor default rather than forwarding a level another
|
|
54
|
+
* version's snapshot advertises to a binary that may reject it.
|
|
55
|
+
*/
|
|
56
|
+
export declare function claudeAdvertisedEffortsForRun(efforts: {
|
|
57
|
+
levels: readonly EffortHint[];
|
|
58
|
+
live: boolean;
|
|
59
|
+
}, installedVersion: string | null): readonly EffortHint[];
|
|
60
|
+
/**
|
|
61
|
+
* The RUN's whole INV-105 effort seam in one place: probe the installed
|
|
62
|
+
* binary's ladder, version-gate snapshot-fallback trust
|
|
63
|
+
* (`claudeAdvertisedEffortsForRun`), and derive the DROP/CLAMP disclosure on
|
|
64
|
+
* the SAME advertised list the arg builder will resolve against — so the flag
|
|
65
|
+
* sent and the disclosure emitted can never disagree. The `--version` spawn
|
|
66
|
+
* happens only when it can matter (fallback ladder AND an effort actually
|
|
67
|
+
* requested); a live parse or a hint-less run never pays for it.
|
|
68
|
+
*/
|
|
69
|
+
export declare function claudeRunEffortResolution(spec: Pick<HarnessRunSpec, "session_id" | "effort_hint">, deps: {
|
|
70
|
+
probeEffortLevels: typeof probeClaudeEffortLevels;
|
|
71
|
+
detectVersion: (abortSignal?: AbortSignal) => Promise<string | null>;
|
|
72
|
+
}, abortSignal?: AbortSignal): Promise<{
|
|
73
|
+
advertised: readonly EffortHint[];
|
|
74
|
+
disclosure: HarnessEvent | null;
|
|
75
|
+
}>;
|
|
76
|
+
/**
|
|
77
|
+
* Pull the advertised levels out of `claude --help` text, or null when the
|
|
78
|
+
* `--effort` line is absent or documents no values.
|
|
79
|
+
*
|
|
80
|
+
* Pure and separately testable: the spawn lives in the adapter's runtime deps so
|
|
81
|
+
* a test can feed recorded help text for any CLI version.
|
|
82
|
+
*/
|
|
83
|
+
export declare function parseClaudeEffortHelp(help: string): EffortHint[] | null;
|
|
84
|
+
type ClaudeHelpProbe = {
|
|
85
|
+
ok: true;
|
|
86
|
+
help: string;
|
|
87
|
+
code: number | null;
|
|
88
|
+
} | {
|
|
89
|
+
ok: false;
|
|
90
|
+
error: string;
|
|
91
|
+
};
|
|
92
|
+
/**
|
|
93
|
+
* The shared capture, with the caller's cancellation bounding only the CALLER'S
|
|
94
|
+
* OWN wait. An abandoned caller reads a probe failure — its run is going away
|
|
95
|
+
* anyway, and the ladder falls back to the snapshot for that one run — while the
|
|
96
|
+
* capture keeps running for everybody else.
|
|
97
|
+
*/
|
|
98
|
+
export declare function probeClaudeHelp(abortSignal?: AbortSignal): Promise<ClaudeHelpProbe>;
|
|
99
|
+
/**
|
|
100
|
+
* The effort ladder the INSTALLED claude binary advertises, falling back to the
|
|
101
|
+
* recorded snapshot when `--help` cannot be read or no longer documents the
|
|
102
|
+
* values. A probe failure costs freshness, never the run.
|
|
103
|
+
*/
|
|
104
|
+
export declare function probeClaudeEffortLevels(abortSignal?: AbortSignal): Promise<{
|
|
105
|
+
levels: readonly EffortHint[];
|
|
106
|
+
live: boolean;
|
|
107
|
+
}>;
|
|
108
|
+
/**
|
|
109
|
+
* The INV-105 disclosure for an effort the RUN itself could not honor, or null
|
|
110
|
+
* when nothing was dropped. Preflight validates against the manifest ladder,
|
|
111
|
+
* but the arg builder resolves against what the INSTALLED binary advertises at
|
|
112
|
+
* run time (an older CLI's `--help` can be narrower than the discovered
|
|
113
|
+
* manifest), and its normalizer answers "send no flag" — which without this
|
|
114
|
+
* event was a silent vendor-default run. The payload rides the same
|
|
115
|
+
* `ignored_settings` channel governance uses (QA-070 timeline warning).
|
|
116
|
+
*/
|
|
117
|
+
export declare function claudeEffortIgnoredEvent(spec: Pick<HarnessRunSpec, "session_id" | "effort_hint">, advertised: readonly EffortHint[]): HarnessEvent | null;
|
|
118
|
+
/**
|
|
119
|
+
* The INV-105 disclosure for an effort the resolution CLAMPED, or null when the
|
|
120
|
+
* level rode through verbatim (or was dropped — `claudeEffortIgnoredEvent`'s
|
|
121
|
+
* shape; the two are mutually exclusive: a drop sends no flag, a clamp sends a
|
|
122
|
+
* different one). Mirrors the codex clamp seam so a moved level is disclosed
|
|
123
|
+
* the same way on both adapters, and takes the SAME (advertised, ladder)
|
|
124
|
+
* inputs the arg builder's normalizer takes so the disclosure can never
|
|
125
|
+
* disagree with the flag actually sent.
|
|
126
|
+
*
|
|
127
|
+
* Reachability today: the arg builder resolves with the installed binary's own
|
|
128
|
+
* list as both advertised set and rank ladder (`normalizeEffort`'s two-arg
|
|
129
|
+
* form), and against one's own ladder every miss is a DROP, never a clamp —
|
|
130
|
+
* so with current call sites this event only fires if a rank ladder broader
|
|
131
|
+
* than the binary's list is ever threaded through (the codex-shaped future,
|
|
132
|
+
* e.g. `ultra` ranking above a max-capped binary and clamping onto `max`).
|
|
133
|
+
* The seam exists precisely so that future cannot be silent.
|
|
134
|
+
*/
|
|
135
|
+
/**
|
|
136
|
+
* The one INV-105 seam the run yields: the DROP disclosure or the CLAMP
|
|
137
|
+
* disclosure, whichever applies (they are mutually exclusive by construction —
|
|
138
|
+
* a drop sends no flag, a clamp sends a different one), or null when the
|
|
139
|
+
* requested level rode through verbatim or nothing was requested.
|
|
140
|
+
*/
|
|
141
|
+
export declare function claudeEffortDisclosureEvent(spec: Pick<HarnessRunSpec, "session_id" | "effort_hint">, advertised: readonly EffortHint[]): HarnessEvent | null;
|
|
142
|
+
export declare function claudeEffortClampedEvent(spec: Pick<HarnessRunSpec, "session_id" | "effort_hint">, advertised: readonly EffortHint[], ladder?: readonly EffortHint[]): HarnessEvent | null;
|
|
143
|
+
export {};
|
|
144
|
+
//# sourceMappingURL=effort-probe.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"effort-probe.d.ts","sourceRoot":"","sources":["../src/effort-probe.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACtE,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAI/C,eAAO,MAAM,GAAG,QAA+C,CAAC;AAEhE;;;GAGG;AACH,eAAO,MAAM,sBAAsB,EAAE,SAAS,UAAU,EAMvD,CAAC;AAEF,qEAAqE;AACrE,eAAO,MAAM,uCAAuC,YAAY,CAAC;AAEjE;;;;;;;;;;;;GAYG;AACH,wBAAgB,+BAA+B,CAAC,gBAAgB,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAIxF;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,6BAA6B,CAC3C,OAAO,EAAE;IAAE,MAAM,EAAE,SAAS,UAAU,EAAE,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,EACzD,gBAAgB,EAAE,MAAM,GAAG,IAAI,GAC9B,SAAS,UAAU,EAAE,CAGvB;AAED;;;;;;;;GAQG;AACH,wBAAsB,yBAAyB,CAC7C,IAAI,EAAE,IAAI,CAAC,cAAc,EAAE,YAAY,GAAG,aAAa,CAAC,EACxD,IAAI,EAAE;IACJ,iBAAiB,EAAE,OAAO,uBAAuB,CAAC;IAClD,aAAa,EAAE,CAAC,WAAW,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CACtE,EACD,WAAW,CAAC,EAAE,WAAW,GACxB,OAAO,CAAC;IAAE,UAAU,EAAE,SAAS,UAAU,EAAE,CAAC;IAAC,UAAU,EAAE,YAAY,GAAG,IAAI,CAAA;CAAE,CAAC,CAOjF;AAUD;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,EAAE,GAAG,IAAI,CA2CvE;AAqCD,KAAK,eAAe,GAClB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAoEjF;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,WAAW,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,eAAe,CAAC,CAYnF;AAED;;;;GAIG;AACH,wBAAsB,uBAAuB,CAC3C,WAAW,CAAC,EAAE,WAAW,GACxB,OAAO,CAAC;IAAE,MAAM,EAAE,SAAS,UAAU,EAAE,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC,CAI3D;AAED;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,IAAI,CAAC,cAAc,EAAE,YAAY,GAAG,aAAa,CAAC,EACxD,UAAU,EAAE,SAAS,UAAU,EAAE,GAChC,YAAY,GAAG,IAAI,CAsBrB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH;;;;;GAKG;AACH,wBAAgB,2BAA2B,CACzC,IAAI,EAAE,IAAI,CAAC,cAAc,EAAE,YAAY,GAAG,aAAa,CAAC,EACxD,UAAU,EAAE,SAAS,UAAU,EAAE,GAChC,YAAY,GAAG,IAAI,CAErB;AAED,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,IAAI,CAAC,cAAc,EAAE,YAAY,GAAG,aAAa,CAAC,EACxD,UAAU,EAAE,SAAS,UAAU,EAAE,EACjC,MAAM,GAAE,SAAS,UAAU,EAAe,GACzC,YAAY,GAAG,IAAI,CAerB"}
|