@oneharness/sdk 0.11.4 → 0.12.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.
@@ -57,7 +57,7 @@ export type ControlVerb = "interrupt";
57
57
  * new variant is a report `schema_version` bump like any other enum value, since
58
58
  * a consumer matching exhaustively learns of it only from the version.
59
59
  */
60
- export type FallThroughReason = "not-installed" | "spawn-error" | "auth" | "quota" | "session-not-found" | "untrusted-directory" | "input-too-large" | "model-not-found" | "rate-limit";
60
+ export type FallThroughReason = "not-installed" | "spawn-error" | "auth" | "quota" | "session-not-found" | "untrusted-directory" | "input-too-large" | "model-mismatch" | "model-not-found" | "rate-limit";
61
61
  export type ToolCallStatus = "completed" | "failed" | "timeout" | "interrupted";
62
62
  /**
63
63
  * How a normalized tool interval was obtained.
@@ -74,7 +74,7 @@ export type TimingSource = "provider_measured" | "stdout_observed";
74
74
  * the report, history) one definition to share instead of scattered string
75
75
  * literals.
76
76
  */
77
- export type FailureKind = "auth" | "rate_limit" | "model_not_found" | "quota" | "session_not_found" | "tool_deferred" | "untrusted_directory" | "input_too_large";
77
+ export type FailureKind = "auth" | "rate_limit" | "model_not_found" | "quota" | "session_not_found" | "tool_deferred" | "untrusted_directory" | "input_too_large" | "model_mismatch";
78
78
  /**
79
79
  * How a harness emits its result, which decides how `text` is extracted.
80
80
  *
@@ -308,7 +308,8 @@ export interface FallbackReport {
308
308
  * The candidates fallen through because they could not run the task at all,
309
309
  * in priority order, each with why (`not-installed`, `spawn-error`, `auth`,
310
310
  * `quota`, `session-not-found`, `untrusted-directory`, `input-too-large`,
311
- * and — on a model fan-out — `model-not-found` / `rate-limit`; see
311
+ * `model-mismatch`, and — on a model fan-out — `model-not-found` /
312
+ * `rate-limit`; see
312
313
  * [`crate::domain::fallback::startup_failure_reason`]).
313
314
  */
314
315
  fell_through: FallThrough[];
@@ -323,13 +324,16 @@ export interface FallbackReport {
323
324
  * [`RunResult::work`] read [`RunWork::None`] on a failure no classifier
324
325
  * recognized.
325
326
  *
326
- * The chain still stops there, deliberately: re-running a task that may
327
- * genuinely have failed for free would burn the next identity's quota on
328
- * the same failure, which is worse than stopping (see
327
+ * The chain still stops there, deliberately — decided, not inherited:
328
+ * empty accounting is the absence of work evidence, not proof nothing was
329
+ * spent, so handing the candidate on could bill a task twice (the decision
330
+ * and its reasoning are stated once, at
329
331
  * [`crate::domain::fallback::startup_failure_reason`]). What this flag adds
330
332
  * is the *attribution* — without it a candidate that never got started reads
331
333
  * in the report exactly like one that tried the task and failed it, and the
332
- * remaining candidates look untried for a reason nobody can name.
334
+ * remaining candidates look untried for a reason nobody can name — and the
335
+ * failure summary carries the candidate's own words beside it, so the
336
+ * reader left holding that one line can act on the cause.
333
337
  *
334
338
  * `false` whenever `ran` is `null` (no candidate ran at all — every one is
335
339
  * in `fell_through`, each with its reason).
@@ -415,7 +419,8 @@ export interface RunResult {
415
419
  * Best-effort failure reason; `null` when unclassified. Distinct from
416
420
  * `status`, which records oneharness's relationship to the process. Two
417
421
  * families: coarse reasons for a non-zero run (`auth`, `rate_limit`,
418
- * `model_not_found`, `quota`, `session_not_found`), and `tool_deferred` — a run that exited
422
+ * `model_not_found`, `quota`, `session_not_found`, `untrusted_directory`,
423
+ * `input_too_large`, `model_mismatch`), and `tool_deferred` — a run that exited
419
424
  * *cleanly* but only deferred a builtin tool call instead of executing it
420
425
  * (Claude Code bridge/managed deployments), so it did no useful work. The
421
426
  * deferred case is the only `failure_kind` that can appear on a `status: ok`
@@ -445,6 +450,17 @@ export interface RunResult {
445
450
  * without parsing the argv.
446
451
  */
447
452
  model: string | null;
453
+ /**
454
+ * The model the harness **itself** reported the conversation would run
455
+ * under, read off its own protocol before any token was spent — for codex
456
+ * over `app-server`, `result.model` of the `thread/start` / `thread/resume`
457
+ * response. `null` on every path that reports none, which today is every
458
+ * path but codex's app-server. Never inferred and never copied from
459
+ * `model`: where both are set they are the requested model and the served
460
+ * one, and a difference between them is exactly the `model_mismatch`
461
+ * refusal, which this field then names the other half of.
462
+ */
463
+ observed_model: string | null;
448
464
  output_format: OutputFormat;
449
465
  /**
450
466
  * The prompt this result ran, set only on a **batch** run (one harness
@@ -6,7 +6,7 @@ export type HistoryLine = ({
6
6
  harness: string;
7
7
  harness_id?: string | null | undefined;
8
8
  run_id: string;
9
- schema_version: "1.2" | "1.3" | "1.4" | "1.5" | "1.6" | "1.7";
9
+ schema_version: "1.2" | "1.3" | "1.4" | "1.5" | "1.6" | "1.7" | "1.8";
10
10
  type: "event";
11
11
  variant?: string | null | undefined;
12
12
  [k: string]: unknown;
@@ -27,7 +27,7 @@ export type HistoryLine = ({
27
27
  [k: string]: unknown;
28
28
  } | ({
29
29
  error: string;
30
- schema_version?: "1.3" | "1.4" | "1.5" | "1.6" | "1.7" | undefined;
30
+ schema_version?: "1.3" | "1.4" | "1.5" | "1.6" | "1.7" | "1.8" | undefined;
31
31
  [k: string]: unknown;
32
32
  } & ({
33
33
  status?: "nonzero" | "timeout" | "cancelled" | "spawn-error" | "skipped" | undefined;
@@ -39,27 +39,40 @@ export type HistoryLine = ({
39
39
  work?: null | undefined;
40
40
  [k: string]: unknown;
41
41
  } | {
42
- schema_version?: "1.7" | undefined;
42
+ schema_version?: "1.7" | "1.8" | undefined;
43
43
  status?: "nonzero" | "timeout" | "cancelled" | undefined;
44
44
  work: "done" | "none";
45
45
  [k: string]: unknown;
46
+ }) & ({
47
+ observed_model?: null | undefined;
48
+ [k: string]: unknown;
49
+ } | {
50
+ observed_model: string;
51
+ schema_version?: "1.8" | undefined;
52
+ [k: string]: unknown;
46
53
  }) & ({
47
54
  status?: "ok" | "nonzero" | "timeout" | "spawn-error" | "skipped" | "planned" | undefined;
48
55
  [k: string]: unknown;
49
56
  } | {
50
- schema_version?: "1.4" | "1.5" | "1.6" | "1.7" | undefined;
57
+ schema_version?: "1.4" | "1.5" | "1.6" | "1.7" | "1.8" | undefined;
51
58
  [k: string]: unknown;
52
59
  }) & (({
53
- failure_kind?: "auth" | "rate_limit" | "model_not_found" | "quota" | "tool_deferred" | "untrusted_directory" | "input_too_large" | null;
60
+ failure_kind?: "auth" | "rate_limit" | "model_not_found" | "quota" | "tool_deferred" | "untrusted_directory" | "input_too_large" | "model_mismatch" | null;
61
+ [k: string]: unknown;
62
+ } | {
63
+ schema_version?: "1.5" | "1.6" | "1.7" | "1.8" | undefined;
64
+ [k: string]: unknown;
65
+ }) & ({
66
+ failure_kind?: "auth" | "rate_limit" | "model_not_found" | "quota" | "session_not_found" | "tool_deferred" | "model_mismatch" | null;
54
67
  [k: string]: unknown;
55
68
  } | {
56
- schema_version?: "1.5" | "1.6" | "1.7" | undefined;
69
+ schema_version?: "1.6" | "1.7" | "1.8" | undefined;
57
70
  [k: string]: unknown;
58
71
  }) & ({
59
- failure_kind?: "auth" | "rate_limit" | "model_not_found" | "quota" | "session_not_found" | "tool_deferred" | null;
72
+ failure_kind?: "auth" | "rate_limit" | "model_not_found" | "quota" | "session_not_found" | "tool_deferred" | "untrusted_directory" | "input_too_large" | null;
60
73
  [k: string]: unknown;
61
74
  } | {
62
- schema_version?: "1.6" | "1.7" | undefined;
75
+ schema_version?: "1.8" | undefined;
63
76
  [k: string]: unknown;
64
77
  })) & ({
65
78
  duration_ms: number;
@@ -78,11 +91,16 @@ export type HistoryLine = ({
78
91
  model: string | null;
79
92
  model_ms: number;
80
93
  name: string;
94
+ /**
95
+ * The model the harness itself reported it would run under (see
96
+ * [`HistoryRecord::observed_model`]). Omitted on the wire when absent.
97
+ */
98
+ observed_model?: string | null | undefined;
81
99
  observed_tool_ms?: never | undefined;
82
100
  permission_mode: PermissionMode;
83
101
  project: string;
84
102
  prompt: string;
85
- schema_version: "1.0" | "1.1" | "1.2" | "1.3" | "1.4" | "1.5" | "1.6" | "1.7";
103
+ schema_version: "1.0" | "1.1" | "1.2" | "1.3" | "1.4" | "1.5" | "1.6" | "1.7" | "1.8";
86
104
  session: string;
87
105
  session_id: string | null;
88
106
  started_at: string;
@@ -118,11 +136,16 @@ export type HistoryLine = ({
118
136
  model: string | null;
119
137
  model_ms: number;
120
138
  name: string;
139
+ /**
140
+ * The model the harness itself reported it would run under (see
141
+ * [`HistoryRecord::observed_model`]). Omitted on the wire when absent.
142
+ */
143
+ observed_model?: string | null | undefined;
121
144
  observed_tool_ms?: never | undefined;
122
145
  permission_mode: PermissionMode;
123
146
  project: string;
124
147
  prompt: string;
125
- schema_version: "1.0" | "1.1" | "1.2" | "1.3" | "1.4" | "1.5" | "1.6" | "1.7";
148
+ schema_version: "1.0" | "1.1" | "1.2" | "1.3" | "1.4" | "1.5" | "1.6" | "1.7" | "1.8";
126
149
  session: string;
127
150
  session_id: string | null;
128
151
  started_at: string;
@@ -158,11 +181,16 @@ export type HistoryLine = ({
158
181
  model: string | null;
159
182
  model_ms?: never | undefined;
160
183
  name: string;
184
+ /**
185
+ * The model the harness itself reported it would run under (see
186
+ * [`HistoryRecord::observed_model`]). Omitted on the wire when absent.
187
+ */
188
+ observed_model?: string | null | undefined;
161
189
  observed_tool_ms: number;
162
190
  permission_mode: PermissionMode;
163
191
  project: string;
164
192
  prompt: string;
165
- schema_version: "1.2" | "1.3" | "1.4" | "1.5" | "1.6" | "1.7";
193
+ schema_version: "1.2" | "1.3" | "1.4" | "1.5" | "1.6" | "1.7" | "1.8";
166
194
  session: string;
167
195
  session_id: string | null;
168
196
  started_at?: never | undefined;
@@ -198,11 +226,16 @@ export type HistoryLine = ({
198
226
  model: string | null;
199
227
  model_ms?: never | undefined;
200
228
  name: string;
229
+ /**
230
+ * The model the harness itself reported it would run under (see
231
+ * [`HistoryRecord::observed_model`]). Omitted on the wire when absent.
232
+ */
233
+ observed_model?: string | null | undefined;
201
234
  observed_tool_ms?: never | undefined;
202
235
  permission_mode: PermissionMode;
203
236
  project: string;
204
237
  prompt: string;
205
- schema_version: "1.0" | "1.1" | "1.2" | "1.3" | "1.4" | "1.5" | "1.6" | "1.7";
238
+ schema_version: "1.0" | "1.1" | "1.2" | "1.3" | "1.4" | "1.5" | "1.6" | "1.7" | "1.8";
206
239
  session: string;
207
240
  session_id: string | null;
208
241
  started_at?: never | undefined;
@@ -238,11 +271,16 @@ export type HistoryLine = ({
238
271
  model: string | null;
239
272
  model_ms?: never | undefined;
240
273
  name: string;
274
+ /**
275
+ * The model the harness itself reported it would run under (see
276
+ * [`HistoryRecord::observed_model`]). Omitted on the wire when absent.
277
+ */
278
+ observed_model?: string | null | undefined;
241
279
  observed_tool_ms?: never | undefined;
242
280
  permission_mode: PermissionMode;
243
281
  project: string;
244
282
  prompt: string;
245
- schema_version: "1.3" | "1.4" | "1.5" | "1.6" | "1.7";
283
+ schema_version: "1.3" | "1.4" | "1.5" | "1.6" | "1.7" | "1.8";
246
284
  session: string;
247
285
  session_id: string | null;
248
286
  started_at: string;
@@ -278,11 +316,16 @@ export type HistoryLine = ({
278
316
  model: string | null;
279
317
  model_ms?: never | undefined;
280
318
  name: string;
319
+ /**
320
+ * The model the harness itself reported it would run under (see
321
+ * [`HistoryRecord::observed_model`]). Omitted on the wire when absent.
322
+ */
323
+ observed_model?: string | null | undefined;
281
324
  observed_tool_ms?: never | undefined;
282
325
  permission_mode: PermissionMode;
283
326
  project: string;
284
327
  prompt: string;
285
- schema_version: "1.0" | "1.1" | "1.2" | "1.3" | "1.4" | "1.5" | "1.6" | "1.7";
328
+ schema_version: "1.0" | "1.1" | "1.2" | "1.3" | "1.4" | "1.5" | "1.6" | "1.7" | "1.8";
286
329
  session: string;
287
330
  session_id: string | null;
288
331
  started_at?: never | undefined;
@@ -318,7 +361,7 @@ export type TimingSource = "provider_measured" | "stdout_observed";
318
361
  * the report, history) one definition to share instead of scattered string
319
362
  * literals.
320
363
  */
321
- export type FailureKind = "auth" | "rate_limit" | "model_not_found" | "quota" | "session_not_found" | "tool_deferred" | "untrusted_directory" | "input_too_large";
364
+ export type FailureKind = "auth" | "rate_limit" | "model_not_found" | "quota" | "session_not_found" | "tool_deferred" | "untrusted_directory" | "input_too_large" | "model_mismatch";
322
365
  /**
323
366
  * The unified approval mode, from least to most autonomy. A harness may not
324
367
  * support every value (see [`crate::domain::harness::HarnessSpec::mode`]); the