@zhivex-ai/harness 1.4.0-rc.6 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/README.md +124 -71
  3. package/SECURITY.md +1 -1
  4. package/SUPPORT.md +2 -2
  5. package/contracts/engine-api.json +55 -0
  6. package/contracts/stable-api-signatures.json +33 -33
  7. package/dist/acp-cli.js +18 -15
  8. package/dist/cli/arguments.d.ts +3 -0
  9. package/dist/cli/console/console-budget.d.ts +8 -2
  10. package/dist/{cli-s1rs15vv.js → cli-2h37qyvg.js} +34 -15
  11. package/dist/{cli-entry-d5788aay.js → cli-entry-20w6nh0k.js} +359 -21
  12. package/dist/{cli-entry-9c2k0zwz.js → cli-entry-4ngptr62.js} +2902 -1482
  13. package/dist/{cli-entry-4k1cf0m3.js → cli-entry-w0hterjs.js} +8 -5
  14. package/dist/cli.js +2 -2
  15. package/dist/client/json-contracts.d.ts +95 -2
  16. package/dist/client/local-service.d.ts +2 -2
  17. package/dist/client/protocol.d.ts +3 -0
  18. package/dist/client/stream.d.ts +2 -1
  19. package/dist/compat/code-support.d.ts +6 -0
  20. package/dist/compat/code-support.js +29 -6
  21. package/dist/{config-c002f06f.js → config-j9624t6t.js} +1 -1
  22. package/dist/{config-j3jga5wh.js → config-qt69hkqj.js} +4 -2
  23. package/dist/engine/acp.js +14 -12
  24. package/dist/engine/client.js +11 -10
  25. package/dist/engine/desktop-providers-v1.js +2 -1
  26. package/dist/engine/desktop-state-v1.js +9 -9
  27. package/dist/engine/index.js +48 -46
  28. package/dist/engine/mcp-stdio-v1.js +7 -6
  29. package/dist/engine/protocol.js +30 -2
  30. package/dist/engine/service.js +12 -11
  31. package/dist/hostile-repository-demo.js +4773 -3027
  32. package/dist/{index-49ys3s4q.js → index-5jhgatga.js} +35 -16
  33. package/dist/{index-wq2tax80.js → index-61gthdz6.js} +1 -1
  34. package/dist/index-6dft2vev.js +343 -0
  35. package/dist/{index-gq9xagx2.js → index-8zjmnyw5.js} +25 -138
  36. package/dist/index-937cb7y8.js +705 -0
  37. package/dist/index-bpc596v3.js +154 -0
  38. package/dist/index-fm84men1.js +239 -0
  39. package/dist/{index-e6r04a18.js → index-m34q25jj.js} +1127 -170
  40. package/dist/index-m49jx72n.js +220 -0
  41. package/dist/{index-dj5z774k.js → index-m82cfspw.js} +35 -16
  42. package/dist/{index-qfpz5y2v.js → index-nmjdwd4p.js} +8 -2
  43. package/dist/{index-0g939pfs.js → index-pdmevfxv.js} +10 -7
  44. package/dist/{index-4j1h4j8c.js → index-pp474137.js} +1598 -973
  45. package/dist/{index-2tgb2b4e.js → index-rkbf7dqg.js} +3 -5
  46. package/dist/index-s2k2edts.js +3778 -0
  47. package/dist/{index-z6br6qdn.js → index-tfzta544.js} +28 -11
  48. package/dist/index.js +44 -42
  49. package/dist/persistence/operations.d.ts +3 -0
  50. package/dist/providers/vertex-auth.d.ts +5 -1
  51. package/dist/runtime/config.d.ts +8 -0
  52. package/dist/runtime/context-runtime.d.ts +1 -0
  53. package/dist/runtime/error-diagnostics.d.ts +8 -0
  54. package/dist/runtime/errors.d.ts +10 -0
  55. package/dist/runtime/harness.d.ts +9 -0
  56. package/dist/runtime/policy-inspection.d.ts +1 -0
  57. package/dist/runtime/provider-transient.d.ts +33 -0
  58. package/dist/runtime/runtime-diagnostics.d.ts +3 -0
  59. package/dist/runtime/runtime-policy.d.ts +8 -10
  60. package/dist/runtime/task-acceptance-host.d.ts +1 -1
  61. package/dist/runtime/task-budget-host.d.ts +217 -0
  62. package/dist/runtime/task-budget.d.ts +147 -0
  63. package/dist/runtime/task-continuity.d.ts +434 -0
  64. package/dist/runtime/task-telemetry.d.ts +63 -0
  65. package/dist/runtime/task-transport.d.ts +3 -0
  66. package/dist/runtime/task-usage-context.d.ts +13 -0
  67. package/dist/runtime/time-to-safe-fix.d.ts +8 -0
  68. package/dist/runtime/usage-ledger.d.ts +17 -0
  69. package/dist/service-cli.js +12 -11
  70. package/dist/{service-client-cli-b52c67hx.js → service-client-cli-fn54ev6w.js} +18 -7
  71. package/dist/verify-historical-migrations.js +2426 -652
  72. package/dist/zhx.js +2 -2
  73. package/docs/CLI.md +38 -8
  74. package/docs/CLIENT_PROTOCOL.md +9 -1
  75. package/docs/CODE_RELEASE.md +118 -1
  76. package/docs/DURABLE_OPERATIONS.md +1 -1
  77. package/docs/EXTENSIBILITY.md +1 -1
  78. package/docs/FIRST_USE.md +6 -6
  79. package/docs/MINIMUM_OFFLINE_EVALS.md +31 -0
  80. package/docs/MINIMUM_TASK_AUTHORITY.md +395 -0
  81. package/docs/PROJECT_MEMORY.md +1 -1
  82. package/docs/README.md +2 -0
  83. package/docs/STABILITY.md +1 -1
  84. package/docs/WEB_LIMITS.md +117 -0
  85. package/evaluations/representative-assembly-matrix.json +28 -1
  86. package/examples/README.md +5 -5
  87. package/package.json +8 -5
  88. package/dist/index-8705zxpr.js +0 -145
  89. package/dist/index-a1q355va.js +0 -600
  90. package/dist/index-r0tdj04h.js +0 -976
  91. package/dist/index-rd0s3gqj.js +0 -1669
  92. package/dist/index-vtqfjnab.js +0 -1626
@@ -87,6 +87,8 @@ function providerDiagnostic(body, status) {
87
87
  reason = "permission";
88
88
  else if (["rate_limit_exceeded", "rate_limit_error", "RESOURCE_EXHAUSTED"].includes(code))
89
89
  reason = "rate_limit";
90
+ else if (["UNAVAILABLE", "DEADLINE_EXCEEDED", "ABORTED", "INTERNAL"].includes(code))
91
+ reason = "server_error";
90
92
  else if (["model_not_found", "model_not_available", "NOT_FOUND"].includes(code))
91
93
  reason = "model_unavailable";
92
94
  else if (["invalid_request_error", "INVALID_ARGUMENT"].includes(code) || status === 400 || status === 422)
@@ -97,6 +99,201 @@ function providerDiagnostic(body, status) {
97
99
  }
98
100
  }
99
101
 
102
+ // src/runtime/provider-transient.ts
103
+ var PROVIDER_STATUS_CATEGORIES = [
104
+ "ABORTED",
105
+ "RESOURCE_EXHAUSTED",
106
+ "UNAVAILABLE",
107
+ "DEADLINE_EXCEEDED",
108
+ "INTERNAL",
109
+ "STREAM_RESET"
110
+ ];
111
+ var VERTEX_TRANSIENT_ATTEMPTS = 3;
112
+ var TRANSIENT_HTTP = {
113
+ 408: "DEADLINE_EXCEEDED",
114
+ 409: "ABORTED",
115
+ 425: "UNAVAILABLE",
116
+ 429: "RESOURCE_EXHAUSTED",
117
+ 500: "INTERNAL",
118
+ 502: "UNAVAILABLE",
119
+ 503: "UNAVAILABLE",
120
+ 504: "DEADLINE_EXCEEDED"
121
+ };
122
+ var TRANSIENT_GRPC = {
123
+ 4: "DEADLINE_EXCEEDED",
124
+ 8: "RESOURCE_EXHAUSTED",
125
+ 10: "ABORTED",
126
+ 13: "INTERNAL",
127
+ 14: "UNAVAILABLE"
128
+ };
129
+ var CATEGORY_HTTP = {
130
+ ABORTED: 409,
131
+ RESOURCE_EXHAUSTED: 429,
132
+ UNAVAILABLE: 503,
133
+ DEADLINE_EXCEEDED: 504,
134
+ INTERNAL: 500,
135
+ STREAM_RESET: undefined
136
+ };
137
+ var SYMBOLIC = new Set(["ABORTED", "RESOURCE_EXHAUSTED", "UNAVAILABLE", "DEADLINE_EXCEEDED", "INTERNAL"]);
138
+ var STREAM_RESET_CODES = new Set(["ECONNRESET", "ECONNABORTED", "EPIPE", "ETIMEDOUT", "UND_ERR_SOCKET", "ERR_STREAM_PREMATURE_CLOSE"]);
139
+ var HTTP_IN_MESSAGE = /(?:^|[^\d])(408|409|425|429|500|502|503|504)(?=$|[^\d])/;
140
+ var STREAM_RESET_MESSAGE = /stream reset|RST_STREAM|ECONNRESET|socket hang up|ERR_STREAM_PREMATURE_CLOSE|UND_ERR_SOCKET/i;
141
+ var isProviderStatus = (value) => typeof value === "string" && PROVIDER_STATUS_CATEGORIES.includes(value);
142
+ var httpStatusValue = (value) => typeof value === "number" && Number.isInteger(value) && value >= 100 && value <= 599 ? value : undefined;
143
+ var definitiveClientStatus = (status) => status !== undefined && status >= 400 && status < 500 && TRANSIENT_HTTP[status] === undefined;
144
+ function readProviderFailureRecord(record, depth = 0) {
145
+ let retryable = false;
146
+ let clientError = false;
147
+ let httpStatus;
148
+ let providerStatus;
149
+ const noteHttp = (status) => {
150
+ if (status === undefined)
151
+ return;
152
+ httpStatus ??= status;
153
+ const category = TRANSIENT_HTTP[status];
154
+ if (category) {
155
+ retryable = true;
156
+ providerStatus ??= category;
157
+ } else if (status >= 400 && status < 500)
158
+ clientError = true;
159
+ };
160
+ const noteCategory = (category) => {
161
+ if (!category || clientError)
162
+ return;
163
+ retryable = true;
164
+ providerStatus ??= category;
165
+ if (httpStatus === undefined)
166
+ httpStatus = CATEGORY_HTTP[category];
167
+ };
168
+ const absorb = (value) => {
169
+ if (depth >= 2 || !value || typeof value !== "object" || value === record)
170
+ return;
171
+ const signals = readProviderFailureRecord(value, depth + 1);
172
+ noteHttp(signals.httpStatus);
173
+ noteCategory(signals.providerStatus);
174
+ };
175
+ noteHttp(httpStatusValue(record.status) ?? httpStatusValue(record.statusCode) ?? httpStatusValue(record.httpStatusCode));
176
+ if (typeof record.status === "string" && /^\d{3}$/.test(record.status))
177
+ noteHttp(Number(record.status));
178
+ if (typeof record.code === "number" && record.code >= 100 && record.code <= 599)
179
+ noteHttp(record.code);
180
+ if (typeof record.code === "number" && record.code >= 0 && record.code <= 16)
181
+ noteCategory(TRANSIENT_GRPC[record.code]);
182
+ if (typeof record.code === "string") {
183
+ if (STREAM_RESET_CODES.has(record.code))
184
+ noteCategory("STREAM_RESET");
185
+ else if (SYMBOLIC.has(record.code))
186
+ noteCategory(record.code);
187
+ }
188
+ if (typeof record.status === "string" && SYMBOLIC.has(record.status))
189
+ noteCategory(record.status);
190
+ if (isProviderStatus(record.providerStatus))
191
+ noteCategory(record.providerStatus);
192
+ if (record.diagnosticCode === "VERTEX_STREAM_TOOL_TRUNCATED" || record.reason === "stream_truncated")
193
+ noteCategory("STREAM_RESET");
194
+ if (record.code === "PROVIDER_UNAVAILABLE" && record.retryable === true)
195
+ retryable = true;
196
+ const body = record.responseBody ?? record.body;
197
+ if (!clientError) {
198
+ if (typeof body === "string")
199
+ noteCategory(categoryFromBody(body));
200
+ else
201
+ absorb(body);
202
+ absorb(record.error);
203
+ }
204
+ if (!retryable && !clientError && typeof record.message === "string") {
205
+ const match = record.message.match(HTTP_IN_MESSAGE);
206
+ if (match?.[1])
207
+ noteHttp(Number(match[1]));
208
+ else if (STREAM_RESET_MESSAGE.test(record.message))
209
+ noteCategory("STREAM_RESET");
210
+ }
211
+ if (httpStatus !== undefined && definitiveClientStatus(httpStatus))
212
+ return { retryable: false, httpStatus };
213
+ return { retryable, ...httpStatus !== undefined ? { httpStatus } : {}, ...providerStatus ? { providerStatus } : {} };
214
+ }
215
+ function categoryFromBody(body) {
216
+ if (Buffer.byteLength(body) > 8192)
217
+ return;
218
+ try {
219
+ const parsed = JSON.parse(body);
220
+ if (!parsed || typeof parsed !== "object")
221
+ return;
222
+ const detail = parsed.error;
223
+ const source = detail && typeof detail === "object" ? detail : parsed;
224
+ return readProviderFailureRecord(source).providerStatus;
225
+ } catch {
226
+ return;
227
+ }
228
+ }
229
+ function classifyProviderFailure(error) {
230
+ if (error && typeof error === "object") {
231
+ const top = readProviderFailureRecord(error);
232
+ if (top.httpStatus !== undefined && definitiveClientStatus(top.httpStatus))
233
+ return { retryable: false, httpStatus: top.httpStatus };
234
+ }
235
+ const seen = new Set;
236
+ let retryable = false;
237
+ let httpStatus;
238
+ let providerStatus;
239
+ const visit = (current, depth) => {
240
+ if (!current || typeof current !== "object" || depth > 5 || seen.has(current))
241
+ return;
242
+ seen.add(current);
243
+ const record = current;
244
+ const signals = readProviderFailureRecord(record);
245
+ httpStatus ??= signals.httpStatus;
246
+ providerStatus ??= signals.providerStatus;
247
+ if (httpStatus !== undefined && providerStatus === undefined)
248
+ providerStatus = TRANSIENT_HTTP[httpStatus];
249
+ if (record.retryable === false)
250
+ return;
251
+ if (signals.retryable)
252
+ retryable = true;
253
+ visit(record.cause, depth + 1);
254
+ if (record.error && typeof record.error === "object")
255
+ visit(record.error, depth + 1);
256
+ if (record.details && typeof record.details === "object")
257
+ visit(record.details, depth + 1);
258
+ if (Array.isArray(record.chain))
259
+ for (const entry of record.chain)
260
+ visit(entry, depth + 1);
261
+ };
262
+ visit(error, 0);
263
+ if (retryable && httpStatus === undefined && providerStatus)
264
+ httpStatus = CATEGORY_HTTP[providerStatus];
265
+ return { retryable, ...httpStatus !== undefined ? { httpStatus } : {}, ...providerStatus ? { providerStatus } : {} };
266
+ }
267
+ function isRetryableProviderFailure(error) {
268
+ return classifyProviderFailure(error).retryable;
269
+ }
270
+ function transientBackoffMs(attempt, baseMs = 250) {
271
+ const exponential = Math.min(baseMs * 2 ** Math.max(0, attempt), 1e4);
272
+ return exponential + Math.floor(Math.random() * exponential);
273
+ }
274
+ var thoughtOnlyText = (text) => {
275
+ try {
276
+ const parsed = JSON.parse(text);
277
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
278
+ return false;
279
+ const record = parsed;
280
+ return record.thought === true && Object.keys(record).every((key) => key === "thought" || key === "thoughtSignature");
281
+ } catch {
282
+ return false;
283
+ }
284
+ };
285
+ function isEmptyModelTurn(result) {
286
+ if (result.finishReason === "content-filter" || result.finishReason === "error")
287
+ return false;
288
+ if ((result.images?.length ?? 0) > 0 || (result.audio?.length ?? 0) > 0)
289
+ return false;
290
+ const parts = result.messages?.flatMap((message) => message.parts ?? []) ?? [];
291
+ if (parts.some((part) => part.type === "tool-call" || part.type === "image" || part.type === "audio"))
292
+ return false;
293
+ const texts = [result.text ?? "", ...parts.filter((part) => part.type === "text").map((part) => part.text ?? "")];
294
+ return texts.every((text) => text.trim().length === 0 || thoughtOnlyText(text.trim()));
295
+ }
296
+
100
297
  // src/providers/vertex-auth.ts
101
298
  var CLOUD_PLATFORM_SCOPE = "https://www.googleapis.com/auth/cloud-platform";
102
299
  function vertexRoute(env) {
@@ -146,13 +343,31 @@ class VertexAuthenticationError extends Error {
146
343
  this.name = "VertexAuthenticationError";
147
344
  }
148
345
  }
149
- function createVertexModel(model, env, createAuth) {
346
+ function createVertexModel(model, env, createAuth, retry) {
150
347
  const route = vertexRoute(env);
151
348
  const adapter = createVertex({
152
349
  ...route,
153
350
  getAccessToken: vertexTokenSource(env, route, createAuth)
154
351
  })(model);
155
- return wrapLanguageModel2(adapter, [{
352
+ const attempts = retry?.attempts ?? VERTEX_TRANSIENT_ATTEMPTS;
353
+ const delayFor = (input) => retry?.delayMs ?? ((attempt) => input.retryBackoffMs === 0 ? 0 : transientBackoffMs(attempt, input.retryBackoffMs ?? 250));
354
+ const generate = async (input) => withVertexAttempts(input.abortSignal, vertexAttemptBudget(input, attempts), delayFor(input), async () => {
355
+ try {
356
+ return await adapter.generate({ ...input, maxRetries: 0 });
357
+ } catch (error) {
358
+ throw safeVertexError(error);
359
+ }
360
+ }, (result) => !isEmptyModelTurn(result));
361
+ const innerStream = adapter.stream?.bind(adapter);
362
+ const retrying = innerStream ? {
363
+ ...adapter,
364
+ generate,
365
+ async stream(input) {
366
+ const events = await withVertexAttempts(input.abortSignal, vertexAttemptBudget(input, attempts), delayFor(input), () => collectVertexStream(() => innerStream({ ...input, maxRetries: 0 })), (events2) => !isEmptyVertexStream(events2));
367
+ return replayVertexStream(events);
368
+ }
369
+ } : { ...adapter, generate };
370
+ return wrapLanguageModel2(retrying, [{
156
371
  name: "harness-vertex-sanitized-errors",
157
372
  async wrapGenerate(_context, next) {
158
373
  try {
@@ -178,19 +393,109 @@ function createVertexModel(model, env, createAuth) {
178
393
  }
179
394
  }]);
180
395
  }
396
+ async function collectVertexStream(next) {
397
+ let stream;
398
+ try {
399
+ stream = await next();
400
+ } catch (error) {
401
+ throw safeVertexError(error);
402
+ }
403
+ const events = [];
404
+ try {
405
+ for await (const event of stream) {
406
+ if (event.type === "error")
407
+ throw safeVertexError(event.error);
408
+ events.push(event);
409
+ }
410
+ } catch (error) {
411
+ throw error instanceof Error && error.message.startsWith("Vertex request failed.") ? error : safeVertexError(error);
412
+ }
413
+ return events;
414
+ }
415
+ function isEmptyVertexStream(events) {
416
+ let text = "";
417
+ let finishReason;
418
+ let tools = false;
419
+ let media = false;
420
+ for (const event of events) {
421
+ if (event.type === "text-delta")
422
+ text += event.textDelta;
423
+ else if (event.type === "tool-call" || event.type === "tool-approval-request")
424
+ tools = true;
425
+ else if (event.type === "image-generation")
426
+ media = true;
427
+ else if (event.type === "finish")
428
+ finishReason = event.finishReason;
429
+ }
430
+ return isEmptyModelTurn({
431
+ text,
432
+ finishReason,
433
+ ...tools ? { messages: [{ parts: [{ type: "tool-call" }] }] } : {},
434
+ ...media ? { images: [{}] } : {}
435
+ });
436
+ }
437
+ function replayVertexStream(events) {
438
+ return async function* () {
439
+ yield* events;
440
+ }();
441
+ }
442
+ async function withVertexAttempts(abortSignal, attempts, delayMs, run, accept) {
443
+ let last;
444
+ for (let attempt = 0;attempt < attempts; attempt += 1) {
445
+ if (abortSignal?.aborted)
446
+ throw new DOMException("Vertex request cancelled.", "AbortError");
447
+ try {
448
+ const value = await run();
449
+ if (accept(value) || attempt === attempts - 1)
450
+ return value;
451
+ last = value;
452
+ } catch (error) {
453
+ const safe = error instanceof Error && (error.name === "AbortError" || error.message.startsWith("Vertex request failed.")) ? error : safeVertexError(error);
454
+ if (safe.name === "AbortError" || abortSignal?.aborted || attempt === attempts - 1 || !isRetryableProviderFailure(safe))
455
+ throw safe;
456
+ }
457
+ await sleep(delayMs(attempt));
458
+ }
459
+ return last;
460
+ }
461
+ var sleep = (ms) => ms > 0 ? new Promise((resolve) => setTimeout(resolve, ms)) : Promise.resolve();
462
+ function vertexAttemptBudget(input, fallback) {
463
+ const requested = [
464
+ typeof input.maxProviderRequests === "number" ? input.maxProviderRequests : undefined,
465
+ typeof input.maxRetries === "number" ? input.maxRetries + 1 : undefined
466
+ ].filter((value) => value !== undefined);
467
+ if (requested.length === 0)
468
+ return Math.max(1, fallback);
469
+ return Math.max(1, Math.min(...requested));
470
+ }
181
471
  function safeVertexError(error) {
182
472
  if (error instanceof VertexAuthenticationError)
183
473
  return error;
184
474
  const record = error && typeof error === "object" ? error : {};
185
475
  if (record.name === "AbortError")
186
476
  return new DOMException("Vertex request cancelled.", "AbortError");
187
- const status = typeof record.status === "number" && Number.isInteger(record.status) && record.status >= 100 && record.status <= 599 ? record.status : undefined;
477
+ const failure = classifyProviderFailure(error);
478
+ const body = providerBody(record.responseBody) ?? providerBody(record.body);
479
+ const preserved = providerDiagnosticSchema.safeParse(record.provider);
480
+ const provider = body !== undefined ? providerDiagnostic(body, failure.httpStatus) : preserved.success ? preserved.data : providerDiagnostic(undefined, failure.httpStatus);
188
481
  return Object.assign(new Error("Vertex request failed. Check the sanitized provider diagnosis."), {
189
- ...status ? { status } : {},
190
- provider: providerDiagnostic(record.responseBody ?? record.body, status),
191
- retryable: record.retryable === true
482
+ ...failure.httpStatus !== undefined ? { status: failure.httpStatus } : {},
483
+ ...failure.providerStatus ? { providerStatus: failure.providerStatus } : {},
484
+ provider,
485
+ retryable: failure.retryable
192
486
  });
193
487
  }
488
+ function providerBody(value) {
489
+ if (typeof value === "string")
490
+ return value;
491
+ if (!value || typeof value !== "object")
492
+ return;
493
+ try {
494
+ return JSON.stringify(value).slice(0, 8192);
495
+ } catch {
496
+ return;
497
+ }
498
+ }
194
499
 
195
500
  // src/providers/qwen-hosted-policy.ts
196
501
  import { wrapLanguageModel as wrapLanguageModel3 } from "@zhivex-ai/core";
@@ -1845,6 +2150,17 @@ function withReasoningEffort(model, value) {
1845
2150
  }]);
1846
2151
  }
1847
2152
 
2153
+ // src/runtime/task-transport.ts
2154
+ var provenance = Symbol("harness-vetted-task-transport");
2155
+ var capability = Object.freeze({ version: 1 });
2156
+ function markTaskTransportModel(model) {
2157
+ Object.defineProperty(model, provenance, { value: capability, enumerable: true });
2158
+ return model;
2159
+ }
2160
+ function isTaskTransportModel(model) {
2161
+ return Reflect.get(model, provenance) === capability;
2162
+ }
2163
+
1848
2164
  // src/runtime/config.ts
1849
2165
  import { createHash as createHash2 } from "node:crypto";
1850
2166
  import { realpathSync } from "node:fs";
@@ -1861,6 +2177,18 @@ var HARNESS_ERROR_CODES = [
1861
2177
  "EXECUTION_FAILED"
1862
2178
  ];
1863
2179
  var HARNESS_ERROR_SCHEMA_VERSION = 1;
2180
+ var providerStreamDiagnostic = (error) => {
2181
+ const seen = new Set;
2182
+ for (let depth = 0;depth < 5 && error && typeof error === "object" && !seen.has(error); depth++) {
2183
+ seen.add(error);
2184
+ const value = error;
2185
+ if (value.provider === "qwen" && value.diagnosticCode === "QWEN_SSE_EVENT_INVALID" && (value.name === "QwenStreamEventError" || value.category === "provider-stream") && (value.transport === "chat" || value.transport === "responses") && (value.reason === "invalid_json" || value.reason === "invalid_event") && value.retryable === false) {
2186
+ return { provider: "qwen", transport: value.transport, diagnosticCode: "QWEN_SSE_EVENT_INVALID", reason: value.reason, retryable: false };
2187
+ }
2188
+ error = value.cause;
2189
+ }
2190
+ return;
2191
+ };
1864
2192
 
1865
2193
  class HarnessError extends Error {
1866
2194
  code;
@@ -1933,30 +2261,35 @@ class HarnessExecutionError extends HarnessError {
1933
2261
  }
1934
2262
  var harnessErrorDocument = (error) => {
1935
2263
  const normalized = normalizeHarnessError(error);
2264
+ const diagnostic = providerStreamDiagnostic(error);
1936
2265
  return {
1937
2266
  schemaVersion: HARNESS_ERROR_SCHEMA_VERSION,
1938
2267
  kind: "error",
1939
2268
  error: {
1940
2269
  code: normalized.code,
1941
2270
  category: normalized.category,
1942
- retryable: normalized.retryable
2271
+ retryable: normalized.retryable,
2272
+ ...diagnostic ? { providerDiagnostic: diagnostic } : {}
1943
2273
  }
1944
2274
  };
1945
2275
  };
1946
- var numericStatuses = (error) => {
1947
- if (!error || typeof error !== "object")
1948
- return;
1949
- const record = error;
1950
- const values = [record.status, record.statusCode].filter((value) => typeof value === "number" && Number.isSafeInteger(value));
1951
- return values.length > 0 ? values : undefined;
1952
- };
1953
2276
  var normalizeHarnessError = (error) => {
2277
+ const diagnostic = providerStreamDiagnostic(error);
2278
+ if (diagnostic)
2279
+ return new HarnessProviderError("Provider stream failed.", { cause: error, retryable: false });
1954
2280
  if (error instanceof HarnessError)
1955
2281
  return error;
1956
2282
  const message = error instanceof Error ? error.message : "Harness execution failed.";
1957
- const statuses = numericStatuses(error) ?? [];
1958
- if (statuses.some((status) => status === 429 || status >= 500 && status <= 599)) {
1959
- return new HarnessProviderError(message, { cause: error, retryable: true });
2283
+ const failure = classifyProviderFailure(error);
2284
+ if (failure.retryable) {
2285
+ const record = error && typeof error === "object" ? error : {};
2286
+ const body = typeof record.responseBody === "string" ? record.responseBody : typeof record.body === "string" ? record.body : undefined;
2287
+ const providerError = new HarnessProviderError("Provider request failed.", { cause: error, retryable: true });
2288
+ return Object.assign(providerError, {
2289
+ ...failure.httpStatus !== undefined ? { status: failure.httpStatus } : {},
2290
+ ...failure.providerStatus ? { providerStatus: failure.providerStatus } : {},
2291
+ provider: providerDiagnostic(body, failure.httpStatus)
2292
+ });
1960
2293
  }
1961
2294
  const name = error && typeof error === "object" && typeof error.name === "string" ? error.name : "";
1962
2295
  const code = error && typeof error === "object" && typeof error.code === "string" ? error.code : "";
@@ -2236,12 +2569,15 @@ var resolveHarnessConfig = (input = {}, registry = DEFAULT_PROVIDER_REGISTRY) =>
2236
2569
  const userId = scopeValue("userId", input.userId ?? process.env.ZHIVEX_HARNESS_USER_ID);
2237
2570
  const namespace = scopeValue("namespace", input.namespace ?? process.env.ZHIVEX_HARNESS_NAMESPACE, defaultHarnessNamespace(workspace));
2238
2571
  const timeoutMs = integerOption("timeoutMs", input.timeoutMs, process.env.ZHIVEX_HARNESS_TIMEOUT_MS, 15 * 60000, 1000, 24 * 60 * 60000);
2239
- if (input.unlimitedTokens !== undefined && typeof input.unlimitedTokens !== "boolean") {
2240
- throw new HarnessConfigError("unlimitedTokens must be a boolean.");
2572
+ for (const key of ["unlimitedTokens", "unlimitedSteps", "unlimitedToolCalls", "unlimitedDuration"]) {
2573
+ if (input[key] !== undefined && typeof input[key] !== "boolean")
2574
+ throw new HarnessConfigError(`${key} must be a boolean.`);
2241
2575
  }
2242
2576
  const tokenMode = input.unlimitedTokens === undefined ? {} : { unlimitedTokens: input.unlimitedTokens };
2243
2577
  const budget = {
2244
2578
  ...tokenMode,
2579
+ ...input.unlimitedSteps === undefined ? {} : { unlimitedSteps: input.unlimitedSteps },
2580
+ ...input.unlimitedToolCalls === undefined ? {} : { unlimitedToolCalls: input.unlimitedToolCalls },
2245
2581
  maxSteps,
2246
2582
  maxToolCalls: integerOption("maxToolCalls", input.maxToolCalls, process.env.ZHIVEX_HARNESS_MAX_TOOL_CALLS, DEFAULT_HARNESS_BUDGET.maxToolCalls, 0, Number.MAX_SAFE_INTEGER),
2247
2583
  maxToolErrors: integerOption("maxToolErrors", input.maxToolErrors, process.env.ZHIVEX_HARNESS_MAX_TOOL_ERRORS, DEFAULT_HARNESS_BUDGET.maxToolErrors, 0, 100),
@@ -2315,6 +2651,7 @@ var resolveHarnessConfig = (input = {}, registry = DEFAULT_PROVIDER_REGISTRY) =>
2315
2651
  },
2316
2652
  maxSteps,
2317
2653
  timeoutMs,
2654
+ ...input.unlimitedDuration === undefined ? {} : { unlimitedDuration: input.unlimitedDuration },
2318
2655
  requireVerifiedDelivery: input.requireVerifiedDelivery ?? false,
2319
2656
  budget,
2320
2657
  ...maxCostUsd === undefined ? {} : {
@@ -2338,7 +2675,8 @@ var resolveHarnessConfig = (input = {}, registry = DEFAULT_PROVIDER_REGISTRY) =>
2338
2675
  };
2339
2676
  var createProviderModel = (config, env = process.env, registry = DEFAULT_PROVIDER_REGISTRY) => {
2340
2677
  try {
2341
- return registry.createModel(config, env);
2678
+ const model = registry.createModel(config, env);
2679
+ return registry === DEFAULT_PROVIDER_REGISTRY && ["anthropic", "openai", "gemini", "vertex", "qwen"].includes(config.provider) ? markTaskTransportModel(model) : model;
2342
2680
  } catch (error) {
2343
2681
  throw new HarnessProviderError(`Provider ${config.provider} could not be initialized.`, {
2344
2682
  cause: error,
@@ -2347,4 +2685,4 @@ var createProviderModel = (config, env = process.env, registry = DEFAULT_PROVIDE
2347
2685
  }
2348
2686
  };
2349
2687
  var providerAvailability = (env = process.env, registry = DEFAULT_PROVIDER_REGISTRY) => registry.availability(env);
2350
- export { HARNESS_ERROR_CODES, HARNESS_ERROR_SCHEMA_VERSION, HarnessError, HarnessConfigError, HarnessWorkspaceError, HarnessStateConflictError, HarnessProviderError, HarnessExecutionError, harnessErrorDocument, normalizeHarnessError, vertexRoute, vertexConfigured, modelCatalogSchema, bundledModelCatalog, catalogModels, modelDescription, PROVIDERS, createProviderRegistry, BUILTIN_PROVIDER_REGISTRATIONS, DEFAULT_PROVIDER_REGISTRY, PROVIDER_DESCRIPTORS, reasoningEffortSchema, modelReasoningEfforts, withReasoningEffort, DEFAULT_ALLOWED_CHECKS, HARNESS_CONFIG_SCHEMA_VERSION, HARNESS_CONFIG_MIGRATABLE_SCHEMA_VERSIONS, HARNESS_STORE_BACKENDS, HARNESS_EXECUTION_BACKENDS, HARNESS_OCI_RUNTIMES, HARNESS_OCI_SHELL_MODES, HARNESS_EXECUTION_POLICY_VERSION, DEFAULT_OCI_EXECUTION, HARNESS_REQUIRED_CAPABILITIES, HARNESS_SUBAGENT_PROFILES, DEFAULT_HARNESS_MAX_STEPS, DEFAULT_HARNESS_BUDGET, DEFAULT_HARNESS_COMPACTION, DEFAULT_SUBAGENT_BUDGET, migrateHarnessConfigInput, defaultHarnessNamespace, parseProvider, providerDescriptor, resolveHarnessConfig, createProviderModel, providerAvailability };
2688
+ export { HARNESS_ERROR_CODES, HARNESS_ERROR_SCHEMA_VERSION, providerStreamDiagnostic, HarnessError, HarnessConfigError, HarnessWorkspaceError, HarnessStateConflictError, HarnessProviderError, HarnessExecutionError, harnessErrorDocument, normalizeHarnessError, vertexRoute, vertexConfigured, modelCatalogSchema, bundledModelCatalog, catalogModels, modelDescription, PROVIDERS, createProviderRegistry, BUILTIN_PROVIDER_REGISTRATIONS, DEFAULT_PROVIDER_REGISTRY, PROVIDER_DESCRIPTORS, reasoningEffortSchema, modelReasoningEfforts, withReasoningEffort, isTaskTransportModel, DEFAULT_ALLOWED_CHECKS, HARNESS_CONFIG_SCHEMA_VERSION, HARNESS_CONFIG_MIGRATABLE_SCHEMA_VERSIONS, HARNESS_STORE_BACKENDS, HARNESS_EXECUTION_BACKENDS, HARNESS_OCI_RUNTIMES, HARNESS_OCI_SHELL_MODES, HARNESS_EXECUTION_POLICY_VERSION, DEFAULT_OCI_EXECUTION, HARNESS_REQUIRED_CAPABILITIES, HARNESS_SUBAGENT_PROFILES, DEFAULT_HARNESS_MAX_STEPS, DEFAULT_HARNESS_BUDGET, DEFAULT_HARNESS_COMPACTION, DEFAULT_SUBAGENT_BUDGET, migrateHarnessConfigInput, defaultHarnessNamespace, parseProvider, providerDescriptor, resolveHarnessConfig, createProviderModel, providerAvailability };