@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.
- package/CHANGELOG.md +53 -0
- package/README.md +12 -10
- package/SECURITY.md +1 -1
- package/SUPPORT.md +4 -4
- package/contracts/engine-api.json +334 -0
- package/contracts/public-api.json +267 -1
- package/contracts/stable-api-signatures.json +43 -43
- package/dist/acp-cli.js +54 -18
- package/dist/approvals/approval-history.d.ts +22 -0
- package/dist/approvals/explicit-review.d.ts +24 -0
- package/dist/approvals/host-policy-identity.d.ts +3 -0
- package/dist/cli/arguments.d.ts +6 -2
- package/dist/cli/checkpoints.d.ts +230 -0
- package/dist/cli/cli-profiles.d.ts +4 -2
- package/dist/cli/governance-report.d.ts +5 -0
- package/dist/cli/policy-decisions.d.ts +9 -0
- package/dist/cli/policy.d.ts +5 -0
- package/dist/cli/presentation.d.ts +3 -1
- package/dist/cli/terminal/terminal-ui.d.ts +4 -0
- package/dist/{cli-entry-xmf48p6a.js → cli-entry-1gfg3brj.js} +14921 -10692
- package/dist/cli-entry-bx3vjw7h.js +656 -0
- package/dist/{index-fvca1xea.js → cli-entry-d5788aay.js} +339 -58
- package/dist/{cli-qgwvtk0w.js → cli-etsmtst3.js} +918 -2222
- package/dist/cli.js +3 -5
- package/dist/client/acp-mcp-admission.d.ts +32 -0
- package/dist/client/acp-mcp-host.d.ts +19 -0
- package/dist/client/acp-mcp-session.d.ts +14 -0
- package/dist/client/acp-stdio.d.ts +2 -0
- package/dist/client/acp.d.ts +4 -1
- package/dist/client/adapter.d.ts +13 -1
- package/dist/client/json-contracts.d.ts +107 -4
- package/dist/client/local-service.d.ts +2 -0
- package/dist/client/protocol.d.ts +127 -1
- package/dist/client/service-events.d.ts +4 -0
- package/dist/compat/cli-options.d.ts +13 -1
- package/dist/compat/code-support.js +23 -87
- package/dist/{config-q32jm1e6.js → config-c002f06f.js} +1 -1
- package/dist/{config-6gtpxvjv.js → config-j3jga5wh.js} +3 -1
- package/dist/context/adaptive-compaction.d.ts +1 -0
- package/dist/context/compaction.d.ts +1 -1
- package/dist/context/request-measurements.d.ts +17 -0
- package/dist/context/request-projection.d.ts +10 -0
- package/dist/context/task-memory.d.ts +1 -0
- package/dist/engine/acp.d.ts +2 -0
- package/dist/engine/acp.js +197 -1
- package/dist/engine/client.js +11 -4
- package/dist/engine/desktop-providers-v1.d.ts +4 -0
- package/dist/engine/desktop-providers-v1.js +18 -0
- package/dist/engine/desktop-state-v1.d.ts +10 -0
- package/dist/engine/desktop-state-v1.js +168 -0
- package/dist/engine/index.d.ts +12 -0
- package/dist/engine/index.js +571 -71
- package/dist/engine/mcp-stdio-v1.d.ts +11 -0
- package/dist/engine/mcp-stdio-v1.js +108 -0
- package/dist/engine/models.d.ts +3 -0
- package/dist/engine/models.js +894 -0
- package/dist/engine/protocol.d.ts +1 -0
- package/dist/engine/protocol.js +24 -0
- package/dist/engine/service.js +12 -5
- package/dist/execution/acceptance-snapshot.d.ts +2 -0
- package/dist/execution/execution-environment.d.ts +10 -0
- package/dist/execution/mcp-oci-channel.d.ts +11 -0
- package/dist/execution/mcp-oci-server.d.ts +38 -0
- package/dist/execution/mcp-oci-workspace.d.ts +23 -0
- package/dist/execution/mcp-resource-recovery.d.ts +19 -0
- package/dist/execution/mcp-workspace-snapshot.d.ts +20 -0
- package/dist/hostile-repository-demo.js +3169 -1163
- package/dist/{index-f4sb0e2q.js → index-2jrdcj6b.js} +17 -2
- package/dist/{index-77h9qr5h.js → index-3ah1f369.js} +40 -10
- package/dist/{index-pgqz45fj.js → index-42gp2hy8.js} +197 -1091
- package/dist/{index-41fkzt91.js → index-4jw3tvy8.js} +10 -2
- package/dist/index-6m08wvab.js +1768 -0
- package/dist/index-8705zxpr.js +145 -0
- package/dist/{index-d0wrghff.js → index-8vm2m34s.js} +225 -1416
- package/dist/index-8zzhggxv.js +477 -0
- package/dist/index-a97bezbz.js +1073 -0
- package/dist/index-azmwjp95.js +1004 -0
- package/dist/{cli-entry-0mmeag20.js → index-gq9xagx2.js} +122 -836
- package/dist/index-h0mqx2ed.js +1373 -0
- package/dist/index-hnaxfpb5.js +5589 -0
- package/dist/{index-2aymdsqc.js → index-qfpz5y2v.js} +24 -0
- package/dist/{index-kfgt9yqq.js → index-w2sj0wkw.js} +33 -10
- package/dist/index-wg1sd3at.js +80 -0
- package/dist/index-xqxeypt5.js +888 -0
- package/dist/index-yb239ghk.js +961 -0
- package/dist/index-z0qxmkm2.js +3389 -0
- package/dist/index.js +85 -72
- package/dist/integrations/mcp-host-session.d.ts +26 -0
- package/dist/integrations/mcp-stdio-admission.d.ts +54 -0
- package/dist/integrations/mcp-stdio-client.d.ts +44 -0
- package/dist/integrations/mcp-stdio-framing.d.ts +18 -0
- package/dist/integrations/mcp-stdio-launch.d.ts +20 -0
- package/dist/integrations/mcp-stdio-session.d.ts +7 -0
- package/dist/integrations/mcp-stdio-tools.d.ts +12 -0
- package/dist/internal/desktop/catalog.d.ts +2 -0
- package/dist/internal/desktop/persistence.d.ts +2 -3
- package/dist/internal/desktop/providers.d.ts +1 -0
- package/dist/models/catalog.d.ts +2 -0
- package/dist/persistence/governance-context.d.ts +126 -0
- package/dist/persistence/governance-report.d.ts +299 -0
- package/dist/persistence/host-database-backup.d.ts +28 -0
- package/dist/persistence/mcp-execution-journal.d.ts +19 -0
- package/dist/persistence/mcp-reconciliation.d.ts +33 -0
- package/dist/persistence/mcp-resource-journal.d.ts +54 -0
- package/dist/persistence/workspace-checkpoints.d.ts +138 -0
- package/dist/providers/anthropic-continuation.d.ts +5 -0
- package/dist/providers/providers.d.ts +1 -1
- package/dist/providers/vertex-auth.d.ts +27 -0
- package/dist/runtime/delegation-contracts.d.ts +9 -0
- package/dist/runtime/delegation-correction.d.ts +9 -0
- package/dist/runtime/delegation-result.d.ts +73 -0
- package/dist/runtime/error-diagnostics.d.ts +86 -0
- package/dist/runtime/harness.d.ts +11 -1
- package/dist/runtime/policy-decisions.d.ts +66 -0
- package/dist/runtime/policy-inspection.d.ts +52 -0
- package/dist/runtime/provider-diagnostics.d.ts +1 -0
- package/dist/runtime/runtime-instructions.d.ts +8 -0
- package/dist/runtime/task-acceptance-checks.d.ts +103 -0
- package/dist/runtime/task-acceptance-delivery.d.ts +107 -0
- package/dist/runtime/task-acceptance-host.d.ts +20 -0
- package/dist/runtime/task-acceptance-record.d.ts +107 -0
- package/dist/runtime/task-acceptance-validation.d.ts +25 -0
- package/dist/runtime/task-acceptance.d.ts +47 -0
- package/dist/runtime/time-to-safe-fix.d.ts +83 -0
- package/dist/runtime/tool-policy-file.d.ts +23 -0
- package/dist/runtime/tool-policy-paths.d.ts +5 -0
- package/dist/runtime/tool-policy.d.ts +6 -0
- package/dist/service-cli.js +14 -7
- package/dist/{service-client-cli-gs78wrxe.js → service-client-cli-3365rfav.js} +307 -248
- package/dist/verify-historical-migrations.js +3134 -1129
- package/dist/workspace/path-policy.d.ts +4 -0
- package/dist/zhx.js +3 -5
- package/docs/ACP.md +14 -2
- package/docs/ANTHROPIC.md +33 -0
- package/docs/CLI.md +132 -0
- package/docs/CLIENT_PROTOCOL.md +45 -0
- package/docs/CODE_RELEASE.md +35 -18
- package/docs/ENGINE_API.md +216 -7
- package/docs/EXTENSIBILITY.md +46 -3
- package/docs/FIRST_USE.md +6 -6
- package/docs/LOCAL_SERVICE.md +13 -0
- package/docs/MCP_STDIO.md +20 -0
- package/docs/README.md +1 -0
- package/docs/STABILITY.md +4 -2
- package/docs/SUPPORT_MATRIX.md +1 -1
- package/docs/TOOL_POLICY.md +81 -0
- package/docs/VERTEX.md +50 -0
- package/docs/adr/0002-isolated-mcp-stdio.md +135 -0
- package/docs/fixtures/mcp-stdio-contract-v1.json +189 -0
- package/docs/support-matrix.json +2 -0
- package/evaluations/representative-assembly-matrix.json +46 -1
- package/evaluations/task-acceptance-routes.json +7 -0
- package/examples/README.md +3 -3
- package/package.json +43 -12
- package/dist/cli-entry-64pdp3k5.js +0 -17
- package/dist/cli-entry-7h9savv5.js +0 -375
- package/dist/index-5wjwe91x.js +0 -9434
|
@@ -1,9 +1,199 @@
|
|
|
1
1
|
// src/providers/reasoning.ts
|
|
2
|
-
import { z as
|
|
3
|
-
import { wrapLanguageModel as
|
|
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 =
|
|
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
|
|
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
|
|
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-
|
|
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 =
|
|
964
|
-
var text =
|
|
965
|
-
var evidence =
|
|
966
|
-
sourceUrl:
|
|
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:
|
|
1227
|
+
checkedAt: z2.iso.date()
|
|
971
1228
|
}).strict();
|
|
972
|
-
var tokenLimit =
|
|
973
|
-
var price =
|
|
974
|
-
var catalogModelSchema =
|
|
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:
|
|
978
|
-
order:
|
|
979
|
-
lifecycle:
|
|
980
|
-
validation:
|
|
981
|
-
capabilities:
|
|
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:
|
|
985
|
-
limits:
|
|
1241
|
+
retirementDate: z2.iso.date().optional(),
|
|
1242
|
+
limits: z2.object({
|
|
986
1243
|
contextWindowTokens: tokenLimit,
|
|
987
|
-
contextWindowType:
|
|
1244
|
+
contextWindowType: z2.enum(["combined", "input"]),
|
|
988
1245
|
maxOutputTokens: tokenLimit,
|
|
989
1246
|
maxInputTokens: tokenLimit.optional(),
|
|
990
1247
|
evidence
|
|
991
1248
|
}).strict().optional(),
|
|
992
|
-
pricing:
|
|
993
|
-
currency:
|
|
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:
|
|
1002
|
-
suitability:
|
|
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 =
|
|
1017
|
-
schemaVersion:
|
|
1018
|
-
revision:
|
|
1019
|
-
providers:
|
|
1020
|
-
id:
|
|
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:
|
|
1023
|
-
}).strict()).length(
|
|
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 !==
|
|
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
|
|
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) =>
|
|
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) =>
|
|
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) =>
|
|
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 =
|
|
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
|
|
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 {
|
|
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 };
|