@zhivex-ai/harness 1.4.0-rc.8 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -0
- package/README.md +124 -72
- package/SECURITY.md +1 -1
- package/SUPPORT.md +2 -2
- package/dist/acp-cli.js +13 -12
- package/dist/{cli-3bzvq594.js → cli-2h37qyvg.js} +4 -4
- package/dist/{cli-entry-yqwa1943.js → cli-entry-20w6nh0k.js} +321 -16
- package/dist/{cli-entry-25xefnws.js → cli-entry-4ngptr62.js} +3 -3
- package/dist/{cli-entry-qav71mxw.js → cli-entry-w0hterjs.js} +1 -1
- package/dist/cli.js +2 -2
- package/dist/compat/code-support.js +8 -7
- package/dist/{config-pwbnze4g.js → config-j9624t6t.js} +1 -1
- package/dist/{config-depqpsae.js → config-qt69hkqj.js} +4 -3
- package/dist/engine/acp.js +12 -11
- package/dist/engine/client.js +11 -10
- package/dist/engine/desktop-providers-v1.js +2 -1
- package/dist/engine/desktop-state-v1.js +8 -7
- package/dist/engine/index.js +15 -14
- package/dist/engine/mcp-stdio-v1.js +7 -6
- package/dist/engine/protocol.js +12 -0
- package/dist/engine/service.js +12 -11
- package/dist/hostile-repository-demo.js +322 -17
- package/dist/{index-1k248k0w.js → index-5jhgatga.js} +5 -5
- package/dist/{index-pcn2bk8j.js → index-61gthdz6.js} +1 -1
- package/dist/{index-sbzvrpm7.js → index-6dft2vev.js} +2 -2
- package/dist/{index-09zphhwt.js → index-8zjmnyw5.js} +2 -2
- package/dist/{index-txrqqd2r.js → index-937cb7y8.js} +6 -6
- package/dist/{index-jdb1q8yn.js → index-bpc596v3.js} +15 -10
- package/dist/index-fm84men1.js +239 -0
- package/dist/{index-zmx264xy.js → index-m34q25jj.js} +2 -2
- package/dist/index-m49jx72n.js +220 -0
- package/dist/{index-9v72fpya.js → index-m82cfspw.js} +16 -10
- package/dist/{index-ngg2168h.js → index-nmjdwd4p.js} +1 -1
- package/dist/{index-w9pjt7td.js → index-pdmevfxv.js} +3 -3
- package/dist/{index-nqhnh1hz.js → index-pp474137.js} +5 -5
- package/dist/{index-vga76vmb.js → index-rkbf7dqg.js} +2 -2
- package/dist/{index-fny13znr.js → index-s2k2edts.js} +3 -3
- package/dist/{index-7y6b4yjx.js → index-tfzta544.js} +4 -4
- package/dist/index.js +15 -14
- package/dist/providers/vertex-auth.d.ts +5 -1
- package/dist/runtime/error-diagnostics.d.ts +8 -0
- package/dist/runtime/provider-transient.d.ts +33 -0
- package/dist/runtime/time-to-safe-fix.d.ts +8 -0
- package/dist/service-cli.js +12 -11
- package/dist/{service-client-cli-ra3yzvjg.js → service-client-cli-fn54ev6w.js} +3 -3
- package/dist/verify-historical-migrations.js +322 -17
- package/dist/zhx.js +2 -2
- package/docs/CLI.md +1 -1
- package/docs/CODE_RELEASE.md +38 -1
- package/docs/FIRST_USE.md +6 -6
- package/docs/PROJECT_MEMORY.md +1 -1
- package/evaluations/representative-assembly-matrix.json +10 -1
- package/examples/README.md +5 -5
- package/package.json +1 -1
- package/dist/index-8705zxpr.js +0 -145
package/dist/engine/index.js
CHANGED
|
@@ -62,7 +62,7 @@ import {
|
|
|
62
62
|
timeToSafeFixLatencyStatistics,
|
|
63
63
|
timeToSafeFixTaskSchema,
|
|
64
64
|
verifyChangeEnvelope
|
|
65
|
-
} from "../index-
|
|
65
|
+
} from "../index-m82cfspw.js";
|
|
66
66
|
import {
|
|
67
67
|
HARNESS_STATE_BACKUP_MAX_BYTES,
|
|
68
68
|
HARNESS_STATE_BACKUP_SCHEMA_VERSION,
|
|
@@ -73,7 +73,7 @@ import {
|
|
|
73
73
|
inspectHarnessState,
|
|
74
74
|
readHarnessStateBackup,
|
|
75
75
|
stateBackupBundleSchema
|
|
76
|
-
} from "../index-
|
|
76
|
+
} from "../index-tfzta544.js";
|
|
77
77
|
import {
|
|
78
78
|
CLI_COMMAND_OPTION_CONTRACTS,
|
|
79
79
|
CLI_OPTION_DEFINITIONS,
|
|
@@ -83,7 +83,7 @@ import {
|
|
|
83
83
|
resolveHarnessModelRoutes,
|
|
84
84
|
serializeHarnessModelRoutes,
|
|
85
85
|
validateCliCommandOptions
|
|
86
|
-
} from "../index-
|
|
86
|
+
} from "../index-61gthdz6.js";
|
|
87
87
|
import {
|
|
88
88
|
harnessLocalCredentialsSchema,
|
|
89
89
|
openHarnessActivityStore,
|
|
@@ -91,17 +91,17 @@ import {
|
|
|
91
91
|
recoverHarnessLocalService,
|
|
92
92
|
requestHarnessLocalService,
|
|
93
93
|
startHarnessLocalService
|
|
94
|
-
} from "../index-
|
|
94
|
+
} from "../index-5jhgatga.js";
|
|
95
95
|
import {
|
|
96
96
|
createAcpConnection,
|
|
97
97
|
serveAcpStdio
|
|
98
98
|
} from "../index-3ah1f369.js";
|
|
99
99
|
import {
|
|
100
100
|
createHarnessClientAdapter
|
|
101
|
-
} from "../index-
|
|
101
|
+
} from "../index-937cb7y8.js";
|
|
102
102
|
import {
|
|
103
103
|
openWorkspaceCheckpointStore
|
|
104
|
-
} from "../index-
|
|
104
|
+
} from "../index-6dft2vev.js";
|
|
105
105
|
import {
|
|
106
106
|
APPROVAL_HISTORY_KEY,
|
|
107
107
|
DEFAULT_HARNESS_CONTEXT_MANIFEST,
|
|
@@ -149,7 +149,7 @@ import {
|
|
|
149
149
|
runHarness,
|
|
150
150
|
runHarnessReviewGroup,
|
|
151
151
|
selectHarnessModel
|
|
152
|
-
} from "../index-
|
|
152
|
+
} from "../index-pp474137.js";
|
|
153
153
|
import {
|
|
154
154
|
HARNESS_OPERATIONS_SCHEMA_VERSION,
|
|
155
155
|
HARNESS_PROJECT_MEMORY_LIMITS,
|
|
@@ -177,7 +177,7 @@ import {
|
|
|
177
177
|
readTaskAcceptanceLedger,
|
|
178
178
|
taskAcceptanceContractSchema,
|
|
179
179
|
validateStateDirectory
|
|
180
|
-
} from "../index-
|
|
180
|
+
} from "../index-s2k2edts.js";
|
|
181
181
|
import {
|
|
182
182
|
BUN_ENGINE_RANGE,
|
|
183
183
|
HARNESS_MCP_CONFIG_SCHEMA_VERSION,
|
|
@@ -188,7 +188,7 @@ import {
|
|
|
188
188
|
createHttpMcpClient,
|
|
189
189
|
loadHarnessMcpConfiguration,
|
|
190
190
|
normalizeHarnessMcpConfiguration
|
|
191
|
-
} from "../index-
|
|
191
|
+
} from "../index-pdmevfxv.js";
|
|
192
192
|
import {
|
|
193
193
|
CliOciRuntimeAdapter,
|
|
194
194
|
EDIT_CONTRACT_SCHEMA_VERSION,
|
|
@@ -222,7 +222,7 @@ import {
|
|
|
222
222
|
taskCheckReceiptSchema,
|
|
223
223
|
validateEditProposal,
|
|
224
224
|
workspaceFilePathSchema
|
|
225
|
-
} from "../index-
|
|
225
|
+
} from "../index-m34q25jj.js";
|
|
226
226
|
import {
|
|
227
227
|
BUILTIN_PROVIDER_REGISTRATIONS,
|
|
228
228
|
DEFAULT_ALLOWED_CHECKS,
|
|
@@ -247,8 +247,8 @@ import {
|
|
|
247
247
|
providerAvailability,
|
|
248
248
|
providerDescriptor,
|
|
249
249
|
resolveHarnessConfig
|
|
250
|
-
} from "../index-
|
|
251
|
-
import"../index-
|
|
250
|
+
} from "../index-8zjmnyw5.js";
|
|
251
|
+
import"../index-m49jx72n.js";
|
|
252
252
|
import"../index-xqxeypt5.js";
|
|
253
253
|
import {
|
|
254
254
|
CLI_EVENT_SCHEMA_VERSION,
|
|
@@ -260,7 +260,7 @@ import {
|
|
|
260
260
|
serializeStreamResult,
|
|
261
261
|
streamEventDocument,
|
|
262
262
|
streamResultDocument
|
|
263
|
-
} from "../index-
|
|
263
|
+
} from "../index-nmjdwd4p.js";
|
|
264
264
|
import {
|
|
265
265
|
HARNESS_ERROR_CODES,
|
|
266
266
|
HARNESS_ERROR_SCHEMA_VERSION,
|
|
@@ -273,7 +273,8 @@ import {
|
|
|
273
273
|
HarnessWorkspaceError,
|
|
274
274
|
harnessErrorDocument,
|
|
275
275
|
normalizeHarnessError
|
|
276
|
-
} from "../index-
|
|
276
|
+
} from "../index-bpc596v3.js";
|
|
277
|
+
import"../index-fm84men1.js";
|
|
277
278
|
import"../index-1bx83sw4.js";
|
|
278
279
|
// src/persistence/project-memory-command.ts
|
|
279
280
|
var HARNESS_MEMORY_COMMANDS = ["remember", "list", "read", "update", "forget", "suggest", "accept", "clear", "enable", "disable", "context"];
|
|
@@ -8,13 +8,14 @@ import {
|
|
|
8
8
|
mcpResourcePlanSchema,
|
|
9
9
|
prepareMcpWorkspaceSnapshot,
|
|
10
10
|
recoverDockerMcpResources
|
|
11
|
-
} from "../index-
|
|
12
|
-
import"../index-
|
|
13
|
-
import"../index-
|
|
14
|
-
import"../index-
|
|
15
|
-
import"../index-
|
|
11
|
+
} from "../index-rkbf7dqg.js";
|
|
12
|
+
import"../index-pdmevfxv.js";
|
|
13
|
+
import"../index-m34q25jj.js";
|
|
14
|
+
import"../index-8zjmnyw5.js";
|
|
15
|
+
import"../index-m49jx72n.js";
|
|
16
16
|
import"../index-xqxeypt5.js";
|
|
17
|
-
import"../index-
|
|
17
|
+
import"../index-bpc596v3.js";
|
|
18
|
+
import"../index-fm84men1.js";
|
|
18
19
|
import"../index-1bx83sw4.js";
|
|
19
20
|
// src/persistence/mcp-reconciliation.ts
|
|
20
21
|
import { z } from "zod";
|
package/dist/engine/protocol.js
CHANGED
|
@@ -54,6 +54,18 @@ var harnessClientRequestSchema = z.object({
|
|
|
54
54
|
connectionId: id,
|
|
55
55
|
command: harnessClientCommandSchema
|
|
56
56
|
}).strict();
|
|
57
|
+
// src/runtime/provider-diagnostics.ts
|
|
58
|
+
import { z as z2 } from "zod";
|
|
59
|
+
var providerDiagnosticSchema = z2.strictObject({
|
|
60
|
+
reason: z2.enum(["previous_response_unavailable", "context_length_exceeded", "authentication", "payment_required", "permission", "rate_limit", "model_unavailable", "invalid_request", "server_error", "unknown"]),
|
|
61
|
+
parameter: z2.enum(["previous_response_id", "input", "messages", "tools", "model", "max_output_tokens", "max_tokens", "temperature", "other", "none"]),
|
|
62
|
+
bodyState: z2.enum(["parsed", "malformed", "too_large", "unavailable", "read_timeout"])
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
// src/runtime/provider-transient.ts
|
|
66
|
+
var SYMBOLIC = new Set(["ABORTED", "RESOURCE_EXHAUSTED", "UNAVAILABLE", "DEADLINE_EXCEEDED", "INTERNAL"]);
|
|
67
|
+
var STREAM_RESET_CODES = new Set(["ECONNRESET", "ECONNABORTED", "EPIPE", "ETIMEDOUT", "UND_ERR_SOCKET", "ERR_STREAM_PREMATURE_CLOSE"]);
|
|
68
|
+
|
|
57
69
|
// src/runtime/errors.ts
|
|
58
70
|
var providerStreamDiagnostic = (error) => {
|
|
59
71
|
const seen = new Set;
|
package/dist/engine/service.js
CHANGED
|
@@ -5,18 +5,19 @@ import {
|
|
|
5
5
|
recoverHarnessLocalService,
|
|
6
6
|
requestHarnessLocalService,
|
|
7
7
|
startHarnessLocalService
|
|
8
|
-
} from "../index-
|
|
9
|
-
import"../index-
|
|
10
|
-
import"../index-
|
|
11
|
-
import"../index-
|
|
12
|
-
import"../index-
|
|
13
|
-
import"../index-
|
|
14
|
-
import"../index-
|
|
15
|
-
import"../index-
|
|
16
|
-
import"../index-
|
|
8
|
+
} from "../index-5jhgatga.js";
|
|
9
|
+
import"../index-937cb7y8.js";
|
|
10
|
+
import"../index-6dft2vev.js";
|
|
11
|
+
import"../index-pp474137.js";
|
|
12
|
+
import"../index-s2k2edts.js";
|
|
13
|
+
import"../index-pdmevfxv.js";
|
|
14
|
+
import"../index-m34q25jj.js";
|
|
15
|
+
import"../index-8zjmnyw5.js";
|
|
16
|
+
import"../index-m49jx72n.js";
|
|
17
17
|
import"../index-xqxeypt5.js";
|
|
18
|
-
import"../index-
|
|
19
|
-
import"../index-
|
|
18
|
+
import"../index-nmjdwd4p.js";
|
|
19
|
+
import"../index-bpc596v3.js";
|
|
20
|
+
import"../index-fm84men1.js";
|
|
20
21
|
import"../index-1bx83sw4.js";
|
|
21
22
|
export {
|
|
22
23
|
harnessLocalCredentialsSchema,
|
|
@@ -96,6 +96,8 @@ function providerDiagnostic(body, status) {
|
|
|
96
96
|
reason = "permission";
|
|
97
97
|
else if (["rate_limit_exceeded", "rate_limit_error", "RESOURCE_EXHAUSTED"].includes(code))
|
|
98
98
|
reason = "rate_limit";
|
|
99
|
+
else if (["UNAVAILABLE", "DEADLINE_EXCEEDED", "ABORTED", "INTERNAL"].includes(code))
|
|
100
|
+
reason = "server_error";
|
|
99
101
|
else if (["model_not_found", "model_not_available", "NOT_FOUND"].includes(code))
|
|
100
102
|
reason = "model_unavailable";
|
|
101
103
|
else if (["invalid_request_error", "INVALID_ARGUMENT"].includes(code) || status === 400 || status === 422)
|
|
@@ -106,6 +108,201 @@ function providerDiagnostic(body, status) {
|
|
|
106
108
|
}
|
|
107
109
|
}
|
|
108
110
|
|
|
111
|
+
// src/runtime/provider-transient.ts
|
|
112
|
+
var PROVIDER_STATUS_CATEGORIES = [
|
|
113
|
+
"ABORTED",
|
|
114
|
+
"RESOURCE_EXHAUSTED",
|
|
115
|
+
"UNAVAILABLE",
|
|
116
|
+
"DEADLINE_EXCEEDED",
|
|
117
|
+
"INTERNAL",
|
|
118
|
+
"STREAM_RESET"
|
|
119
|
+
];
|
|
120
|
+
var VERTEX_TRANSIENT_ATTEMPTS = 3;
|
|
121
|
+
var TRANSIENT_HTTP = {
|
|
122
|
+
408: "DEADLINE_EXCEEDED",
|
|
123
|
+
409: "ABORTED",
|
|
124
|
+
425: "UNAVAILABLE",
|
|
125
|
+
429: "RESOURCE_EXHAUSTED",
|
|
126
|
+
500: "INTERNAL",
|
|
127
|
+
502: "UNAVAILABLE",
|
|
128
|
+
503: "UNAVAILABLE",
|
|
129
|
+
504: "DEADLINE_EXCEEDED"
|
|
130
|
+
};
|
|
131
|
+
var TRANSIENT_GRPC = {
|
|
132
|
+
4: "DEADLINE_EXCEEDED",
|
|
133
|
+
8: "RESOURCE_EXHAUSTED",
|
|
134
|
+
10: "ABORTED",
|
|
135
|
+
13: "INTERNAL",
|
|
136
|
+
14: "UNAVAILABLE"
|
|
137
|
+
};
|
|
138
|
+
var CATEGORY_HTTP = {
|
|
139
|
+
ABORTED: 409,
|
|
140
|
+
RESOURCE_EXHAUSTED: 429,
|
|
141
|
+
UNAVAILABLE: 503,
|
|
142
|
+
DEADLINE_EXCEEDED: 504,
|
|
143
|
+
INTERNAL: 500,
|
|
144
|
+
STREAM_RESET: undefined
|
|
145
|
+
};
|
|
146
|
+
var SYMBOLIC = new Set(["ABORTED", "RESOURCE_EXHAUSTED", "UNAVAILABLE", "DEADLINE_EXCEEDED", "INTERNAL"]);
|
|
147
|
+
var STREAM_RESET_CODES = new Set(["ECONNRESET", "ECONNABORTED", "EPIPE", "ETIMEDOUT", "UND_ERR_SOCKET", "ERR_STREAM_PREMATURE_CLOSE"]);
|
|
148
|
+
var HTTP_IN_MESSAGE = /(?:^|[^\d])(408|409|425|429|500|502|503|504)(?=$|[^\d])/;
|
|
149
|
+
var STREAM_RESET_MESSAGE = /stream reset|RST_STREAM|ECONNRESET|socket hang up|ERR_STREAM_PREMATURE_CLOSE|UND_ERR_SOCKET/i;
|
|
150
|
+
var isProviderStatus = (value) => typeof value === "string" && PROVIDER_STATUS_CATEGORIES.includes(value);
|
|
151
|
+
var httpStatusValue = (value) => typeof value === "number" && Number.isInteger(value) && value >= 100 && value <= 599 ? value : undefined;
|
|
152
|
+
var definitiveClientStatus = (status) => status !== undefined && status >= 400 && status < 500 && TRANSIENT_HTTP[status] === undefined;
|
|
153
|
+
function readProviderFailureRecord(record, depth = 0) {
|
|
154
|
+
let retryable = false;
|
|
155
|
+
let clientError = false;
|
|
156
|
+
let httpStatus;
|
|
157
|
+
let providerStatus;
|
|
158
|
+
const noteHttp = (status) => {
|
|
159
|
+
if (status === undefined)
|
|
160
|
+
return;
|
|
161
|
+
httpStatus ??= status;
|
|
162
|
+
const category = TRANSIENT_HTTP[status];
|
|
163
|
+
if (category) {
|
|
164
|
+
retryable = true;
|
|
165
|
+
providerStatus ??= category;
|
|
166
|
+
} else if (status >= 400 && status < 500)
|
|
167
|
+
clientError = true;
|
|
168
|
+
};
|
|
169
|
+
const noteCategory = (category) => {
|
|
170
|
+
if (!category || clientError)
|
|
171
|
+
return;
|
|
172
|
+
retryable = true;
|
|
173
|
+
providerStatus ??= category;
|
|
174
|
+
if (httpStatus === undefined)
|
|
175
|
+
httpStatus = CATEGORY_HTTP[category];
|
|
176
|
+
};
|
|
177
|
+
const absorb = (value) => {
|
|
178
|
+
if (depth >= 2 || !value || typeof value !== "object" || value === record)
|
|
179
|
+
return;
|
|
180
|
+
const signals = readProviderFailureRecord(value, depth + 1);
|
|
181
|
+
noteHttp(signals.httpStatus);
|
|
182
|
+
noteCategory(signals.providerStatus);
|
|
183
|
+
};
|
|
184
|
+
noteHttp(httpStatusValue(record.status) ?? httpStatusValue(record.statusCode) ?? httpStatusValue(record.httpStatusCode));
|
|
185
|
+
if (typeof record.status === "string" && /^\d{3}$/.test(record.status))
|
|
186
|
+
noteHttp(Number(record.status));
|
|
187
|
+
if (typeof record.code === "number" && record.code >= 100 && record.code <= 599)
|
|
188
|
+
noteHttp(record.code);
|
|
189
|
+
if (typeof record.code === "number" && record.code >= 0 && record.code <= 16)
|
|
190
|
+
noteCategory(TRANSIENT_GRPC[record.code]);
|
|
191
|
+
if (typeof record.code === "string") {
|
|
192
|
+
if (STREAM_RESET_CODES.has(record.code))
|
|
193
|
+
noteCategory("STREAM_RESET");
|
|
194
|
+
else if (SYMBOLIC.has(record.code))
|
|
195
|
+
noteCategory(record.code);
|
|
196
|
+
}
|
|
197
|
+
if (typeof record.status === "string" && SYMBOLIC.has(record.status))
|
|
198
|
+
noteCategory(record.status);
|
|
199
|
+
if (isProviderStatus(record.providerStatus))
|
|
200
|
+
noteCategory(record.providerStatus);
|
|
201
|
+
if (record.diagnosticCode === "VERTEX_STREAM_TOOL_TRUNCATED" || record.reason === "stream_truncated")
|
|
202
|
+
noteCategory("STREAM_RESET");
|
|
203
|
+
if (record.code === "PROVIDER_UNAVAILABLE" && record.retryable === true)
|
|
204
|
+
retryable = true;
|
|
205
|
+
const body = record.responseBody ?? record.body;
|
|
206
|
+
if (!clientError) {
|
|
207
|
+
if (typeof body === "string")
|
|
208
|
+
noteCategory(categoryFromBody(body));
|
|
209
|
+
else
|
|
210
|
+
absorb(body);
|
|
211
|
+
absorb(record.error);
|
|
212
|
+
}
|
|
213
|
+
if (!retryable && !clientError && typeof record.message === "string") {
|
|
214
|
+
const match = record.message.match(HTTP_IN_MESSAGE);
|
|
215
|
+
if (match?.[1])
|
|
216
|
+
noteHttp(Number(match[1]));
|
|
217
|
+
else if (STREAM_RESET_MESSAGE.test(record.message))
|
|
218
|
+
noteCategory("STREAM_RESET");
|
|
219
|
+
}
|
|
220
|
+
if (httpStatus !== undefined && definitiveClientStatus(httpStatus))
|
|
221
|
+
return { retryable: false, httpStatus };
|
|
222
|
+
return { retryable, ...httpStatus !== undefined ? { httpStatus } : {}, ...providerStatus ? { providerStatus } : {} };
|
|
223
|
+
}
|
|
224
|
+
function categoryFromBody(body) {
|
|
225
|
+
if (Buffer.byteLength(body) > 8192)
|
|
226
|
+
return;
|
|
227
|
+
try {
|
|
228
|
+
const parsed = JSON.parse(body);
|
|
229
|
+
if (!parsed || typeof parsed !== "object")
|
|
230
|
+
return;
|
|
231
|
+
const detail = parsed.error;
|
|
232
|
+
const source = detail && typeof detail === "object" ? detail : parsed;
|
|
233
|
+
return readProviderFailureRecord(source).providerStatus;
|
|
234
|
+
} catch {
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
function classifyProviderFailure(error) {
|
|
239
|
+
if (error && typeof error === "object") {
|
|
240
|
+
const top = readProviderFailureRecord(error);
|
|
241
|
+
if (top.httpStatus !== undefined && definitiveClientStatus(top.httpStatus))
|
|
242
|
+
return { retryable: false, httpStatus: top.httpStatus };
|
|
243
|
+
}
|
|
244
|
+
const seen = new Set;
|
|
245
|
+
let retryable = false;
|
|
246
|
+
let httpStatus;
|
|
247
|
+
let providerStatus;
|
|
248
|
+
const visit = (current, depth) => {
|
|
249
|
+
if (!current || typeof current !== "object" || depth > 5 || seen.has(current))
|
|
250
|
+
return;
|
|
251
|
+
seen.add(current);
|
|
252
|
+
const record = current;
|
|
253
|
+
const signals = readProviderFailureRecord(record);
|
|
254
|
+
httpStatus ??= signals.httpStatus;
|
|
255
|
+
providerStatus ??= signals.providerStatus;
|
|
256
|
+
if (httpStatus !== undefined && providerStatus === undefined)
|
|
257
|
+
providerStatus = TRANSIENT_HTTP[httpStatus];
|
|
258
|
+
if (record.retryable === false)
|
|
259
|
+
return;
|
|
260
|
+
if (signals.retryable)
|
|
261
|
+
retryable = true;
|
|
262
|
+
visit(record.cause, depth + 1);
|
|
263
|
+
if (record.error && typeof record.error === "object")
|
|
264
|
+
visit(record.error, depth + 1);
|
|
265
|
+
if (record.details && typeof record.details === "object")
|
|
266
|
+
visit(record.details, depth + 1);
|
|
267
|
+
if (Array.isArray(record.chain))
|
|
268
|
+
for (const entry of record.chain)
|
|
269
|
+
visit(entry, depth + 1);
|
|
270
|
+
};
|
|
271
|
+
visit(error, 0);
|
|
272
|
+
if (retryable && httpStatus === undefined && providerStatus)
|
|
273
|
+
httpStatus = CATEGORY_HTTP[providerStatus];
|
|
274
|
+
return { retryable, ...httpStatus !== undefined ? { httpStatus } : {}, ...providerStatus ? { providerStatus } : {} };
|
|
275
|
+
}
|
|
276
|
+
function isRetryableProviderFailure(error) {
|
|
277
|
+
return classifyProviderFailure(error).retryable;
|
|
278
|
+
}
|
|
279
|
+
function transientBackoffMs(attempt, baseMs = 250) {
|
|
280
|
+
const exponential = Math.min(baseMs * 2 ** Math.max(0, attempt), 1e4);
|
|
281
|
+
return exponential + Math.floor(Math.random() * exponential);
|
|
282
|
+
}
|
|
283
|
+
var thoughtOnlyText = (text) => {
|
|
284
|
+
try {
|
|
285
|
+
const parsed = JSON.parse(text);
|
|
286
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
|
|
287
|
+
return false;
|
|
288
|
+
const record = parsed;
|
|
289
|
+
return record.thought === true && Object.keys(record).every((key) => key === "thought" || key === "thoughtSignature");
|
|
290
|
+
} catch {
|
|
291
|
+
return false;
|
|
292
|
+
}
|
|
293
|
+
};
|
|
294
|
+
function isEmptyModelTurn(result) {
|
|
295
|
+
if (result.finishReason === "content-filter" || result.finishReason === "error")
|
|
296
|
+
return false;
|
|
297
|
+
if ((result.images?.length ?? 0) > 0 || (result.audio?.length ?? 0) > 0)
|
|
298
|
+
return false;
|
|
299
|
+
const parts = result.messages?.flatMap((message) => message.parts ?? []) ?? [];
|
|
300
|
+
if (parts.some((part) => part.type === "tool-call" || part.type === "image" || part.type === "audio"))
|
|
301
|
+
return false;
|
|
302
|
+
const texts = [result.text ?? "", ...parts.filter((part) => part.type === "text").map((part) => part.text ?? "")];
|
|
303
|
+
return texts.every((text) => text.trim().length === 0 || thoughtOnlyText(text.trim()));
|
|
304
|
+
}
|
|
305
|
+
|
|
109
306
|
// src/providers/vertex-auth.ts
|
|
110
307
|
var CLOUD_PLATFORM_SCOPE = "https://www.googleapis.com/auth/cloud-platform";
|
|
111
308
|
function vertexRoute(env) {
|
|
@@ -155,13 +352,31 @@ class VertexAuthenticationError extends Error {
|
|
|
155
352
|
this.name = "VertexAuthenticationError";
|
|
156
353
|
}
|
|
157
354
|
}
|
|
158
|
-
function createVertexModel(model, env, createAuth) {
|
|
355
|
+
function createVertexModel(model, env, createAuth, retry) {
|
|
159
356
|
const route = vertexRoute(env);
|
|
160
357
|
const adapter = createVertex({
|
|
161
358
|
...route,
|
|
162
359
|
getAccessToken: vertexTokenSource(env, route, createAuth)
|
|
163
360
|
})(model);
|
|
164
|
-
|
|
361
|
+
const attempts = retry?.attempts ?? VERTEX_TRANSIENT_ATTEMPTS;
|
|
362
|
+
const delayFor = (input) => retry?.delayMs ?? ((attempt) => input.retryBackoffMs === 0 ? 0 : transientBackoffMs(attempt, input.retryBackoffMs ?? 250));
|
|
363
|
+
const generate = async (input) => withVertexAttempts(input.abortSignal, vertexAttemptBudget(input, attempts), delayFor(input), async () => {
|
|
364
|
+
try {
|
|
365
|
+
return await adapter.generate({ ...input, maxRetries: 0 });
|
|
366
|
+
} catch (error) {
|
|
367
|
+
throw safeVertexError(error);
|
|
368
|
+
}
|
|
369
|
+
}, (result) => !isEmptyModelTurn(result));
|
|
370
|
+
const innerStream = adapter.stream?.bind(adapter);
|
|
371
|
+
const retrying = innerStream ? {
|
|
372
|
+
...adapter,
|
|
373
|
+
generate,
|
|
374
|
+
async stream(input) {
|
|
375
|
+
const events = await withVertexAttempts(input.abortSignal, vertexAttemptBudget(input, attempts), delayFor(input), () => collectVertexStream(() => innerStream({ ...input, maxRetries: 0 })), (events2) => !isEmptyVertexStream(events2));
|
|
376
|
+
return replayVertexStream(events);
|
|
377
|
+
}
|
|
378
|
+
} : { ...adapter, generate };
|
|
379
|
+
return wrapLanguageModel2(retrying, [{
|
|
165
380
|
name: "harness-vertex-sanitized-errors",
|
|
166
381
|
async wrapGenerate(_context, next) {
|
|
167
382
|
try {
|
|
@@ -187,19 +402,109 @@ function createVertexModel(model, env, createAuth) {
|
|
|
187
402
|
}
|
|
188
403
|
}]);
|
|
189
404
|
}
|
|
405
|
+
async function collectVertexStream(next) {
|
|
406
|
+
let stream;
|
|
407
|
+
try {
|
|
408
|
+
stream = await next();
|
|
409
|
+
} catch (error) {
|
|
410
|
+
throw safeVertexError(error);
|
|
411
|
+
}
|
|
412
|
+
const events = [];
|
|
413
|
+
try {
|
|
414
|
+
for await (const event of stream) {
|
|
415
|
+
if (event.type === "error")
|
|
416
|
+
throw safeVertexError(event.error);
|
|
417
|
+
events.push(event);
|
|
418
|
+
}
|
|
419
|
+
} catch (error) {
|
|
420
|
+
throw error instanceof Error && error.message.startsWith("Vertex request failed.") ? error : safeVertexError(error);
|
|
421
|
+
}
|
|
422
|
+
return events;
|
|
423
|
+
}
|
|
424
|
+
function isEmptyVertexStream(events) {
|
|
425
|
+
let text = "";
|
|
426
|
+
let finishReason;
|
|
427
|
+
let tools = false;
|
|
428
|
+
let media = false;
|
|
429
|
+
for (const event of events) {
|
|
430
|
+
if (event.type === "text-delta")
|
|
431
|
+
text += event.textDelta;
|
|
432
|
+
else if (event.type === "tool-call" || event.type === "tool-approval-request")
|
|
433
|
+
tools = true;
|
|
434
|
+
else if (event.type === "image-generation")
|
|
435
|
+
media = true;
|
|
436
|
+
else if (event.type === "finish")
|
|
437
|
+
finishReason = event.finishReason;
|
|
438
|
+
}
|
|
439
|
+
return isEmptyModelTurn({
|
|
440
|
+
text,
|
|
441
|
+
finishReason,
|
|
442
|
+
...tools ? { messages: [{ parts: [{ type: "tool-call" }] }] } : {},
|
|
443
|
+
...media ? { images: [{}] } : {}
|
|
444
|
+
});
|
|
445
|
+
}
|
|
446
|
+
function replayVertexStream(events) {
|
|
447
|
+
return async function* () {
|
|
448
|
+
yield* events;
|
|
449
|
+
}();
|
|
450
|
+
}
|
|
451
|
+
async function withVertexAttempts(abortSignal, attempts, delayMs, run, accept) {
|
|
452
|
+
let last;
|
|
453
|
+
for (let attempt = 0;attempt < attempts; attempt += 1) {
|
|
454
|
+
if (abortSignal?.aborted)
|
|
455
|
+
throw new DOMException("Vertex request cancelled.", "AbortError");
|
|
456
|
+
try {
|
|
457
|
+
const value = await run();
|
|
458
|
+
if (accept(value) || attempt === attempts - 1)
|
|
459
|
+
return value;
|
|
460
|
+
last = value;
|
|
461
|
+
} catch (error) {
|
|
462
|
+
const safe = error instanceof Error && (error.name === "AbortError" || error.message.startsWith("Vertex request failed.")) ? error : safeVertexError(error);
|
|
463
|
+
if (safe.name === "AbortError" || abortSignal?.aborted || attempt === attempts - 1 || !isRetryableProviderFailure(safe))
|
|
464
|
+
throw safe;
|
|
465
|
+
}
|
|
466
|
+
await sleep(delayMs(attempt));
|
|
467
|
+
}
|
|
468
|
+
return last;
|
|
469
|
+
}
|
|
470
|
+
var sleep = (ms) => ms > 0 ? new Promise((resolve) => setTimeout(resolve, ms)) : Promise.resolve();
|
|
471
|
+
function vertexAttemptBudget(input, fallback) {
|
|
472
|
+
const requested = [
|
|
473
|
+
typeof input.maxProviderRequests === "number" ? input.maxProviderRequests : undefined,
|
|
474
|
+
typeof input.maxRetries === "number" ? input.maxRetries + 1 : undefined
|
|
475
|
+
].filter((value) => value !== undefined);
|
|
476
|
+
if (requested.length === 0)
|
|
477
|
+
return Math.max(1, fallback);
|
|
478
|
+
return Math.max(1, Math.min(...requested));
|
|
479
|
+
}
|
|
190
480
|
function safeVertexError(error) {
|
|
191
481
|
if (error instanceof VertexAuthenticationError)
|
|
192
482
|
return error;
|
|
193
483
|
const record = error && typeof error === "object" ? error : {};
|
|
194
484
|
if (record.name === "AbortError")
|
|
195
485
|
return new DOMException("Vertex request cancelled.", "AbortError");
|
|
196
|
-
const
|
|
486
|
+
const failure = classifyProviderFailure(error);
|
|
487
|
+
const body = providerBody(record.responseBody) ?? providerBody(record.body);
|
|
488
|
+
const preserved = providerDiagnosticSchema.safeParse(record.provider);
|
|
489
|
+
const provider = body !== undefined ? providerDiagnostic(body, failure.httpStatus) : preserved.success ? preserved.data : providerDiagnostic(undefined, failure.httpStatus);
|
|
197
490
|
return Object.assign(new Error("Vertex request failed. Check the sanitized provider diagnosis."), {
|
|
198
|
-
...
|
|
199
|
-
|
|
200
|
-
|
|
491
|
+
...failure.httpStatus !== undefined ? { status: failure.httpStatus } : {},
|
|
492
|
+
...failure.providerStatus ? { providerStatus: failure.providerStatus } : {},
|
|
493
|
+
provider,
|
|
494
|
+
retryable: failure.retryable
|
|
201
495
|
});
|
|
202
496
|
}
|
|
497
|
+
function providerBody(value) {
|
|
498
|
+
if (typeof value === "string")
|
|
499
|
+
return value;
|
|
500
|
+
if (!value || typeof value !== "object")
|
|
501
|
+
return;
|
|
502
|
+
try {
|
|
503
|
+
return JSON.stringify(value).slice(0, 8192);
|
|
504
|
+
} catch {
|
|
505
|
+
return;
|
|
506
|
+
}
|
|
507
|
+
}
|
|
203
508
|
|
|
204
509
|
// src/providers/qwen-hosted-policy.ts
|
|
205
510
|
import { wrapLanguageModel as wrapLanguageModel3 } from "@zhivex-ai/core";
|
|
@@ -1921,13 +2226,6 @@ class HarnessExecutionError extends HarnessError {
|
|
|
1921
2226
|
this.name = "HarnessExecutionError";
|
|
1922
2227
|
}
|
|
1923
2228
|
}
|
|
1924
|
-
var numericStatuses = (error) => {
|
|
1925
|
-
if (!error || typeof error !== "object")
|
|
1926
|
-
return;
|
|
1927
|
-
const record = error;
|
|
1928
|
-
const values = [record.status, record.statusCode].filter((value) => typeof value === "number" && Number.isSafeInteger(value));
|
|
1929
|
-
return values.length > 0 ? values : undefined;
|
|
1930
|
-
};
|
|
1931
2229
|
var normalizeHarnessError = (error) => {
|
|
1932
2230
|
const diagnostic = providerStreamDiagnostic(error);
|
|
1933
2231
|
if (diagnostic)
|
|
@@ -1935,9 +2233,16 @@ var normalizeHarnessError = (error) => {
|
|
|
1935
2233
|
if (error instanceof HarnessError)
|
|
1936
2234
|
return error;
|
|
1937
2235
|
const message = error instanceof Error ? error.message : "Harness execution failed.";
|
|
1938
|
-
const
|
|
1939
|
-
if (
|
|
1940
|
-
|
|
2236
|
+
const failure = classifyProviderFailure(error);
|
|
2237
|
+
if (failure.retryable) {
|
|
2238
|
+
const record = error && typeof error === "object" ? error : {};
|
|
2239
|
+
const body = typeof record.responseBody === "string" ? record.responseBody : typeof record.body === "string" ? record.body : undefined;
|
|
2240
|
+
const providerError = new HarnessProviderError("Provider request failed.", { cause: error, retryable: true });
|
|
2241
|
+
return Object.assign(providerError, {
|
|
2242
|
+
...failure.httpStatus !== undefined ? { status: failure.httpStatus } : {},
|
|
2243
|
+
...failure.providerStatus ? { providerStatus: failure.providerStatus } : {},
|
|
2244
|
+
provider: providerDiagnostic(body, failure.httpStatus)
|
|
2245
|
+
});
|
|
1941
2246
|
}
|
|
1942
2247
|
const name = error && typeof error === "object" && typeof error.name === "string" ? error.name : "";
|
|
1943
2248
|
const code = error && typeof error === "object" && typeof error.code === "string" ? error.code : "";
|
|
@@ -13920,7 +14225,7 @@ import { z as z32 } from "zod";
|
|
|
13920
14225
|
// package.json
|
|
13921
14226
|
var package_default = {
|
|
13922
14227
|
name: "@zhivex-ai/harness",
|
|
13923
|
-
version: "1.4.0
|
|
14228
|
+
version: "1.4.0",
|
|
13924
14229
|
description: "Governed, provider-portable runtime for coding agents with durable approvals and isolated repository execution.",
|
|
13925
14230
|
type: "module",
|
|
13926
14231
|
license: "MIT",
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createHarnessClientAdapter
|
|
3
|
-
} from "./index-
|
|
3
|
+
} from "./index-937cb7y8.js";
|
|
4
4
|
import {
|
|
5
5
|
harnessPolicyDecisionEventSchema
|
|
6
|
-
} from "./index-
|
|
6
|
+
} from "./index-pp474137.js";
|
|
7
7
|
import {
|
|
8
8
|
openCliSessionStore
|
|
9
|
-
} from "./index-
|
|
9
|
+
} from "./index-s2k2edts.js";
|
|
10
10
|
import {
|
|
11
11
|
SqliteDatabase
|
|
12
|
-
} from "./index-
|
|
12
|
+
} from "./index-m34q25jj.js";
|
|
13
13
|
import {
|
|
14
14
|
harnessClientRequestSchema,
|
|
15
15
|
streamEventDocument
|
|
16
|
-
} from "./index-
|
|
16
|
+
} from "./index-nmjdwd4p.js";
|
|
17
17
|
import {
|
|
18
18
|
__require
|
|
19
19
|
} from "./index-1bx83sw4.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
DEFAULT_PROVIDER_REGISTRY,
|
|
3
3
|
HARNESS_SUBAGENT_PROFILES
|
|
4
|
-
} from "./index-
|
|
4
|
+
} from "./index-8zjmnyw5.js";
|
|
5
5
|
|
|
6
6
|
// src/providers/routing.ts
|
|
7
7
|
var routeError = (value) => new Error(`Invalid route: ${value}. Use <profile>=<provider>[:<model>].`);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
TERMINAL_SESSION_RUN_STATUSES
|
|
3
|
-
} from "./index-
|
|
3
|
+
} from "./index-s2k2edts.js";
|
|
4
4
|
import {
|
|
5
5
|
SqliteDatabase,
|
|
6
6
|
createEditProposal,
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
statRegularFileNoFollow,
|
|
10
10
|
withWorkspaceMutation,
|
|
11
11
|
workspaceFilePathSchema
|
|
12
|
-
} from "./index-
|
|
12
|
+
} from "./index-m34q25jj.js";
|
|
13
13
|
|
|
14
14
|
// src/persistence/workspace-checkpoints.ts
|
|
15
15
|
import { createHash, randomUUID } from "node:crypto";
|
|
@@ -2,14 +2,14 @@ import {
|
|
|
2
2
|
VERTEX_ENVIRONMENT,
|
|
3
3
|
createVertexModel,
|
|
4
4
|
vertexConfigured
|
|
5
|
-
} from "./index-
|
|
5
|
+
} from "./index-m49jx72n.js";
|
|
6
6
|
import {
|
|
7
7
|
bundledDefaultModel
|
|
8
8
|
} from "./index-xqxeypt5.js";
|
|
9
9
|
import {
|
|
10
10
|
HarnessConfigError,
|
|
11
11
|
HarnessProviderError
|
|
12
|
-
} from "./index-
|
|
12
|
+
} from "./index-bpc596v3.js";
|
|
13
13
|
|
|
14
14
|
// src/providers/reasoning.ts
|
|
15
15
|
import { z } from "zod";
|