@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.
- package/CHANGELOG.md +64 -0
- package/README.md +9 -10
- package/contracts/engine-api.json +2921 -0
- package/contracts/public-api.json +267 -1
- package/contracts/stable-api-signatures.json +43 -43
- package/dist/acp-cli.js +137 -15002
- 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-options.d.ts +2 -41
- package/dist/cli/cli-profiles.d.ts +4 -2
- package/dist/cli/cli-stream.d.ts +2 -167
- 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/run-document.d.ts +2 -91
- package/dist/cli/terminal/terminal-continuation.d.ts +2 -3
- package/dist/cli/terminal/terminal-ui.d.ts +4 -0
- package/dist/{cli-entry-c2f58zj2.js → cli-entry-ae7x44d4.js} +14969 -10731
- package/dist/{cli-entry-427869g9.js → cli-entry-d5788aay.js} +388 -47
- package/dist/cli-entry-ev76ezcd.js +656 -0
- package/dist/{cli-3jmy4h5h.js → cli-t7hrhayq.js} +918 -2223
- 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/continuation.d.ts +3 -0
- 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/run-document.d.ts +91 -0
- package/dist/client/service-events.d.ts +4 -0
- package/dist/client/stream.d.ts +167 -0
- package/dist/compat/cli-options.d.ts +53 -0
- package/dist/compat/code-support.d.ts +22 -0
- package/dist/compat/code-support.js +74 -0
- package/dist/{config-1k9t4jhh.js → config-c002f06f.js} +1 -1
- package/dist/config-j3jga5wh.js +61 -0
- 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 +6 -0
- package/dist/engine/acp.js +205 -0
- package/dist/engine/client.d.ts +6 -0
- package/dist/engine/client.js +28 -0
- 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 +73 -0
- package/dist/engine/index.js +977 -0
- 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 +7 -0
- package/dist/engine/protocol.js +182 -0
- package/dist/engine/service.d.ts +5 -0
- package/dist/engine/service.js +28 -0
- 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 +3368 -1304
- package/dist/index-1bx83sw4.js +4 -0
- package/dist/index-2gz7jv7g.js +549 -0
- package/dist/{cli-entry-b1mfvmxe.js → index-2jrdcj6b.js} +72 -115
- package/dist/index-3ah1f369.js +356 -0
- package/dist/index-42gp2hy8.js +1555 -0
- package/dist/index-4jw3tvy8.js +301 -0
- package/dist/index-8705zxpr.js +145 -0
- package/dist/index-8vm2m34s.js +2080 -0
- package/dist/index-8zzhggxv.js +477 -0
- package/dist/index-a97bezbz.js +1073 -0
- package/dist/index-gq9xagx2.js +1343 -0
- package/dist/index-h0mqx2ed.js +1373 -0
- package/dist/index-jgrx804e.js +5589 -0
- package/dist/index-qfpz5y2v.js +174 -0
- package/dist/index-t60rva31.js +1004 -0
- 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-z4e8d0ph.js +1768 -0
- package/dist/index.js +251 -18649
- 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 +19 -14504
- package/dist/{service-client-cli-yx56n0hc.js → service-client-cli-kns4mf57.js} +307 -248
- package/dist/verify-historical-migrations.js +3314 -1251
- 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 +93 -0
- package/docs/ENGINE_API.md +319 -0
- 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 +6 -0
- package/docs/STABILITY.md +9 -1
- 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 +64 -1
- package/evaluations/task-acceptance-routes.json +7 -0
- package/examples/README.md +1 -1
- package/package.json +74 -12
- package/dist/cli-entry-64pdp3k5.js +0 -17
|
@@ -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,8 @@ 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";
|
|
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
|
|
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
|
-
|
|
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-
|
|
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 =
|
|
916
|
-
var text =
|
|
917
|
-
var evidence =
|
|
918
|
-
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) => {
|
|
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:
|
|
1227
|
+
checkedAt: z2.iso.date()
|
|
923
1228
|
}).strict();
|
|
924
|
-
var tokenLimit =
|
|
925
|
-
var price =
|
|
926
|
-
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({
|
|
927
1232
|
id: modelId,
|
|
928
1233
|
name: text,
|
|
929
|
-
group:
|
|
930
|
-
order:
|
|
931
|
-
lifecycle:
|
|
932
|
-
validation:
|
|
933
|
-
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),
|
|
934
1239
|
reason: text.optional(),
|
|
935
1240
|
replacement: modelId.optional(),
|
|
936
|
-
retirementDate:
|
|
937
|
-
limits:
|
|
1241
|
+
retirementDate: z2.iso.date().optional(),
|
|
1242
|
+
limits: z2.object({
|
|
938
1243
|
contextWindowTokens: tokenLimit,
|
|
939
|
-
contextWindowType:
|
|
1244
|
+
contextWindowType: z2.enum(["combined", "input"]),
|
|
940
1245
|
maxOutputTokens: tokenLimit,
|
|
941
1246
|
maxInputTokens: tokenLimit.optional(),
|
|
942
1247
|
evidence
|
|
943
1248
|
}).strict().optional(),
|
|
944
|
-
pricing:
|
|
945
|
-
currency:
|
|
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:
|
|
954
|
-
suitability:
|
|
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 =
|
|
969
|
-
schemaVersion:
|
|
970
|
-
revision:
|
|
971
|
-
providers:
|
|
972
|
-
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"]),
|
|
973
1278
|
defaultModel: modelId,
|
|
974
|
-
models:
|
|
975
|
-
}).strict()).length(
|
|
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 !==
|
|
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
|
|
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) =>
|
|
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) =>
|
|
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) =>
|
|
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 =
|
|
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
|
|
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 };
|