@zhivex-ai/harness 1.2.0 → 1.3.0-rc.7

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 (164) hide show
  1. package/CHANGELOG.md +64 -0
  2. package/README.md +9 -10
  3. package/contracts/engine-api.json +2921 -0
  4. package/contracts/public-api.json +267 -1
  5. package/contracts/stable-api-signatures.json +43 -43
  6. package/dist/acp-cli.js +137 -15002
  7. package/dist/approvals/approval-history.d.ts +22 -0
  8. package/dist/approvals/explicit-review.d.ts +24 -0
  9. package/dist/approvals/host-policy-identity.d.ts +3 -0
  10. package/dist/cli/arguments.d.ts +6 -2
  11. package/dist/cli/checkpoints.d.ts +230 -0
  12. package/dist/cli/cli-options.d.ts +2 -41
  13. package/dist/cli/cli-profiles.d.ts +4 -2
  14. package/dist/cli/cli-stream.d.ts +2 -167
  15. package/dist/cli/governance-report.d.ts +5 -0
  16. package/dist/cli/policy-decisions.d.ts +9 -0
  17. package/dist/cli/policy.d.ts +5 -0
  18. package/dist/cli/presentation.d.ts +3 -1
  19. package/dist/cli/run-document.d.ts +2 -91
  20. package/dist/cli/terminal/terminal-continuation.d.ts +2 -3
  21. package/dist/cli/terminal/terminal-ui.d.ts +4 -0
  22. package/dist/{cli-entry-c2f58zj2.js → cli-entry-ae7x44d4.js} +14969 -10731
  23. package/dist/{cli-entry-427869g9.js → cli-entry-d5788aay.js} +388 -47
  24. package/dist/cli-entry-ev76ezcd.js +656 -0
  25. package/dist/{cli-3jmy4h5h.js → cli-t7hrhayq.js} +918 -2223
  26. package/dist/cli.js +3 -5
  27. package/dist/client/acp-mcp-admission.d.ts +32 -0
  28. package/dist/client/acp-mcp-host.d.ts +19 -0
  29. package/dist/client/acp-mcp-session.d.ts +14 -0
  30. package/dist/client/acp-stdio.d.ts +2 -0
  31. package/dist/client/acp.d.ts +4 -1
  32. package/dist/client/adapter.d.ts +13 -1
  33. package/dist/client/continuation.d.ts +3 -0
  34. package/dist/client/json-contracts.d.ts +107 -4
  35. package/dist/client/local-service.d.ts +2 -0
  36. package/dist/client/protocol.d.ts +127 -1
  37. package/dist/client/run-document.d.ts +91 -0
  38. package/dist/client/service-events.d.ts +4 -0
  39. package/dist/client/stream.d.ts +167 -0
  40. package/dist/compat/cli-options.d.ts +53 -0
  41. package/dist/compat/code-support.d.ts +22 -0
  42. package/dist/compat/code-support.js +74 -0
  43. package/dist/{config-1k9t4jhh.js → config-c002f06f.js} +1 -1
  44. package/dist/config-j3jga5wh.js +61 -0
  45. package/dist/context/adaptive-compaction.d.ts +1 -0
  46. package/dist/context/compaction.d.ts +1 -1
  47. package/dist/context/request-measurements.d.ts +17 -0
  48. package/dist/context/request-projection.d.ts +10 -0
  49. package/dist/context/task-memory.d.ts +1 -0
  50. package/dist/engine/acp.d.ts +6 -0
  51. package/dist/engine/acp.js +205 -0
  52. package/dist/engine/client.d.ts +6 -0
  53. package/dist/engine/client.js +28 -0
  54. package/dist/engine/desktop-providers-v1.d.ts +4 -0
  55. package/dist/engine/desktop-providers-v1.js +18 -0
  56. package/dist/engine/desktop-state-v1.d.ts +10 -0
  57. package/dist/engine/desktop-state-v1.js +168 -0
  58. package/dist/engine/index.d.ts +73 -0
  59. package/dist/engine/index.js +977 -0
  60. package/dist/engine/mcp-stdio-v1.d.ts +11 -0
  61. package/dist/engine/mcp-stdio-v1.js +108 -0
  62. package/dist/engine/models.d.ts +3 -0
  63. package/dist/engine/models.js +894 -0
  64. package/dist/engine/protocol.d.ts +7 -0
  65. package/dist/engine/protocol.js +182 -0
  66. package/dist/engine/service.d.ts +5 -0
  67. package/dist/engine/service.js +28 -0
  68. package/dist/execution/acceptance-snapshot.d.ts +2 -0
  69. package/dist/execution/execution-environment.d.ts +10 -0
  70. package/dist/execution/mcp-oci-channel.d.ts +11 -0
  71. package/dist/execution/mcp-oci-server.d.ts +38 -0
  72. package/dist/execution/mcp-oci-workspace.d.ts +23 -0
  73. package/dist/execution/mcp-resource-recovery.d.ts +19 -0
  74. package/dist/execution/mcp-workspace-snapshot.d.ts +20 -0
  75. package/dist/hostile-repository-demo.js +3368 -1304
  76. package/dist/index-1bx83sw4.js +4 -0
  77. package/dist/index-2gz7jv7g.js +549 -0
  78. package/dist/{cli-entry-b1mfvmxe.js → index-2jrdcj6b.js} +72 -115
  79. package/dist/index-3ah1f369.js +356 -0
  80. package/dist/index-42gp2hy8.js +1555 -0
  81. package/dist/index-4jw3tvy8.js +301 -0
  82. package/dist/index-8705zxpr.js +145 -0
  83. package/dist/index-8vm2m34s.js +2080 -0
  84. package/dist/index-8zzhggxv.js +477 -0
  85. package/dist/index-a97bezbz.js +1073 -0
  86. package/dist/index-gq9xagx2.js +1343 -0
  87. package/dist/index-h0mqx2ed.js +1373 -0
  88. package/dist/index-jgrx804e.js +5589 -0
  89. package/dist/index-qfpz5y2v.js +174 -0
  90. package/dist/index-t60rva31.js +1004 -0
  91. package/dist/index-wg1sd3at.js +80 -0
  92. package/dist/index-xqxeypt5.js +888 -0
  93. package/dist/index-yb239ghk.js +961 -0
  94. package/dist/index-z0qxmkm2.js +3389 -0
  95. package/dist/index-z4e8d0ph.js +1768 -0
  96. package/dist/index.js +251 -18649
  97. package/dist/integrations/mcp-host-session.d.ts +26 -0
  98. package/dist/integrations/mcp-stdio-admission.d.ts +54 -0
  99. package/dist/integrations/mcp-stdio-client.d.ts +44 -0
  100. package/dist/integrations/mcp-stdio-framing.d.ts +18 -0
  101. package/dist/integrations/mcp-stdio-launch.d.ts +20 -0
  102. package/dist/integrations/mcp-stdio-session.d.ts +7 -0
  103. package/dist/integrations/mcp-stdio-tools.d.ts +12 -0
  104. package/dist/internal/desktop/catalog.d.ts +2 -0
  105. package/dist/internal/desktop/persistence.d.ts +2 -3
  106. package/dist/internal/desktop/providers.d.ts +1 -0
  107. package/dist/models/catalog.d.ts +2 -0
  108. package/dist/persistence/governance-context.d.ts +126 -0
  109. package/dist/persistence/governance-report.d.ts +299 -0
  110. package/dist/persistence/host-database-backup.d.ts +28 -0
  111. package/dist/persistence/mcp-execution-journal.d.ts +19 -0
  112. package/dist/persistence/mcp-reconciliation.d.ts +33 -0
  113. package/dist/persistence/mcp-resource-journal.d.ts +54 -0
  114. package/dist/persistence/workspace-checkpoints.d.ts +138 -0
  115. package/dist/providers/anthropic-continuation.d.ts +5 -0
  116. package/dist/providers/providers.d.ts +1 -1
  117. package/dist/providers/vertex-auth.d.ts +27 -0
  118. package/dist/runtime/delegation-contracts.d.ts +9 -0
  119. package/dist/runtime/delegation-correction.d.ts +9 -0
  120. package/dist/runtime/delegation-result.d.ts +73 -0
  121. package/dist/runtime/error-diagnostics.d.ts +86 -0
  122. package/dist/runtime/harness.d.ts +11 -1
  123. package/dist/runtime/policy-decisions.d.ts +66 -0
  124. package/dist/runtime/policy-inspection.d.ts +52 -0
  125. package/dist/runtime/provider-diagnostics.d.ts +1 -0
  126. package/dist/runtime/runtime-instructions.d.ts +8 -0
  127. package/dist/runtime/task-acceptance-checks.d.ts +103 -0
  128. package/dist/runtime/task-acceptance-delivery.d.ts +107 -0
  129. package/dist/runtime/task-acceptance-host.d.ts +20 -0
  130. package/dist/runtime/task-acceptance-record.d.ts +107 -0
  131. package/dist/runtime/task-acceptance-validation.d.ts +25 -0
  132. package/dist/runtime/task-acceptance.d.ts +47 -0
  133. package/dist/runtime/time-to-safe-fix.d.ts +83 -0
  134. package/dist/runtime/tool-policy-file.d.ts +23 -0
  135. package/dist/runtime/tool-policy-paths.d.ts +5 -0
  136. package/dist/runtime/tool-policy.d.ts +6 -0
  137. package/dist/service-cli.js +19 -14504
  138. package/dist/{service-client-cli-yx56n0hc.js → service-client-cli-kns4mf57.js} +307 -248
  139. package/dist/verify-historical-migrations.js +3314 -1251
  140. package/dist/workspace/path-policy.d.ts +4 -0
  141. package/dist/zhx.js +3 -5
  142. package/docs/ACP.md +14 -2
  143. package/docs/ANTHROPIC.md +33 -0
  144. package/docs/CLI.md +132 -0
  145. package/docs/CLIENT_PROTOCOL.md +45 -0
  146. package/docs/CODE_RELEASE.md +93 -0
  147. package/docs/ENGINE_API.md +319 -0
  148. package/docs/EXTENSIBILITY.md +46 -3
  149. package/docs/FIRST_USE.md +6 -6
  150. package/docs/LOCAL_SERVICE.md +13 -0
  151. package/docs/MCP_STDIO.md +20 -0
  152. package/docs/README.md +6 -0
  153. package/docs/STABILITY.md +9 -1
  154. package/docs/SUPPORT_MATRIX.md +1 -1
  155. package/docs/TOOL_POLICY.md +81 -0
  156. package/docs/VERTEX.md +50 -0
  157. package/docs/adr/0002-isolated-mcp-stdio.md +135 -0
  158. package/docs/fixtures/mcp-stdio-contract-v1.json +189 -0
  159. package/docs/support-matrix.json +2 -0
  160. package/evaluations/representative-assembly-matrix.json +64 -1
  161. package/evaluations/task-acceptance-routes.json +7 -0
  162. package/examples/README.md +1 -1
  163. package/package.json +74 -12
  164. package/dist/cli-entry-64pdp3k5.js +0 -17
@@ -1,9 +1,199 @@
1
1
  // src/providers/reasoning.ts
2
- import { z as z2 } from "zod";
3
- import { wrapLanguageModel as wrapLanguageModel4 } from "@zhivex-ai/core";
2
+ import { z as z3 } from "zod";
3
+ import { wrapLanguageModel as wrapLanguageModel6 } from "@zhivex-ai/core";
4
+
5
+ // src/providers/anthropic-continuation.ts
6
+ import { ValidationError, wrapLanguageModel } from "@zhivex-ai/core";
7
+ async function* assembleAnthropicContinuation(events) {
8
+ let pending;
9
+ let bytes = 0;
10
+ const invalid = () => new ValidationError("Invalid or oversized Anthropic signed continuation block.");
11
+ const flush = function* () {
12
+ if (!pending)
13
+ return;
14
+ if (!pending.signature)
15
+ throw invalid();
16
+ yield { type: "provider-data", provider: "anthropic", data: pending };
17
+ pending = undefined;
18
+ bytes = 0;
19
+ };
20
+ for await (const event of events) {
21
+ if (event.type === "provider-data" && event.provider === "anthropic" && event.data && typeof event.data === "object" && !Array.isArray(event.data)) {
22
+ const data = event.data;
23
+ if (data.type === "thinking_delta" || data.type === "signature_delta") {
24
+ const field = data.type === "thinking_delta" ? "thinking" : "signature";
25
+ if (!pending || typeof data[field] !== "string")
26
+ throw invalid();
27
+ bytes += Buffer.byteLength(data[field]);
28
+ if (bytes > 1024 * 1024)
29
+ throw invalid();
30
+ pending[field] += data[field];
31
+ continue;
32
+ }
33
+ if (data.type === "thinking") {
34
+ yield* flush();
35
+ if (typeof data.thinking !== "string" || typeof data.signature !== "string")
36
+ throw invalid();
37
+ pending = { type: "thinking", thinking: data.thinking, signature: data.signature };
38
+ bytes = Buffer.byteLength(data.thinking) + Buffer.byteLength(data.signature);
39
+ if (bytes > 1024 * 1024)
40
+ throw invalid();
41
+ continue;
42
+ }
43
+ }
44
+ yield* flush();
45
+ yield event;
46
+ }
47
+ yield* flush();
48
+ }
49
+ var withAnthropicContinuation = (model) => wrapLanguageModel(model, [{
50
+ name: "harness-anthropic-signed-continuation-v1",
51
+ wrapStream: async (_context, next) => assembleAnthropicContinuation(await next())
52
+ }]);
53
+
54
+ // src/providers/vertex-auth.ts
55
+ import { GoogleAuth } from "google-auth-library";
56
+ import { createVertex } from "@zhivex-ai/vertex";
57
+ import { wrapLanguageModel as wrapLanguageModel2 } from "@zhivex-ai/core";
58
+
59
+ // src/runtime/provider-diagnostics.ts
60
+ import { z } from "zod";
61
+ var providerDiagnosticSchema = z.strictObject({
62
+ reason: z.enum(["previous_response_unavailable", "context_length_exceeded", "authentication", "payment_required", "permission", "rate_limit", "model_unavailable", "invalid_request", "server_error", "unknown"]),
63
+ parameter: z.enum(["previous_response_id", "input", "messages", "tools", "model", "max_output_tokens", "max_tokens", "temperature", "other", "none"]),
64
+ bodyState: z.enum(["parsed", "malformed", "too_large", "unavailable", "read_timeout"])
65
+ });
66
+ function providerDiagnostic(body, status) {
67
+ let reason = status === 401 ? "authentication" : status === 402 ? "payment_required" : status === 403 ? "permission" : status === 429 ? "rate_limit" : status && status >= 500 ? "server_error" : "unknown";
68
+ let parameter = "none";
69
+ if (typeof body !== "string")
70
+ return { reason, parameter, bodyState: "unavailable" };
71
+ if (Buffer.byteLength(body) > 8192)
72
+ return { reason, parameter, bodyState: "too_large" };
73
+ try {
74
+ const parsed = JSON.parse(body);
75
+ const detail = parsed?.error ?? parsed;
76
+ const code = [detail?.code, detail?.status, detail?.type].find((value) => typeof value === "string") ?? "";
77
+ const message = typeof detail?.message === "string" ? detail.message : "";
78
+ const param = providerDiagnosticSchema.shape.parameter.safeParse(detail?.param);
79
+ parameter = param.success ? param.data : detail?.param == null ? "none" : "other";
80
+ if (/response/i.test(message) && /not found|expired/i.test(message) && (parameter === "previous_response_id" || parameter === "none"))
81
+ reason = "previous_response_unavailable";
82
+ else if (["context_length_exceeded", "context_window_exceeded"].includes(code))
83
+ reason = "context_length_exceeded";
84
+ else if (["invalid_api_key", "authentication_error", "UNAUTHENTICATED"].includes(code))
85
+ reason = "authentication";
86
+ else if (["permission_denied", "permission_error", "PERMISSION_DENIED"].includes(code))
87
+ reason = "permission";
88
+ else if (["rate_limit_exceeded", "rate_limit_error", "RESOURCE_EXHAUSTED"].includes(code))
89
+ reason = "rate_limit";
90
+ else if (["model_not_found", "model_not_available", "NOT_FOUND"].includes(code))
91
+ reason = "model_unavailable";
92
+ else if (["invalid_request_error", "INVALID_ARGUMENT"].includes(code) || status === 400 || status === 422)
93
+ reason = "invalid_request";
94
+ return { reason, parameter, bodyState: "parsed" };
95
+ } catch {
96
+ return { reason, parameter, bodyState: "malformed" };
97
+ }
98
+ }
99
+
100
+ // src/providers/vertex-auth.ts
101
+ var CLOUD_PLATFORM_SCOPE = "https://www.googleapis.com/auth/cloud-platform";
102
+ function vertexRoute(env) {
103
+ const projectId = (env.GOOGLE_CLOUD_PROJECT ?? "").trim();
104
+ const location = (env.VERTEX_LOCATION ?? "").trim();
105
+ if (!/^(?:[a-z][a-z0-9-]{4,61}[a-z0-9]|[0-9]{6,20})$/.test(projectId)) {
106
+ throw new Error("Vertex requires a valid GOOGLE_CLOUD_PROJECT.");
107
+ }
108
+ if (!/^(?:global|us|eu|[a-z]+-[a-z]+[0-9]+)$/.test(location)) {
109
+ throw new Error("Vertex requires an explicit valid VERTEX_LOCATION.");
110
+ }
111
+ return Object.freeze({ projectId, location });
112
+ }
113
+ function vertexConfigured(env) {
114
+ try {
115
+ vertexRoute(env);
116
+ return true;
117
+ } catch {
118
+ return false;
119
+ }
120
+ }
121
+ var VERTEX_ENVIRONMENT = ["GOOGLE_CLOUD_PROJECT", "VERTEX_LOCATION", "GOOGLE_APPLICATION_CREDENTIALS"];
122
+ function vertexTokenSource(env, route, createAuth = (options) => new GoogleAuth(options)) {
123
+ const keyFilename = env.GOOGLE_APPLICATION_CREDENTIALS?.trim();
124
+ const auth = createAuth({
125
+ projectId: route.projectId,
126
+ scopes: [CLOUD_PLATFORM_SCOPE],
127
+ ...keyFilename ? { keyFilename } : {}
128
+ });
129
+ return async () => {
130
+ try {
131
+ const token = await auth.getAccessToken();
132
+ if (!token)
133
+ throw new Error("Empty ADC token");
134
+ return token;
135
+ } catch {
136
+ throw new VertexAuthenticationError;
137
+ }
138
+ };
139
+ }
140
+
141
+ class VertexAuthenticationError extends Error {
142
+ status = 401;
143
+ retryable = false;
144
+ constructor() {
145
+ super("Vertex ADC credentials are unavailable or could not be refreshed. Configure Application Default Credentials and retry.");
146
+ this.name = "VertexAuthenticationError";
147
+ }
148
+ }
149
+ function createVertexModel(model, env, createAuth) {
150
+ const route = vertexRoute(env);
151
+ const adapter = createVertex({
152
+ ...route,
153
+ getAccessToken: vertexTokenSource(env, route, createAuth)
154
+ })(model);
155
+ return wrapLanguageModel2(adapter, [{
156
+ name: "harness-vertex-sanitized-errors",
157
+ async wrapGenerate(_context, next) {
158
+ try {
159
+ return await next();
160
+ } catch (error) {
161
+ throw safeVertexError(error);
162
+ }
163
+ },
164
+ async wrapStream(_context, next) {
165
+ let stream;
166
+ try {
167
+ stream = await next();
168
+ } catch (error) {
169
+ throw safeVertexError(error);
170
+ }
171
+ return async function* () {
172
+ try {
173
+ yield* stream;
174
+ } catch (error) {
175
+ throw safeVertexError(error);
176
+ }
177
+ }();
178
+ }
179
+ }]);
180
+ }
181
+ function safeVertexError(error) {
182
+ if (error instanceof VertexAuthenticationError)
183
+ return error;
184
+ const record = error && typeof error === "object" ? error : {};
185
+ if (record.name === "AbortError")
186
+ 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;
188
+ 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
192
+ });
193
+ }
4
194
 
5
195
  // src/providers/qwen-hosted-policy.ts
6
- import { wrapLanguageModel } from "@zhivex-ai/core";
196
+ import { wrapLanguageModel as wrapLanguageModel3 } from "@zhivex-ai/core";
7
197
  function withQwenHostedPolicy(model) {
8
198
  if (model.modelId !== "kimi-k3")
9
199
  return model;
@@ -16,7 +206,7 @@ function withQwenHostedPolicy(model) {
16
206
  }
17
207
  input.providerOptions = { ...options, apiMode: "chat", enable_thinking: true };
18
208
  };
19
- const wrapped = wrapLanguageModel(model, [{
209
+ const wrapped = wrapLanguageModel3(model, [{
20
210
  name: "harness-kimi-k3-chat-thinking-v1",
21
211
  async wrapGenerate(context, next) {
22
212
  prepare(context.input);
@@ -98,7 +288,8 @@ var createMetaContinuationFetch = (fetcher = fetch, backoff = [1000, 2000]) => {
98
288
  };
99
289
 
100
290
  // src/providers/meta-replay.ts
101
- import { wrapLanguageModel as wrapLanguageModel2 } from "@zhivex-ai/core";
291
+ import { wrapLanguageModel as wrapLanguageModel4 } from "@zhivex-ai/core";
292
+ import { withTimeoutSignal } from "@zhivex-ai/core/provider";
102
293
  import { createMeta } from "@zhivex-ai/meta";
103
294
  var replayPlan = (messages) => {
104
295
  let offset = 0;
@@ -164,7 +355,7 @@ var createMetaReplayModel = (options, modelId) => {
164
355
  } }
165
356
  };
166
357
  };
167
- return wrapLanguageModel2(createMeta(options)(modelId), [{
358
+ return wrapLanguageModel4(createMeta(options)(modelId), [{
168
359
  name: "harness-meta-stateless-replay-v1",
169
360
  async wrapGenerate({ input }) {
170
361
  const prepared = prepare(input);
@@ -172,7 +363,54 @@ var createMetaReplayModel = (options, modelId) => {
172
363
  },
173
364
  async wrapStream({ input }) {
174
365
  const prepared = prepare(input);
175
- return prepared.model.stream(prepared.input);
366
+ const lifetime = withTimeoutSignal(prepared.input);
367
+ const { timeoutMs: _timeout, ...request } = prepared.input;
368
+ try {
369
+ const stream = await prepared.model.stream({ ...request, abortSignal: lifetime.signal });
370
+ const iterator = stream[Symbol.asyncIterator]();
371
+ const owned = {
372
+ [Symbol.asyncIterator]() {
373
+ return owned;
374
+ },
375
+ async next() {
376
+ try {
377
+ const result = await iterator.next();
378
+ if (result.done)
379
+ lifetime.cleanup();
380
+ return result;
381
+ } catch (error) {
382
+ lifetime.cleanup();
383
+ throw error;
384
+ }
385
+ },
386
+ async return() {
387
+ try {
388
+ return await iterator.return?.() ?? { done: true, value: undefined };
389
+ } finally {
390
+ lifetime.cleanup();
391
+ }
392
+ },
393
+ async throw(error) {
394
+ try {
395
+ if (iterator.throw) {
396
+ const result = await iterator.throw(error);
397
+ if (result.done)
398
+ lifetime.cleanup();
399
+ return result;
400
+ }
401
+ await iterator.return?.();
402
+ throw error;
403
+ } catch (failure) {
404
+ lifetime.cleanup();
405
+ throw failure;
406
+ }
407
+ }
408
+ };
409
+ return owned;
410
+ } catch (error) {
411
+ lifetime.cleanup();
412
+ throw error;
413
+ }
176
414
  }
177
415
  }]);
178
416
  };
@@ -205,11 +443,11 @@ function annotateMetaRequestError(error) {
205
443
  }
206
444
 
207
445
  // src/models/catalog.ts
208
- import { z } from "zod";
446
+ import { z as z2 } from "zod";
209
447
  // src/models/catalog.json
210
448
  var catalog_default = {
211
449
  schemaVersion: 1,
212
- revision: "2026-09-26-frontier",
450
+ revision: "2026-09-29-vertex",
213
451
  providers: [
214
452
  {
215
453
  id: "openai",
@@ -907,42 +1145,109 @@ var catalog_default = {
907
1145
  ]
908
1146
  }
909
1147
  ]
1148
+ },
1149
+ {
1150
+ id: "anthropic",
1151
+ defaultModel: "claude-sonnet-5",
1152
+ models: [
1153
+ {
1154
+ id: "claude-sonnet-5",
1155
+ name: "claude-sonnet-5",
1156
+ group: "primary",
1157
+ order: 0,
1158
+ lifecycle: "active",
1159
+ validation: "unverified",
1160
+ capabilities: [
1161
+ "chat",
1162
+ "tools",
1163
+ "vision"
1164
+ ],
1165
+ reason: "Provisional Anthropic API route. Account access and live Harness certification are not verified."
1166
+ },
1167
+ {
1168
+ id: "claude-haiku-4-5",
1169
+ name: "claude-haiku-4-5",
1170
+ group: "other",
1171
+ order: 1,
1172
+ lifecycle: "active",
1173
+ validation: "unverified",
1174
+ capabilities: [
1175
+ "chat",
1176
+ "tools",
1177
+ "vision"
1178
+ ],
1179
+ reason: "Provisional Anthropic API route. Account access and live Harness certification are not verified."
1180
+ },
1181
+ {
1182
+ id: "claude-opus-5-5",
1183
+ name: "claude-opus-5-5",
1184
+ group: "other",
1185
+ order: 2,
1186
+ lifecycle: "active",
1187
+ validation: "unverified",
1188
+ capabilities: [
1189
+ "chat",
1190
+ "tools",
1191
+ "vision"
1192
+ ],
1193
+ reason: "Provisional Anthropic API route. Account access and live Harness certification are not verified."
1194
+ }
1195
+ ]
1196
+ },
1197
+ {
1198
+ id: "vertex",
1199
+ defaultModel: "gemini-3.7-flash",
1200
+ models: [
1201
+ {
1202
+ id: "gemini-3.7-flash",
1203
+ name: "Gemini 3.7 Flash (Vertex)",
1204
+ group: "primary",
1205
+ order: 0,
1206
+ lifecycle: "unknown",
1207
+ validation: "unverified",
1208
+ capabilities: [
1209
+ "chat",
1210
+ "tools"
1211
+ ],
1212
+ reason: "Provisional Vertex route; availability depends on project, region and IAM. No live certification."
1213
+ }
1214
+ ]
910
1215
  }
911
1216
  ]
912
1217
  };
913
1218
 
914
1219
  // src/models/catalog.ts
915
- var modelId = z.string().min(1).max(160).regex(/^[a-zA-Z0-9][a-zA-Z0-9._:/-]*$/);
916
- var text = z.string().min(1).max(300).regex(/^[^\x00-\x1f\x7f-\x9f]*$/);
917
- var evidence = z.object({
918
- sourceUrl: z.url().max(1000).refine((value) => {
1220
+ var modelId = z2.string().min(1).max(160).regex(/^[a-zA-Z0-9][a-zA-Z0-9._:/-]*$/);
1221
+ var text = z2.string().min(1).max(300).regex(/^[^\x00-\x1f\x7f-\x9f]*$/);
1222
+ var evidence = z2.object({
1223
+ sourceUrl: z2.url().max(1000).refine((value) => {
919
1224
  const url = new URL(value);
920
1225
  return url.protocol === "https:" && !url.username && !url.password;
921
1226
  }, "Evidence requires an HTTPS URL without credentials"),
922
- checkedAt: z.iso.date()
1227
+ checkedAt: z2.iso.date()
923
1228
  }).strict();
924
- var tokenLimit = z.number().int().positive().max(1e9);
925
- var price = z.number().finite().nonnegative().max(1e6);
926
- var catalogModelSchema = z.object({
1229
+ var tokenLimit = z2.number().int().positive().max(1e9);
1230
+ var price = z2.number().finite().nonnegative().max(1e6);
1231
+ var catalogModelSchema = z2.object({
927
1232
  id: modelId,
928
1233
  name: text,
929
- group: z.enum(["primary", "other"]),
930
- order: z.number().int().min(0),
931
- lifecycle: z.enum(["active", "deprecated", "retired", "unknown"]),
932
- validation: z.enum(["verified", "unverified"]),
933
- capabilities: z.array(z.enum(["chat", "tools", "vision"])).max(3),
1234
+ group: z2.enum(["primary", "other"]),
1235
+ order: z2.number().int().min(0),
1236
+ lifecycle: z2.enum(["active", "deprecated", "retired", "unknown"]),
1237
+ validation: z2.enum(["verified", "unverified"]),
1238
+ capabilities: z2.array(z2.enum(["chat", "tools", "vision"])).max(3),
934
1239
  reason: text.optional(),
935
1240
  replacement: modelId.optional(),
936
- retirementDate: z.iso.date().optional(),
937
- limits: z.object({
1241
+ retirementDate: z2.iso.date().optional(),
1242
+ limits: z2.object({
938
1243
  contextWindowTokens: tokenLimit,
939
- contextWindowType: z.enum(["combined", "input"]),
1244
+ contextWindowType: z2.enum(["combined", "input"]),
940
1245
  maxOutputTokens: tokenLimit,
941
1246
  maxInputTokens: tokenLimit.optional(),
942
1247
  evidence
943
1248
  }).strict().optional(),
944
- pricing: z.object({
945
- currency: z.literal("USD"),
1249
+ pricing: z2.object({
1250
+ currency: z2.literal("USD"),
946
1251
  inputPerMillionTokens: price,
947
1252
  outputPerMillionTokens: price,
948
1253
  cachedInputPerMillionTokens: price.optional(),
@@ -950,8 +1255,8 @@ var catalogModelSchema = z.object({
950
1255
  scope: text,
951
1256
  evidence
952
1257
  }).strict().optional(),
953
- compaction: z.object({
954
- suitability: z.enum(["candidate", "evaluated", "unsuitable", "unknown"]),
1258
+ compaction: z2.object({
1259
+ suitability: z2.enum(["candidate", "evaluated", "unsuitable", "unknown"]),
955
1260
  reason: text,
956
1261
  evidence
957
1262
  }).strict().optional()
@@ -965,17 +1270,17 @@ var catalogModelSchema = z.object({
965
1270
  ctx.addIssue({ code: "custom", message: "maxOutputTokens exceeds combined context window" });
966
1271
  }
967
1272
  });
968
- var modelCatalogSchema = z.object({
969
- schemaVersion: z.literal(1),
970
- revision: z.string().min(1).max(80).regex(/^[a-zA-Z0-9._-]+$/),
971
- providers: z.array(z.object({
972
- id: z.enum(["openai", "qwen", "gemini", "meta"]),
1273
+ var modelCatalogSchema = z2.object({
1274
+ schemaVersion: z2.literal(1),
1275
+ revision: z2.string().min(1).max(80).regex(/^[a-zA-Z0-9._-]+$/),
1276
+ providers: z2.array(z2.object({
1277
+ id: z2.enum(["openai", "qwen", "gemini", "meta", "anthropic", "vertex"]),
973
1278
  defaultModel: modelId,
974
- models: z.array(catalogModelSchema).min(1).max(500)
975
- }).strict()).length(4)
1279
+ models: z2.array(catalogModelSchema).min(1).max(500)
1280
+ }).strict()).length(6)
976
1281
  }).strict().superRefine((catalog, ctx) => {
977
1282
  const invalid = (message) => ctx.addIssue({ code: "custom", message });
978
- if (new Set(catalog.providers.map((p) => p.id)).size !== 4)
1283
+ if (new Set(catalog.providers.map((p) => p.id)).size !== 6)
979
1284
  invalid("Duplicate providers");
980
1285
  for (const provider of catalog.providers) {
981
1286
  const ids = new Set(provider.models.map((m) => m.id));
@@ -1027,12 +1332,13 @@ function modelDescription(model) {
1027
1332
  // src/providers/providers.ts
1028
1333
  import { createHash } from "node:crypto";
1029
1334
  import {
1030
- wrapLanguageModel as wrapLanguageModel3
1335
+ wrapLanguageModel as wrapLanguageModel5
1031
1336
  } from "@zhivex-ai/core";
1337
+ import { createAnthropic } from "@zhivex-ai/anthropic";
1032
1338
  import { createGemini } from "@zhivex-ai/gemini";
1033
1339
  import { createOpenAI } from "@zhivex-ai/openai";
1034
1340
  import { createQwen } from "@zhivex-ai/qwen";
1035
- var PROVIDERS = ["meta", "qwen", "openai", "gemini"];
1341
+ var PROVIDERS = ["meta", "qwen", "openai", "gemini", "anthropic", "vertex"];
1036
1342
  var HARNESS_PROVIDER_CAPABILITIES = [
1037
1343
  "streaming",
1038
1344
  "tool-calling",
@@ -1251,13 +1557,13 @@ var createProviderRegistry = (registrations) => {
1251
1557
  const credentials = Object.freeze(registration.descriptor.credentialNames.map((name) => Object.freeze({ name, present: Boolean(env[name]?.trim()) })));
1252
1558
  return Object.freeze({
1253
1559
  ...registration.descriptor,
1254
- configured: credentials.length === 0 || credentials.some((credential) => credential.present),
1560
+ configured: registration.descriptor.id === "vertex" ? vertexConfigured(env) : credentials.length === 0 || credentials.some((credential) => credential.present),
1255
1561
  credentials,
1256
1562
  configuration: providerConfiguration(registration.diagnostics, env)
1257
1563
  });
1258
1564
  })),
1259
1565
  transportFingerprint: (env = process.env) => {
1260
- const transport = frozenRegistrations.map((registration) => {
1566
+ const transport = frozenRegistrations.filter((registration) => (registration.descriptor.id !== "anthropic" || Boolean(env.ANTHROPIC_BASE_URL?.trim())) && (registration.descriptor.id !== "vertex" || VERTEX_ENVIRONMENT.some((name) => Boolean(env[name]?.trim())))).map((registration) => {
1261
1567
  const names = [
1262
1568
  registration.diagnostics.endpointEnvironmentVariable,
1263
1569
  ...(registration.diagnostics.presence ?? []).map((entry) => entry.environmentVariable),
@@ -1351,12 +1657,12 @@ var normalizeStreamToolCallIds = async function* (model, input, events) {
1351
1657
  };
1352
1658
  }
1353
1659
  };
1354
- var withQwenDurableToolCallIds = (model) => wrapLanguageModel3(model, [{
1660
+ var withQwenDurableToolCallIds = (model) => wrapLanguageModel5(model, [{
1355
1661
  name: "harness-qwen-durable-tool-call-ids",
1356
1662
  wrapGenerate: async ({ input }, next) => normalizeGenerateToolCallIds(model, input, await next()),
1357
1663
  wrapStream: async ({ input }, next) => normalizeStreamToolCallIds(model, input, await next())
1358
1664
  }]);
1359
- var withOpenAIToolResultEnvelopes = (model) => wrapLanguageModel3(model, [{
1665
+ var withOpenAIToolResultEnvelopes = (model) => wrapLanguageModel5(model, [{
1360
1666
  name: "harness-openai-tool-result-envelopes-v1",
1361
1667
  async wrapGenerate({ input }, next) {
1362
1668
  input.toolResultFormat = "envelope";
@@ -1367,7 +1673,7 @@ var withOpenAIToolResultEnvelopes = (model) => wrapLanguageModel3(model, [{
1367
1673
  return next();
1368
1674
  }
1369
1675
  }]);
1370
- var withMetaResponses = (model) => wrapLanguageModel3(model, [{
1676
+ var withMetaResponses = (model) => wrapLanguageModel5(model, [{
1371
1677
  name: "harness-meta-responses-v1",
1372
1678
  async wrapGenerate({ input }, next) {
1373
1679
  input.providerOptions = { ...input.providerOptions, apiMode: "responses" };
@@ -1387,6 +1693,41 @@ var withMetaResponses = (model) => wrapLanguageModel3(model, [{
1387
1693
  }
1388
1694
  }]);
1389
1695
  var BUILTIN_PROVIDER_REGISTRATIONS = Object.freeze([
1696
+ {
1697
+ descriptor: {
1698
+ id: "vertex",
1699
+ name: "Google Cloud Vertex AI",
1700
+ defaultModel: bundledDefaultModel("vertex"),
1701
+ credentialNames: [],
1702
+ capabilities: HARNESS_PROVIDER_CAPABILITIES,
1703
+ support: "provisional"
1704
+ },
1705
+ diagnostics: { presence: [
1706
+ { key: "project", environmentVariable: "GOOGLE_CLOUD_PROJECT" },
1707
+ { key: "location", environmentVariable: "VERTEX_LOCATION" },
1708
+ { key: "adcFile", environmentVariable: "GOOGLE_APPLICATION_CREDENTIALS" }
1709
+ ] },
1710
+ factory: ({ model, env }) => createVertexModel(model, env)
1711
+ },
1712
+ {
1713
+ descriptor: {
1714
+ id: "anthropic",
1715
+ name: "Anthropic",
1716
+ defaultModel: bundledDefaultModel("anthropic"),
1717
+ credentialNames: ["ANTHROPIC_API_KEY"],
1718
+ capabilities: HARNESS_PROVIDER_CAPABILITIES,
1719
+ support: "provisional"
1720
+ },
1721
+ diagnostics: { endpointEnvironmentVariable: "ANTHROPIC_BASE_URL" },
1722
+ factory: ({ model, env, credentials }) => {
1723
+ const baseURL = env.ANTHROPIC_BASE_URL?.trim();
1724
+ return withAnthropicContinuation(createAnthropic({
1725
+ apiKey: credentials.require(),
1726
+ baseURL: baseURL || "https://api.anthropic.com/v1",
1727
+ workspaceId: null
1728
+ })(model));
1729
+ }
1730
+ },
1390
1731
  {
1391
1732
  descriptor: {
1392
1733
  id: "meta",
@@ -1477,7 +1818,7 @@ var DEFAULT_PROVIDER_REGISTRY = createProviderRegistry(BUILTIN_PROVIDER_REGISTRA
1477
1818
  var PROVIDER_DESCRIPTORS = DEFAULT_PROVIDER_REGISTRY.descriptors;
1478
1819
 
1479
1820
  // src/providers/reasoning.ts
1480
- var reasoningEffortSchema = z2.enum(["default", "none", "minimal", "low", "medium", "high", "xhigh", "max"]);
1821
+ var reasoningEffortSchema = z3.enum(["default", "none", "minimal", "low", "medium", "high", "xhigh", "max"]);
1481
1822
  var supportedReasoningEfforts = (capabilities) => ["default", ...capabilities.reasoning ? capabilities.reasoningEfforts ?? [] : []];
1482
1823
  function modelReasoningEfforts(provider, model) {
1483
1824
  if (!DEFAULT_PROVIDER_REGISTRY.has(provider))
@@ -1491,7 +1832,7 @@ function withReasoningEffort(model, value) {
1491
1832
  return model;
1492
1833
  if (!supportedReasoningEfforts(model.capabilities).includes(value))
1493
1834
  throw new Error(`Reasoning effort ${value} is not declared for ${model.provider}/${model.modelId}. Use default or a supported level.`);
1494
- return wrapLanguageModel4(model, [{
1835
+ return wrapLanguageModel6(model, [{
1495
1836
  name: `harness-reasoning-${value}`,
1496
1837
  async wrapGenerate(context, next) {
1497
1838
  context.input.reasoning = { ...context.input.reasoning, effort: value };
@@ -2006,4 +2347,4 @@ var createProviderModel = (config, env = process.env, registry = DEFAULT_PROVIDE
2006
2347
  }
2007
2348
  };
2008
2349
  var providerAvailability = (env = process.env, registry = DEFAULT_PROVIDER_REGISTRY) => registry.availability(env);
2009
- export { HARNESS_ERROR_CODES, HARNESS_ERROR_SCHEMA_VERSION, HarnessError, HarnessConfigError, HarnessWorkspaceError, HarnessStateConflictError, HarnessProviderError, HarnessExecutionError, harnessErrorDocument, normalizeHarnessError, 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 };
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 };