@zhivex-ai/harness 1.3.0-rc.3 → 1.3.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 (157) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/README.md +12 -10
  3. package/SECURITY.md +1 -1
  4. package/SUPPORT.md +4 -4
  5. package/contracts/engine-api.json +334 -0
  6. package/contracts/public-api.json +267 -1
  7. package/contracts/stable-api-signatures.json +43 -43
  8. package/dist/acp-cli.js +54 -18
  9. package/dist/approvals/approval-history.d.ts +22 -0
  10. package/dist/approvals/explicit-review.d.ts +24 -0
  11. package/dist/approvals/host-policy-identity.d.ts +3 -0
  12. package/dist/cli/arguments.d.ts +6 -2
  13. package/dist/cli/checkpoints.d.ts +230 -0
  14. package/dist/cli/cli-profiles.d.ts +4 -2
  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/terminal/terminal-ui.d.ts +4 -0
  20. package/dist/{cli-entry-xmf48p6a.js → cli-entry-1gfg3brj.js} +14921 -10692
  21. package/dist/cli-entry-bx3vjw7h.js +656 -0
  22. package/dist/{index-fvca1xea.js → cli-entry-d5788aay.js} +339 -58
  23. package/dist/{cli-qgwvtk0w.js → cli-etsmtst3.js} +918 -2222
  24. package/dist/cli.js +3 -5
  25. package/dist/client/acp-mcp-admission.d.ts +32 -0
  26. package/dist/client/acp-mcp-host.d.ts +19 -0
  27. package/dist/client/acp-mcp-session.d.ts +14 -0
  28. package/dist/client/acp-stdio.d.ts +2 -0
  29. package/dist/client/acp.d.ts +4 -1
  30. package/dist/client/adapter.d.ts +13 -1
  31. package/dist/client/json-contracts.d.ts +107 -4
  32. package/dist/client/local-service.d.ts +2 -0
  33. package/dist/client/protocol.d.ts +127 -1
  34. package/dist/client/service-events.d.ts +4 -0
  35. package/dist/compat/cli-options.d.ts +13 -1
  36. package/dist/compat/code-support.js +23 -87
  37. package/dist/{config-q32jm1e6.js → config-c002f06f.js} +1 -1
  38. package/dist/{config-6gtpxvjv.js → config-j3jga5wh.js} +3 -1
  39. package/dist/context/adaptive-compaction.d.ts +1 -0
  40. package/dist/context/compaction.d.ts +1 -1
  41. package/dist/context/request-measurements.d.ts +17 -0
  42. package/dist/context/request-projection.d.ts +10 -0
  43. package/dist/context/task-memory.d.ts +1 -0
  44. package/dist/engine/acp.d.ts +2 -0
  45. package/dist/engine/acp.js +197 -1
  46. package/dist/engine/client.js +11 -4
  47. package/dist/engine/desktop-providers-v1.d.ts +4 -0
  48. package/dist/engine/desktop-providers-v1.js +18 -0
  49. package/dist/engine/desktop-state-v1.d.ts +10 -0
  50. package/dist/engine/desktop-state-v1.js +168 -0
  51. package/dist/engine/index.d.ts +12 -0
  52. package/dist/engine/index.js +571 -71
  53. package/dist/engine/mcp-stdio-v1.d.ts +11 -0
  54. package/dist/engine/mcp-stdio-v1.js +108 -0
  55. package/dist/engine/models.d.ts +3 -0
  56. package/dist/engine/models.js +894 -0
  57. package/dist/engine/protocol.d.ts +1 -0
  58. package/dist/engine/protocol.js +24 -0
  59. package/dist/engine/service.js +12 -5
  60. package/dist/execution/acceptance-snapshot.d.ts +2 -0
  61. package/dist/execution/execution-environment.d.ts +10 -0
  62. package/dist/execution/mcp-oci-channel.d.ts +11 -0
  63. package/dist/execution/mcp-oci-server.d.ts +38 -0
  64. package/dist/execution/mcp-oci-workspace.d.ts +23 -0
  65. package/dist/execution/mcp-resource-recovery.d.ts +19 -0
  66. package/dist/execution/mcp-workspace-snapshot.d.ts +20 -0
  67. package/dist/hostile-repository-demo.js +3169 -1163
  68. package/dist/{index-f4sb0e2q.js → index-2jrdcj6b.js} +17 -2
  69. package/dist/{index-77h9qr5h.js → index-3ah1f369.js} +40 -10
  70. package/dist/{index-pgqz45fj.js → index-42gp2hy8.js} +197 -1091
  71. package/dist/{index-41fkzt91.js → index-4jw3tvy8.js} +10 -2
  72. package/dist/index-6m08wvab.js +1768 -0
  73. package/dist/index-8705zxpr.js +145 -0
  74. package/dist/{index-d0wrghff.js → index-8vm2m34s.js} +225 -1416
  75. package/dist/index-8zzhggxv.js +477 -0
  76. package/dist/index-a97bezbz.js +1073 -0
  77. package/dist/index-azmwjp95.js +1004 -0
  78. package/dist/{cli-entry-0mmeag20.js → index-gq9xagx2.js} +122 -836
  79. package/dist/index-h0mqx2ed.js +1373 -0
  80. package/dist/index-hnaxfpb5.js +5589 -0
  81. package/dist/{index-2aymdsqc.js → index-qfpz5y2v.js} +24 -0
  82. package/dist/{index-kfgt9yqq.js → index-w2sj0wkw.js} +33 -10
  83. package/dist/index-wg1sd3at.js +80 -0
  84. package/dist/index-xqxeypt5.js +888 -0
  85. package/dist/index-yb239ghk.js +961 -0
  86. package/dist/index-z0qxmkm2.js +3389 -0
  87. package/dist/index.js +85 -72
  88. package/dist/integrations/mcp-host-session.d.ts +26 -0
  89. package/dist/integrations/mcp-stdio-admission.d.ts +54 -0
  90. package/dist/integrations/mcp-stdio-client.d.ts +44 -0
  91. package/dist/integrations/mcp-stdio-framing.d.ts +18 -0
  92. package/dist/integrations/mcp-stdio-launch.d.ts +20 -0
  93. package/dist/integrations/mcp-stdio-session.d.ts +7 -0
  94. package/dist/integrations/mcp-stdio-tools.d.ts +12 -0
  95. package/dist/internal/desktop/catalog.d.ts +2 -0
  96. package/dist/internal/desktop/persistence.d.ts +2 -3
  97. package/dist/internal/desktop/providers.d.ts +1 -0
  98. package/dist/models/catalog.d.ts +2 -0
  99. package/dist/persistence/governance-context.d.ts +126 -0
  100. package/dist/persistence/governance-report.d.ts +299 -0
  101. package/dist/persistence/host-database-backup.d.ts +28 -0
  102. package/dist/persistence/mcp-execution-journal.d.ts +19 -0
  103. package/dist/persistence/mcp-reconciliation.d.ts +33 -0
  104. package/dist/persistence/mcp-resource-journal.d.ts +54 -0
  105. package/dist/persistence/workspace-checkpoints.d.ts +138 -0
  106. package/dist/providers/anthropic-continuation.d.ts +5 -0
  107. package/dist/providers/providers.d.ts +1 -1
  108. package/dist/providers/vertex-auth.d.ts +27 -0
  109. package/dist/runtime/delegation-contracts.d.ts +9 -0
  110. package/dist/runtime/delegation-correction.d.ts +9 -0
  111. package/dist/runtime/delegation-result.d.ts +73 -0
  112. package/dist/runtime/error-diagnostics.d.ts +86 -0
  113. package/dist/runtime/harness.d.ts +11 -1
  114. package/dist/runtime/policy-decisions.d.ts +66 -0
  115. package/dist/runtime/policy-inspection.d.ts +52 -0
  116. package/dist/runtime/provider-diagnostics.d.ts +1 -0
  117. package/dist/runtime/runtime-instructions.d.ts +8 -0
  118. package/dist/runtime/task-acceptance-checks.d.ts +103 -0
  119. package/dist/runtime/task-acceptance-delivery.d.ts +107 -0
  120. package/dist/runtime/task-acceptance-host.d.ts +20 -0
  121. package/dist/runtime/task-acceptance-record.d.ts +107 -0
  122. package/dist/runtime/task-acceptance-validation.d.ts +25 -0
  123. package/dist/runtime/task-acceptance.d.ts +47 -0
  124. package/dist/runtime/time-to-safe-fix.d.ts +83 -0
  125. package/dist/runtime/tool-policy-file.d.ts +23 -0
  126. package/dist/runtime/tool-policy-paths.d.ts +5 -0
  127. package/dist/runtime/tool-policy.d.ts +6 -0
  128. package/dist/service-cli.js +14 -7
  129. package/dist/{service-client-cli-gs78wrxe.js → service-client-cli-3365rfav.js} +307 -248
  130. package/dist/verify-historical-migrations.js +3134 -1129
  131. package/dist/workspace/path-policy.d.ts +4 -0
  132. package/dist/zhx.js +3 -5
  133. package/docs/ACP.md +14 -2
  134. package/docs/ANTHROPIC.md +33 -0
  135. package/docs/CLI.md +132 -0
  136. package/docs/CLIENT_PROTOCOL.md +45 -0
  137. package/docs/CODE_RELEASE.md +35 -18
  138. package/docs/ENGINE_API.md +216 -7
  139. package/docs/EXTENSIBILITY.md +46 -3
  140. package/docs/FIRST_USE.md +6 -6
  141. package/docs/LOCAL_SERVICE.md +13 -0
  142. package/docs/MCP_STDIO.md +20 -0
  143. package/docs/README.md +1 -0
  144. package/docs/STABILITY.md +4 -2
  145. package/docs/SUPPORT_MATRIX.md +1 -1
  146. package/docs/TOOL_POLICY.md +81 -0
  147. package/docs/VERTEX.md +50 -0
  148. package/docs/adr/0002-isolated-mcp-stdio.md +135 -0
  149. package/docs/fixtures/mcp-stdio-contract-v1.json +189 -0
  150. package/docs/support-matrix.json +2 -0
  151. package/evaluations/representative-assembly-matrix.json +46 -1
  152. package/evaluations/task-acceptance-routes.json +7 -0
  153. package/examples/README.md +3 -3
  154. package/package.json +43 -12
  155. package/dist/cli-entry-64pdp3k5.js +0 -17
  156. package/dist/cli-entry-7h9savv5.js +0 -375
  157. package/dist/index-5wjwe91x.js +0 -9434
@@ -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,7 @@ 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";
102
292
  import { withTimeoutSignal } from "@zhivex-ai/core/provider";
103
293
  import { createMeta } from "@zhivex-ai/meta";
104
294
  var replayPlan = (messages) => {
@@ -165,7 +355,7 @@ var createMetaReplayModel = (options, modelId) => {
165
355
  } }
166
356
  };
167
357
  };
168
- return wrapLanguageModel2(createMeta(options)(modelId), [{
358
+ return wrapLanguageModel4(createMeta(options)(modelId), [{
169
359
  name: "harness-meta-stateless-replay-v1",
170
360
  async wrapGenerate({ input }) {
171
361
  const prepared = prepare(input);
@@ -253,11 +443,11 @@ function annotateMetaRequestError(error) {
253
443
  }
254
444
 
255
445
  // src/models/catalog.ts
256
- import { z } from "zod";
446
+ import { z as z2 } from "zod";
257
447
  // src/models/catalog.json
258
448
  var catalog_default = {
259
449
  schemaVersion: 1,
260
- revision: "2026-09-26-frontier",
450
+ revision: "2026-09-29-vertex",
261
451
  providers: [
262
452
  {
263
453
  id: "openai",
@@ -955,42 +1145,109 @@ var catalog_default = {
955
1145
  ]
956
1146
  }
957
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
+ ]
958
1215
  }
959
1216
  ]
960
1217
  };
961
1218
 
962
1219
  // src/models/catalog.ts
963
- var modelId = z.string().min(1).max(160).regex(/^[a-zA-Z0-9][a-zA-Z0-9._:/-]*$/);
964
- var text = z.string().min(1).max(300).regex(/^[^\x00-\x1f\x7f-\x9f]*$/);
965
- var evidence = z.object({
966
- 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) => {
967
1224
  const url = new URL(value);
968
1225
  return url.protocol === "https:" && !url.username && !url.password;
969
1226
  }, "Evidence requires an HTTPS URL without credentials"),
970
- checkedAt: z.iso.date()
1227
+ checkedAt: z2.iso.date()
971
1228
  }).strict();
972
- var tokenLimit = z.number().int().positive().max(1e9);
973
- var price = z.number().finite().nonnegative().max(1e6);
974
- 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({
975
1232
  id: modelId,
976
1233
  name: text,
977
- group: z.enum(["primary", "other"]),
978
- order: z.number().int().min(0),
979
- lifecycle: z.enum(["active", "deprecated", "retired", "unknown"]),
980
- validation: z.enum(["verified", "unverified"]),
981
- 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),
982
1239
  reason: text.optional(),
983
1240
  replacement: modelId.optional(),
984
- retirementDate: z.iso.date().optional(),
985
- limits: z.object({
1241
+ retirementDate: z2.iso.date().optional(),
1242
+ limits: z2.object({
986
1243
  contextWindowTokens: tokenLimit,
987
- contextWindowType: z.enum(["combined", "input"]),
1244
+ contextWindowType: z2.enum(["combined", "input"]),
988
1245
  maxOutputTokens: tokenLimit,
989
1246
  maxInputTokens: tokenLimit.optional(),
990
1247
  evidence
991
1248
  }).strict().optional(),
992
- pricing: z.object({
993
- currency: z.literal("USD"),
1249
+ pricing: z2.object({
1250
+ currency: z2.literal("USD"),
994
1251
  inputPerMillionTokens: price,
995
1252
  outputPerMillionTokens: price,
996
1253
  cachedInputPerMillionTokens: price.optional(),
@@ -998,8 +1255,8 @@ var catalogModelSchema = z.object({
998
1255
  scope: text,
999
1256
  evidence
1000
1257
  }).strict().optional(),
1001
- compaction: z.object({
1002
- suitability: z.enum(["candidate", "evaluated", "unsuitable", "unknown"]),
1258
+ compaction: z2.object({
1259
+ suitability: z2.enum(["candidate", "evaluated", "unsuitable", "unknown"]),
1003
1260
  reason: text,
1004
1261
  evidence
1005
1262
  }).strict().optional()
@@ -1013,17 +1270,17 @@ var catalogModelSchema = z.object({
1013
1270
  ctx.addIssue({ code: "custom", message: "maxOutputTokens exceeds combined context window" });
1014
1271
  }
1015
1272
  });
1016
- var modelCatalogSchema = z.object({
1017
- schemaVersion: z.literal(1),
1018
- revision: z.string().min(1).max(80).regex(/^[a-zA-Z0-9._-]+$/),
1019
- providers: z.array(z.object({
1020
- 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"]),
1021
1278
  defaultModel: modelId,
1022
- models: z.array(catalogModelSchema).min(1).max(500)
1023
- }).strict()).length(4)
1279
+ models: z2.array(catalogModelSchema).min(1).max(500)
1280
+ }).strict()).length(6)
1024
1281
  }).strict().superRefine((catalog, ctx) => {
1025
1282
  const invalid = (message) => ctx.addIssue({ code: "custom", message });
1026
- if (new Set(catalog.providers.map((p) => p.id)).size !== 4)
1283
+ if (new Set(catalog.providers.map((p) => p.id)).size !== 6)
1027
1284
  invalid("Duplicate providers");
1028
1285
  for (const provider of catalog.providers) {
1029
1286
  const ids = new Set(provider.models.map((m) => m.id));
@@ -1075,12 +1332,13 @@ function modelDescription(model) {
1075
1332
  // src/providers/providers.ts
1076
1333
  import { createHash } from "node:crypto";
1077
1334
  import {
1078
- wrapLanguageModel as wrapLanguageModel3
1335
+ wrapLanguageModel as wrapLanguageModel5
1079
1336
  } from "@zhivex-ai/core";
1337
+ import { createAnthropic } from "@zhivex-ai/anthropic";
1080
1338
  import { createGemini } from "@zhivex-ai/gemini";
1081
1339
  import { createOpenAI } from "@zhivex-ai/openai";
1082
1340
  import { createQwen } from "@zhivex-ai/qwen";
1083
- var PROVIDERS = ["meta", "qwen", "openai", "gemini"];
1341
+ var PROVIDERS = ["meta", "qwen", "openai", "gemini", "anthropic", "vertex"];
1084
1342
  var HARNESS_PROVIDER_CAPABILITIES = [
1085
1343
  "streaming",
1086
1344
  "tool-calling",
@@ -1299,13 +1557,13 @@ var createProviderRegistry = (registrations) => {
1299
1557
  const credentials = Object.freeze(registration.descriptor.credentialNames.map((name) => Object.freeze({ name, present: Boolean(env[name]?.trim()) })));
1300
1558
  return Object.freeze({
1301
1559
  ...registration.descriptor,
1302
- 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),
1303
1561
  credentials,
1304
1562
  configuration: providerConfiguration(registration.diagnostics, env)
1305
1563
  });
1306
1564
  })),
1307
1565
  transportFingerprint: (env = process.env) => {
1308
- 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) => {
1309
1567
  const names = [
1310
1568
  registration.diagnostics.endpointEnvironmentVariable,
1311
1569
  ...(registration.diagnostics.presence ?? []).map((entry) => entry.environmentVariable),
@@ -1399,12 +1657,12 @@ var normalizeStreamToolCallIds = async function* (model, input, events) {
1399
1657
  };
1400
1658
  }
1401
1659
  };
1402
- var withQwenDurableToolCallIds = (model) => wrapLanguageModel3(model, [{
1660
+ var withQwenDurableToolCallIds = (model) => wrapLanguageModel5(model, [{
1403
1661
  name: "harness-qwen-durable-tool-call-ids",
1404
1662
  wrapGenerate: async ({ input }, next) => normalizeGenerateToolCallIds(model, input, await next()),
1405
1663
  wrapStream: async ({ input }, next) => normalizeStreamToolCallIds(model, input, await next())
1406
1664
  }]);
1407
- var withOpenAIToolResultEnvelopes = (model) => wrapLanguageModel3(model, [{
1665
+ var withOpenAIToolResultEnvelopes = (model) => wrapLanguageModel5(model, [{
1408
1666
  name: "harness-openai-tool-result-envelopes-v1",
1409
1667
  async wrapGenerate({ input }, next) {
1410
1668
  input.toolResultFormat = "envelope";
@@ -1415,7 +1673,7 @@ var withOpenAIToolResultEnvelopes = (model) => wrapLanguageModel3(model, [{
1415
1673
  return next();
1416
1674
  }
1417
1675
  }]);
1418
- var withMetaResponses = (model) => wrapLanguageModel3(model, [{
1676
+ var withMetaResponses = (model) => wrapLanguageModel5(model, [{
1419
1677
  name: "harness-meta-responses-v1",
1420
1678
  async wrapGenerate({ input }, next) {
1421
1679
  input.providerOptions = { ...input.providerOptions, apiMode: "responses" };
@@ -1435,6 +1693,41 @@ var withMetaResponses = (model) => wrapLanguageModel3(model, [{
1435
1693
  }
1436
1694
  }]);
1437
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
+ },
1438
1731
  {
1439
1732
  descriptor: {
1440
1733
  id: "meta",
@@ -1525,7 +1818,7 @@ var DEFAULT_PROVIDER_REGISTRY = createProviderRegistry(BUILTIN_PROVIDER_REGISTRA
1525
1818
  var PROVIDER_DESCRIPTORS = DEFAULT_PROVIDER_REGISTRY.descriptors;
1526
1819
 
1527
1820
  // src/providers/reasoning.ts
1528
- 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"]);
1529
1822
  var supportedReasoningEfforts = (capabilities) => ["default", ...capabilities.reasoning ? capabilities.reasoningEfforts ?? [] : []];
1530
1823
  function modelReasoningEfforts(provider, model) {
1531
1824
  if (!DEFAULT_PROVIDER_REGISTRY.has(provider))
@@ -1539,7 +1832,7 @@ function withReasoningEffort(model, value) {
1539
1832
  return model;
1540
1833
  if (!supportedReasoningEfforts(model.capabilities).includes(value))
1541
1834
  throw new Error(`Reasoning effort ${value} is not declared for ${model.provider}/${model.modelId}. Use default or a supported level.`);
1542
- return wrapLanguageModel4(model, [{
1835
+ return wrapLanguageModel6(model, [{
1543
1836
  name: `harness-reasoning-${value}`,
1544
1837
  async wrapGenerate(context, next) {
1545
1838
  context.input.reasoning = { ...context.input.reasoning, effort: value };
@@ -1627,18 +1920,6 @@ class HarnessProviderError extends HarnessError {
1627
1920
  this.name = "HarnessProviderError";
1628
1921
  }
1629
1922
  }
1630
-
1631
- class HarnessApprovalError extends HarnessError {
1632
- constructor(message, options = {}) {
1633
- super(message, {
1634
- code: "APPROVAL_REQUIRED",
1635
- category: "approval",
1636
- ...options.cause === undefined ? {} : { cause: options.cause }
1637
- });
1638
- this.name = "HarnessApprovalError";
1639
- }
1640
- }
1641
-
1642
1923
  class HarnessExecutionError extends HarnessError {
1643
1924
  constructor(message, options = {}) {
1644
1925
  super(message, {
@@ -2066,4 +2347,4 @@ var createProviderModel = (config, env = process.env, registry = DEFAULT_PROVIDE
2066
2347
  }
2067
2348
  };
2068
2349
  var providerAvailability = (env = process.env, registry = DEFAULT_PROVIDER_REGISTRY) => registry.availability(env);
2069
- export { modelCatalogSchema, bundledModelCatalog, catalogModels, modelDescription, PROVIDERS, createProviderRegistry, BUILTIN_PROVIDER_REGISTRATIONS, DEFAULT_PROVIDER_REGISTRY, PROVIDER_DESCRIPTORS, reasoningEffortSchema, modelReasoningEfforts, withReasoningEffort, HARNESS_ERROR_CODES, HARNESS_ERROR_SCHEMA_VERSION, HarnessError, HarnessConfigError, HarnessWorkspaceError, HarnessStateConflictError, HarnessProviderError, HarnessApprovalError, HarnessExecutionError, harnessErrorDocument, normalizeHarnessError, 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 };