@the-open-engine/zeroshot 6.33.1 → 6.34.1
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/lib/agent-cli-provider/adapters/codex.d.ts.map +1 -1
- package/lib/agent-cli-provider/adapters/codex.js +3 -1
- package/lib/agent-cli-provider/adapters/codex.js.map +1 -1
- package/lib/hosted-target/adapter-request.cjs +55 -0
- package/lib/hosted-target/adapter-request.d.cts +9 -0
- package/lib/hosted-target/adapter-request.d.mts +9 -0
- package/lib/hosted-target/adapter-request.d.ts +9 -0
- package/lib/hosted-target/adapter-request.mjs +55 -1
- package/lib/hosted-target/adapter-types.d.cts +1 -0
- package/lib/hosted-target/adapter-types.d.mts +1 -0
- package/lib/hosted-target/adapter-types.d.ts +1 -0
- package/lib/hosted-target/response-status.cjs +18 -0
- package/lib/hosted-target/response-status.d.cts +2 -0
- package/lib/hosted-target/response-status.d.mts +2 -0
- package/lib/hosted-target/response-status.d.ts +2 -0
- package/lib/hosted-target/response-status.mjs +15 -0
- package/lib/hosted-target/retry-executor.d.cts +1 -1
- package/lib/hosted-target/retry-executor.d.mts +1 -1
- package/lib/hosted-target/retry-executor.d.ts +1 -1
- package/lib/hosted-target/runtime-install.cjs +45 -0
- package/lib/hosted-target/runtime-install.d.cts +14 -0
- package/lib/hosted-target/runtime-install.d.mts +14 -0
- package/lib/hosted-target/runtime-install.d.ts +14 -0
- package/lib/hosted-target/runtime-install.mjs +42 -0
- package/lib/hosted-target/zero-cloud-v1-adapter.cjs +35 -66
- package/lib/hosted-target/zero-cloud-v1-adapter.d.cts +1 -0
- package/lib/hosted-target/zero-cloud-v1-adapter.d.mts +1 -0
- package/lib/hosted-target/zero-cloud-v1-adapter.d.ts +1 -0
- package/lib/hosted-target/zero-cloud-v1-adapter.mjs +37 -68
- package/lib/target/discovery-validation.cjs +11 -18
- package/lib/target/discovery-validation.d.cts +1 -12
- package/lib/target/discovery-validation.d.mts +1 -12
- package/lib/target/discovery-validation.d.ts +1 -12
- package/lib/target/discovery-validation.js +11 -18
- package/lib/target/discovery-validation.mjs +11 -18
- package/npm-shrinkwrap.json +2 -2
- package/package.json +2 -1
- package/src/agent/agent-task-executor.js +109 -30
- package/src/agent-cli-provider/adapters/codex.ts +3 -1
- package/src/hosted-target/adapter-request.ts +75 -1
- package/src/hosted-target/adapter-types.ts +6 -0
- package/src/hosted-target/response-status.ts +21 -0
- package/src/hosted-target/retry-executor.ts +8 -1
- package/src/hosted-target/runtime-install.ts +83 -0
- package/src/hosted-target/zero-cloud-v1-adapter.ts +65 -100
- package/src/target/discovery-validation.ts +26 -28
- package/task-lib/runner.js +14 -1
- package/task-lib/watcher-output-runtime.js +80 -1
|
@@ -10,4 +10,5 @@ export declare class ZeroCloudV1TargetAdapter implements TargetAdapter {
|
|
|
10
10
|
terminate(capsuleId: string, signal?: AbortSignal): Promise<Capsule>;
|
|
11
11
|
limits(signal?: AbortSignal): Promise<CapsuleLimits>;
|
|
12
12
|
access(capsuleId: string, signal?: AbortSignal): Promise<CapsuleAccess>;
|
|
13
|
+
installRuntime(capsuleId: string, runtime: unknown, accessToken: string, signal?: AbortSignal): Promise<void>;
|
|
13
14
|
}
|
|
@@ -10,4 +10,5 @@ export declare class ZeroCloudV1TargetAdapter implements TargetAdapter {
|
|
|
10
10
|
terminate(capsuleId: string, signal?: AbortSignal): Promise<Capsule>;
|
|
11
11
|
limits(signal?: AbortSignal): Promise<CapsuleLimits>;
|
|
12
12
|
access(capsuleId: string, signal?: AbortSignal): Promise<CapsuleAccess>;
|
|
13
|
+
installRuntime(capsuleId: string, runtime: unknown, accessToken: string, signal?: AbortSignal): Promise<void>;
|
|
13
14
|
}
|
|
@@ -10,4 +10,5 @@ export declare class ZeroCloudV1TargetAdapter implements TargetAdapter {
|
|
|
10
10
|
terminate(capsuleId: string, signal?: AbortSignal): Promise<Capsule>;
|
|
11
11
|
limits(signal?: AbortSignal): Promise<CapsuleLimits>;
|
|
12
12
|
access(capsuleId: string, signal?: AbortSignal): Promise<CapsuleAccess>;
|
|
13
|
+
installRuntime(capsuleId: string, runtime: unknown, accessToken: string, signal?: AbortSignal): Promise<void>;
|
|
13
14
|
}
|
|
@@ -1,22 +1,14 @@
|
|
|
1
1
|
import { IDEMPOTENCY_KEY_PATTERN, MAX_RESPONSE_BYTES } from './bounds.mjs';
|
|
2
|
-
import {
|
|
2
|
+
import { TargetProtocolError } from './errors.mjs';
|
|
3
3
|
import { DefaultRetryPolicy } from './retry.mjs';
|
|
4
4
|
import { assertCapsule, assertCapsuleAccess, assertCapsuleLimits, assertCapsuleListPage, } from './response-validation.mjs';
|
|
5
5
|
import { readBoundedResponseJson } from '../target/bounded-response.mjs';
|
|
6
|
-
import { throwCapsuleServerError } from './capsule-error-response.mjs';
|
|
7
6
|
import { validateAccessUrl } from './access-url.mjs';
|
|
8
7
|
import { withTargetRetry } from './retry-executor.mjs';
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
return globalThis.fetch(url, init);
|
|
13
|
-
},
|
|
14
|
-
};
|
|
8
|
+
import { installRuntime as installOpaqueRuntime } from './runtime-install.mjs';
|
|
9
|
+
import { assertCapsuleResponseStatus } from './response-status.mjs';
|
|
10
|
+
import { createAdapterRequester, } from './adapter-request.mjs';
|
|
15
11
|
const DEFAULT_CLOCK = { now: () => Date.now() };
|
|
16
|
-
function throwIfAborted(signal) {
|
|
17
|
-
if (signal?.aborted)
|
|
18
|
-
throw signal.reason ?? new globalThis.DOMException('The operation was aborted', 'AbortError');
|
|
19
|
-
}
|
|
20
12
|
function validOpaque(value, field) {
|
|
21
13
|
if (value.length === 0 || value.length > 1024)
|
|
22
14
|
throw new TargetProtocolError(`${field} is invalid`);
|
|
@@ -27,16 +19,14 @@ function jsonRequest(body) {
|
|
|
27
19
|
export class ZeroCloudV1TargetAdapter {
|
|
28
20
|
#descriptor;
|
|
29
21
|
#organizationId;
|
|
30
|
-
#
|
|
31
|
-
#transport;
|
|
22
|
+
#request;
|
|
32
23
|
#clock;
|
|
33
24
|
#retryPolicy;
|
|
34
25
|
constructor(options) {
|
|
35
26
|
this.#descriptor = options.descriptor;
|
|
36
27
|
this.#organizationId = options.organization.id;
|
|
37
28
|
validOpaque(this.#organizationId, 'organization id');
|
|
38
|
-
this.#
|
|
39
|
-
this.#transport = options.transport ?? DEFAULT_TRANSPORT;
|
|
29
|
+
this.#request = createAdapterRequester(options.descriptor, options.tokenProvider, options.transport);
|
|
40
30
|
this.#clock = options.clock ?? DEFAULT_CLOCK;
|
|
41
31
|
this.#retryPolicy = options.retryPolicy ?? new DefaultRetryPolicy();
|
|
42
32
|
}
|
|
@@ -106,11 +96,33 @@ export class ZeroCloudV1TargetAdapter {
|
|
|
106
96
|
validateAccessUrl(result.websocketUrl, capsuleId, this.#descriptor);
|
|
107
97
|
return result;
|
|
108
98
|
}
|
|
99
|
+
async installRuntime(capsuleId, runtime, accessToken, signal) {
|
|
100
|
+
const descriptor = this.#descriptor.credentialInstall;
|
|
101
|
+
if (descriptor === null) {
|
|
102
|
+
throw new TargetProtocolError('Target does not advertise runtime installation');
|
|
103
|
+
}
|
|
104
|
+
await installOpaqueRuntime({
|
|
105
|
+
capsuleId,
|
|
106
|
+
runtime,
|
|
107
|
+
accessToken,
|
|
108
|
+
descriptor,
|
|
109
|
+
...(signal === undefined ? {} : { signal }),
|
|
110
|
+
clock: this.#clock,
|
|
111
|
+
retryPolicy: this.#retryPolicy,
|
|
112
|
+
request: (method, path, requestSignal, body, token) => this.#request({
|
|
113
|
+
method,
|
|
114
|
+
path,
|
|
115
|
+
signal: requestSignal,
|
|
116
|
+
request: { body },
|
|
117
|
+
accessToken: token,
|
|
118
|
+
}),
|
|
119
|
+
});
|
|
120
|
+
}
|
|
109
121
|
#execute(...args) {
|
|
110
122
|
return Promise.resolve().then(() => this.#executeExpanded(args));
|
|
111
123
|
}
|
|
112
124
|
#executeExpanded(args) {
|
|
113
|
-
const [operation, method, template, values, expectedStatus, validate, signal, request = {}
|
|
125
|
+
const [operation, method, template, values, expectedStatus, validate, signal, request = {}] = args;
|
|
114
126
|
let path;
|
|
115
127
|
try {
|
|
116
128
|
path = template.expand(values);
|
|
@@ -119,60 +131,17 @@ export class ZeroCloudV1TargetAdapter {
|
|
|
119
131
|
throw new TargetProtocolError('Capsule route expansion is unsafe');
|
|
120
132
|
}
|
|
121
133
|
return withTargetRetry(operation, async () => {
|
|
122
|
-
const response = await this.#request(
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
throw new TargetProtocolError('Target returned an unexpected success status');
|
|
131
|
-
}
|
|
132
|
-
await throwCapsuleServerError(response, (errorResponse) => this.#readJson(errorResponse), this.#clock);
|
|
133
|
-
}
|
|
134
|
+
const response = await this.#request({
|
|
135
|
+
method,
|
|
136
|
+
path,
|
|
137
|
+
signal,
|
|
138
|
+
request,
|
|
139
|
+
accessToken: undefined,
|
|
140
|
+
});
|
|
141
|
+
await assertCapsuleResponseStatus(response, expectedStatus, (errorResponse) => this.#readJson(errorResponse), this.#clock);
|
|
134
142
|
return validate(await this.#readJson(response));
|
|
135
143
|
}, signal, { clock: this.#clock, policy: this.#retryPolicy });
|
|
136
144
|
}
|
|
137
|
-
async #request(method, path, signal, request) {
|
|
138
|
-
throwIfAborted(signal);
|
|
139
|
-
const url = requestUrl(path, this.#descriptor);
|
|
140
|
-
let token;
|
|
141
|
-
try {
|
|
142
|
-
token = await this.#tokenProvider.getAccessToken(signal);
|
|
143
|
-
}
|
|
144
|
-
catch {
|
|
145
|
-
throw new TargetAuthError('Target access authorization failed');
|
|
146
|
-
}
|
|
147
|
-
const init = {
|
|
148
|
-
method,
|
|
149
|
-
headers: {
|
|
150
|
-
Accept: 'application/json',
|
|
151
|
-
Authorization: `Bearer ${token}`,
|
|
152
|
-
...(request.body === undefined ? {} : { 'Content-Type': 'application/json' }),
|
|
153
|
-
...request.headers,
|
|
154
|
-
},
|
|
155
|
-
redirect: 'manual',
|
|
156
|
-
};
|
|
157
|
-
if (request.body !== undefined)
|
|
158
|
-
init.body = request.body;
|
|
159
|
-
if (signal !== undefined)
|
|
160
|
-
init.signal = signal;
|
|
161
|
-
try {
|
|
162
|
-
const response = await this.#transport.fetch(url.href, init);
|
|
163
|
-
if (response.url && new globalThis.URL(response.url).href !== url.href) {
|
|
164
|
-
await response.body?.cancel().catch(() => undefined);
|
|
165
|
-
throw new TargetProtocolError('Capsule response changed target route');
|
|
166
|
-
}
|
|
167
|
-
return response;
|
|
168
|
-
}
|
|
169
|
-
catch (error) {
|
|
170
|
-
if (error instanceof TargetAdapterError)
|
|
171
|
-
throw error;
|
|
172
|
-
throwIfAborted(signal);
|
|
173
|
-
throw new TargetTransportError('Capsule transport failed');
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
145
|
#readJson(response) {
|
|
177
146
|
return readBoundedResponseJson(response, MAX_RESPONSE_BYTES, (kind) => new TargetProtocolError(kind === 'size'
|
|
178
147
|
? 'Capsule response exceeds the size limit'
|
|
@@ -81,29 +81,22 @@ function parseCredentialInstall(value) {
|
|
|
81
81
|
if (value === undefined || value === null)
|
|
82
82
|
return null;
|
|
83
83
|
const extension = closedRecord(value, 'extensions.credential_install', [
|
|
84
|
-
'kind',
|
|
84
|
+
'kind',
|
|
85
|
+
'install',
|
|
86
|
+
'max_body_bytes',
|
|
85
87
|
]);
|
|
86
88
|
exact(extension.kind, 'openengine.capsule-credential-install/v1', 'extensions.credential_install.kind');
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
exact(install.method, 'PUT', 'extensions.credential_install.install.method');
|
|
91
|
-
exact(extension.upload_url_origin, 'same_origin', 'extensions.credential_install.upload_url_origin');
|
|
92
|
-
exactStringSet(extension.sealed_envelope_algorithms, 'extensions.credential_install.sealed_envelope_algorithms', ['RSA-OAEP-3072-SHA256']);
|
|
93
|
-
const bounds = closedRecord(extension.bounds, 'extensions.credential_install.bounds', [
|
|
94
|
-
'max_envelope_bytes', 'max_body_bytes', 'grant_ttl_seconds', 'max_clock_skew_seconds',
|
|
89
|
+
const install = closedRecord(extension.install, 'extensions.credential_install.install', [
|
|
90
|
+
'route_template',
|
|
91
|
+
'method',
|
|
95
92
|
]);
|
|
93
|
+
exact(install.method, 'PUT', 'extensions.credential_install.install.method');
|
|
96
94
|
return Object.freeze({
|
|
97
95
|
kind: 'openengine.capsule-credential-install/v1',
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
sealedEnvelopeAlgorithms: Object.freeze(['RSA-OAEP-3072-SHA256']),
|
|
102
|
-
bounds: Object.freeze({
|
|
103
|
-
maxEnvelopeBytes: integer(bounds.max_envelope_bytes, 'extensions.credential_install.bounds.max_envelope_bytes', 1, 1_048_576),
|
|
104
|
-
maxBodyBytes: integer(bounds.max_body_bytes, 'extensions.credential_install.bounds.max_body_bytes', 1, 1_048_576),
|
|
105
|
-
grantTtlSeconds: integer(bounds.grant_ttl_seconds, 'extensions.credential_install.bounds.grant_ttl_seconds', 1, 3_600),
|
|
106
|
-
maxClockSkewSeconds: integer(bounds.max_clock_skew_seconds, 'extensions.credential_install.bounds.max_clock_skew_seconds', 0, 300),
|
|
96
|
+
install: Object.freeze({
|
|
97
|
+
routeTemplate: (0, route_template_js_1.routeTemplate)(install.route_template, 'extensions.credential_install.install.route_template', ['capsule_id']),
|
|
98
|
+
method: 'PUT',
|
|
107
99
|
}),
|
|
100
|
+
maxBodyBytes: integer(extension.max_body_bytes, 'extensions.credential_install.max_body_bytes', 1, 4 * 1024 * 1024),
|
|
108
101
|
});
|
|
109
102
|
}
|
|
@@ -1,22 +1,11 @@
|
|
|
1
1
|
import { type RouteTemplate } from './route-template.js';
|
|
2
2
|
export interface CredentialInstallDescriptor {
|
|
3
3
|
readonly kind: 'openengine.capsule-credential-install/v1';
|
|
4
|
-
readonly grant: {
|
|
5
|
-
readonly routeTemplate: RouteTemplate;
|
|
6
|
-
readonly method: 'POST';
|
|
7
|
-
};
|
|
8
4
|
readonly install: {
|
|
9
5
|
readonly routeTemplate: RouteTemplate;
|
|
10
6
|
readonly method: 'PUT';
|
|
11
7
|
};
|
|
12
|
-
readonly
|
|
13
|
-
readonly sealedEnvelopeAlgorithms: readonly ['RSA-OAEP-3072-SHA256'];
|
|
14
|
-
readonly bounds: {
|
|
15
|
-
readonly maxEnvelopeBytes: number;
|
|
16
|
-
readonly maxBodyBytes: number;
|
|
17
|
-
readonly grantTtlSeconds: number;
|
|
18
|
-
readonly maxClockSkewSeconds: number;
|
|
19
|
-
};
|
|
8
|
+
readonly maxBodyBytes: number;
|
|
20
9
|
}
|
|
21
10
|
export declare function record(value: unknown, field: string): Record<string, unknown>;
|
|
22
11
|
export declare function closedRecord(value: unknown, field: string, fields: readonly string[]): Record<string, unknown>;
|
|
@@ -1,22 +1,11 @@
|
|
|
1
1
|
import { type RouteTemplate } from './route-template.js';
|
|
2
2
|
export interface CredentialInstallDescriptor {
|
|
3
3
|
readonly kind: 'openengine.capsule-credential-install/v1';
|
|
4
|
-
readonly grant: {
|
|
5
|
-
readonly routeTemplate: RouteTemplate;
|
|
6
|
-
readonly method: 'POST';
|
|
7
|
-
};
|
|
8
4
|
readonly install: {
|
|
9
5
|
readonly routeTemplate: RouteTemplate;
|
|
10
6
|
readonly method: 'PUT';
|
|
11
7
|
};
|
|
12
|
-
readonly
|
|
13
|
-
readonly sealedEnvelopeAlgorithms: readonly ['RSA-OAEP-3072-SHA256'];
|
|
14
|
-
readonly bounds: {
|
|
15
|
-
readonly maxEnvelopeBytes: number;
|
|
16
|
-
readonly maxBodyBytes: number;
|
|
17
|
-
readonly grantTtlSeconds: number;
|
|
18
|
-
readonly maxClockSkewSeconds: number;
|
|
19
|
-
};
|
|
8
|
+
readonly maxBodyBytes: number;
|
|
20
9
|
}
|
|
21
10
|
export declare function record(value: unknown, field: string): Record<string, unknown>;
|
|
22
11
|
export declare function closedRecord(value: unknown, field: string, fields: readonly string[]): Record<string, unknown>;
|
|
@@ -1,22 +1,11 @@
|
|
|
1
1
|
import { type RouteTemplate } from './route-template.js';
|
|
2
2
|
export interface CredentialInstallDescriptor {
|
|
3
3
|
readonly kind: 'openengine.capsule-credential-install/v1';
|
|
4
|
-
readonly grant: {
|
|
5
|
-
readonly routeTemplate: RouteTemplate;
|
|
6
|
-
readonly method: 'POST';
|
|
7
|
-
};
|
|
8
4
|
readonly install: {
|
|
9
5
|
readonly routeTemplate: RouteTemplate;
|
|
10
6
|
readonly method: 'PUT';
|
|
11
7
|
};
|
|
12
|
-
readonly
|
|
13
|
-
readonly sealedEnvelopeAlgorithms: readonly ['RSA-OAEP-3072-SHA256'];
|
|
14
|
-
readonly bounds: {
|
|
15
|
-
readonly maxEnvelopeBytes: number;
|
|
16
|
-
readonly maxBodyBytes: number;
|
|
17
|
-
readonly grantTtlSeconds: number;
|
|
18
|
-
readonly maxClockSkewSeconds: number;
|
|
19
|
-
};
|
|
8
|
+
readonly maxBodyBytes: number;
|
|
20
9
|
}
|
|
21
10
|
export declare function record(value: unknown, field: string): Record<string, unknown>;
|
|
22
11
|
export declare function closedRecord(value: unknown, field: string, fields: readonly string[]): Record<string, unknown>;
|
|
@@ -81,29 +81,22 @@ function parseCredentialInstall(value) {
|
|
|
81
81
|
if (value === undefined || value === null)
|
|
82
82
|
return null;
|
|
83
83
|
const extension = closedRecord(value, 'extensions.credential_install', [
|
|
84
|
-
'kind',
|
|
84
|
+
'kind',
|
|
85
|
+
'install',
|
|
86
|
+
'max_body_bytes',
|
|
85
87
|
]);
|
|
86
88
|
exact(extension.kind, 'openengine.capsule-credential-install/v1', 'extensions.credential_install.kind');
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
exact(install.method, 'PUT', 'extensions.credential_install.install.method');
|
|
91
|
-
exact(extension.upload_url_origin, 'same_origin', 'extensions.credential_install.upload_url_origin');
|
|
92
|
-
exactStringSet(extension.sealed_envelope_algorithms, 'extensions.credential_install.sealed_envelope_algorithms', ['RSA-OAEP-3072-SHA256']);
|
|
93
|
-
const bounds = closedRecord(extension.bounds, 'extensions.credential_install.bounds', [
|
|
94
|
-
'max_envelope_bytes', 'max_body_bytes', 'grant_ttl_seconds', 'max_clock_skew_seconds',
|
|
89
|
+
const install = closedRecord(extension.install, 'extensions.credential_install.install', [
|
|
90
|
+
'route_template',
|
|
91
|
+
'method',
|
|
95
92
|
]);
|
|
93
|
+
exact(install.method, 'PUT', 'extensions.credential_install.install.method');
|
|
96
94
|
return Object.freeze({
|
|
97
95
|
kind: 'openengine.capsule-credential-install/v1',
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
sealedEnvelopeAlgorithms: Object.freeze(['RSA-OAEP-3072-SHA256']),
|
|
102
|
-
bounds: Object.freeze({
|
|
103
|
-
maxEnvelopeBytes: integer(bounds.max_envelope_bytes, 'extensions.credential_install.bounds.max_envelope_bytes', 1, 1_048_576),
|
|
104
|
-
maxBodyBytes: integer(bounds.max_body_bytes, 'extensions.credential_install.bounds.max_body_bytes', 1, 1_048_576),
|
|
105
|
-
grantTtlSeconds: integer(bounds.grant_ttl_seconds, 'extensions.credential_install.bounds.grant_ttl_seconds', 1, 3_600),
|
|
106
|
-
maxClockSkewSeconds: integer(bounds.max_clock_skew_seconds, 'extensions.credential_install.bounds.max_clock_skew_seconds', 0, 300),
|
|
96
|
+
install: Object.freeze({
|
|
97
|
+
routeTemplate: (0, route_template_js_1.routeTemplate)(install.route_template, 'extensions.credential_install.install.route_template', ['capsule_id']),
|
|
98
|
+
method: 'PUT',
|
|
107
99
|
}),
|
|
100
|
+
maxBodyBytes: integer(extension.max_body_bytes, 'extensions.credential_install.max_body_bytes', 1, 4 * 1024 * 1024),
|
|
108
101
|
});
|
|
109
102
|
}
|
|
@@ -71,29 +71,22 @@ export function parseCredentialInstall(value) {
|
|
|
71
71
|
if (value === undefined || value === null)
|
|
72
72
|
return null;
|
|
73
73
|
const extension = closedRecord(value, 'extensions.credential_install', [
|
|
74
|
-
'kind',
|
|
74
|
+
'kind',
|
|
75
|
+
'install',
|
|
76
|
+
'max_body_bytes',
|
|
75
77
|
]);
|
|
76
78
|
exact(extension.kind, 'openengine.capsule-credential-install/v1', 'extensions.credential_install.kind');
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
exact(install.method, 'PUT', 'extensions.credential_install.install.method');
|
|
81
|
-
exact(extension.upload_url_origin, 'same_origin', 'extensions.credential_install.upload_url_origin');
|
|
82
|
-
exactStringSet(extension.sealed_envelope_algorithms, 'extensions.credential_install.sealed_envelope_algorithms', ['RSA-OAEP-3072-SHA256']);
|
|
83
|
-
const bounds = closedRecord(extension.bounds, 'extensions.credential_install.bounds', [
|
|
84
|
-
'max_envelope_bytes', 'max_body_bytes', 'grant_ttl_seconds', 'max_clock_skew_seconds',
|
|
79
|
+
const install = closedRecord(extension.install, 'extensions.credential_install.install', [
|
|
80
|
+
'route_template',
|
|
81
|
+
'method',
|
|
85
82
|
]);
|
|
83
|
+
exact(install.method, 'PUT', 'extensions.credential_install.install.method');
|
|
86
84
|
return Object.freeze({
|
|
87
85
|
kind: 'openengine.capsule-credential-install/v1',
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
sealedEnvelopeAlgorithms: Object.freeze(['RSA-OAEP-3072-SHA256']),
|
|
92
|
-
bounds: Object.freeze({
|
|
93
|
-
maxEnvelopeBytes: integer(bounds.max_envelope_bytes, 'extensions.credential_install.bounds.max_envelope_bytes', 1, 1_048_576),
|
|
94
|
-
maxBodyBytes: integer(bounds.max_body_bytes, 'extensions.credential_install.bounds.max_body_bytes', 1, 1_048_576),
|
|
95
|
-
grantTtlSeconds: integer(bounds.grant_ttl_seconds, 'extensions.credential_install.bounds.grant_ttl_seconds', 1, 3_600),
|
|
96
|
-
maxClockSkewSeconds: integer(bounds.max_clock_skew_seconds, 'extensions.credential_install.bounds.max_clock_skew_seconds', 0, 300),
|
|
86
|
+
install: Object.freeze({
|
|
87
|
+
routeTemplate: routeTemplate(install.route_template, 'extensions.credential_install.install.route_template', ['capsule_id']),
|
|
88
|
+
method: 'PUT',
|
|
97
89
|
}),
|
|
90
|
+
maxBodyBytes: integer(extension.max_body_bytes, 'extensions.credential_install.max_body_bytes', 1, 4 * 1024 * 1024),
|
|
98
91
|
});
|
|
99
92
|
}
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@the-open-engine/zeroshot",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.34.1",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@the-open-engine/zeroshot",
|
|
9
|
-
"version": "6.
|
|
9
|
+
"version": "6.34.1",
|
|
10
10
|
"hasInstallScript": true,
|
|
11
11
|
"license": "MIT",
|
|
12
12
|
"dependencies": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@the-open-engine/zeroshot",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.34.1",
|
|
4
4
|
"description": "Independent executor–verifier orchestration for software changes.",
|
|
5
5
|
"main": "src/orchestrator.js",
|
|
6
6
|
"bin": {
|
|
@@ -44,6 +44,7 @@
|
|
|
44
44
|
"typecheck:agent-cli-provider": "tsc --project tsconfig.agent-cli-provider.json",
|
|
45
45
|
"typecheck:hosted-target": "tsc --project tsconfig.hosted-target.json",
|
|
46
46
|
"typecheck:hosted-session": "tsc --project tsconfig.hosted-session.json",
|
|
47
|
+
"test:hosted": "npm run build:cluster && node --test tests/private-hosted-cli/*.test.js && npm run test:hosted-target",
|
|
47
48
|
"test:hosted-target": "npm run build:cluster && npm run build:target && node --test tests/hosted-target/*.test.ts",
|
|
48
49
|
"test:target": "npm run build:agent-cli-provider && npm run build:target && node --test tests/target/*.test.ts",
|
|
49
50
|
"typecheck:target": "tsc --project tsconfig.target.json",
|
|
@@ -11,8 +11,10 @@
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
const { spawn, spawnSync } = require('child_process');
|
|
14
|
+
const { createHash } = require('crypto');
|
|
14
15
|
const path = require('path');
|
|
15
16
|
const fs = require('fs');
|
|
17
|
+
const { StringDecoder } = require('string_decoder');
|
|
16
18
|
const { getNestedExecutionRegistry, TaskExecutionHandle } = require('./task-execution-handle');
|
|
17
19
|
const os = require('os');
|
|
18
20
|
const { parseProviderChunk, getProvider } = require('../providers');
|
|
@@ -57,6 +59,8 @@ const {
|
|
|
57
59
|
isStructuredOutputInvalidError,
|
|
58
60
|
} = require('./structured-output-error');
|
|
59
61
|
const TASK_TERMINAL_STATUSES = new Set(['completed', 'failed', 'killed', 'stale']);
|
|
62
|
+
const MAX_CONTROL_PLANE_RECORD_BYTES = 1024 * 1024;
|
|
63
|
+
const LOG_READ_CHUNK_BYTES = 64 * 1024;
|
|
60
64
|
function runCommandWithTimeout(command, args, options = {}, callback = null) {
|
|
61
65
|
const timeout = options.timeout ?? 30000;
|
|
62
66
|
if (timeout <= 0) {
|
|
@@ -1225,11 +1229,20 @@ function createLogFollowState() {
|
|
|
1225
1229
|
pollInterval: null,
|
|
1226
1230
|
statusCheckInterval: null,
|
|
1227
1231
|
resolved: false,
|
|
1228
|
-
lineBuffer:
|
|
1232
|
+
lineBuffer: createLogRecordBuffer(),
|
|
1233
|
+
logDecoder: new StringDecoder('utf8'),
|
|
1229
1234
|
consecutiveExecFailures: 0,
|
|
1230
1235
|
};
|
|
1231
1236
|
}
|
|
1232
1237
|
|
|
1238
|
+
function createLogRecordBuffer() {
|
|
1239
|
+
return {
|
|
1240
|
+
byteLength: 0,
|
|
1241
|
+
fragments: [],
|
|
1242
|
+
oversized: null,
|
|
1243
|
+
};
|
|
1244
|
+
}
|
|
1245
|
+
|
|
1233
1246
|
function lookupLogFilePath(ctPath, taskId) {
|
|
1234
1247
|
try {
|
|
1235
1248
|
return runCommandSync(ctPath, ['get-log-path', taskId], {
|
|
@@ -1310,15 +1323,82 @@ function broadcastAgentLine({ agent, providerName, state, line }) {
|
|
|
1310
1323
|
});
|
|
1311
1324
|
}
|
|
1312
1325
|
|
|
1313
|
-
function
|
|
1314
|
-
|
|
1315
|
-
|
|
1326
|
+
function appendLogRecordFragment(buffer, fragment) {
|
|
1327
|
+
const fragmentBytes = Buffer.byteLength(fragment);
|
|
1328
|
+
buffer.byteLength += fragmentBytes;
|
|
1329
|
+
if (buffer.oversized) {
|
|
1330
|
+
buffer.oversized.digest.update(fragment);
|
|
1331
|
+
return;
|
|
1332
|
+
}
|
|
1333
|
+
if (buffer.byteLength <= MAX_CONTROL_PLANE_RECORD_BYTES) {
|
|
1334
|
+
buffer.fragments.push(fragment);
|
|
1335
|
+
return;
|
|
1336
|
+
}
|
|
1316
1337
|
|
|
1317
|
-
|
|
1318
|
-
|
|
1338
|
+
const retainedPrefix = buffer.fragments.join('');
|
|
1339
|
+
const prefixProbe = `${retainedPrefix}${fragment.slice(0, Math.max(0, 32 - retainedPrefix.length))}`;
|
|
1340
|
+
const timestampPrefix = prefixProbe.match(/^\[\d{13}\]/)?.[0] || '';
|
|
1341
|
+
const digest = createHash('sha256');
|
|
1342
|
+
for (const retained of buffer.fragments) digest.update(retained);
|
|
1343
|
+
digest.update(fragment);
|
|
1344
|
+
buffer.fragments = [];
|
|
1345
|
+
buffer.oversized = { digest, timestampPrefix };
|
|
1346
|
+
}
|
|
1347
|
+
|
|
1348
|
+
function completeLogRecord(buffer, onLine, skipEmpty = false) {
|
|
1349
|
+
let line;
|
|
1350
|
+
if (buffer.oversized) {
|
|
1351
|
+
const digest = buffer.oversized.digest.digest('hex');
|
|
1352
|
+
line =
|
|
1353
|
+
`${buffer.oversized.timestampPrefix}[ZEROSHOT] Provider output record retained in task log ` +
|
|
1354
|
+
`but omitted from the control plane (byte_length=${buffer.byteLength}, sha256=${digest})`;
|
|
1355
|
+
} else {
|
|
1356
|
+
line = buffer.fragments.join('');
|
|
1319
1357
|
}
|
|
1358
|
+
buffer.byteLength = 0;
|
|
1359
|
+
buffer.fragments = [];
|
|
1360
|
+
buffer.oversized = null;
|
|
1361
|
+
if (!skipEmpty || line.trim()) onLine(line);
|
|
1362
|
+
}
|
|
1320
1363
|
|
|
1321
|
-
|
|
1364
|
+
function appendContentToBuffer(state, content, onLine, skipEmpty = false) {
|
|
1365
|
+
let offset = 0;
|
|
1366
|
+
while (offset < content.length) {
|
|
1367
|
+
const newline = content.indexOf('\n', offset);
|
|
1368
|
+
if (newline === -1) {
|
|
1369
|
+
appendLogRecordFragment(state.lineBuffer, content.slice(offset));
|
|
1370
|
+
return;
|
|
1371
|
+
}
|
|
1372
|
+
appendLogRecordFragment(state.lineBuffer, content.slice(offset, newline));
|
|
1373
|
+
completeLogRecord(state.lineBuffer, onLine, skipEmpty);
|
|
1374
|
+
offset = newline + 1;
|
|
1375
|
+
}
|
|
1376
|
+
}
|
|
1377
|
+
|
|
1378
|
+
function replayCompleteLogContent(content, onLine) {
|
|
1379
|
+
const replayState = { lineBuffer: createLogRecordBuffer() };
|
|
1380
|
+
appendContentToBuffer(replayState, content, onLine, true);
|
|
1381
|
+
if (replayState.lineBuffer.byteLength > 0) {
|
|
1382
|
+
completeLogRecord(replayState.lineBuffer, onLine, true);
|
|
1383
|
+
}
|
|
1384
|
+
}
|
|
1385
|
+
|
|
1386
|
+
function readLogFileDelta({ fsModule, logFilePath, state, currentSize, onNewContent }) {
|
|
1387
|
+
const fd = fsModule.openSync(logFilePath, 'r');
|
|
1388
|
+
try {
|
|
1389
|
+
let offset = state.lastSize;
|
|
1390
|
+
const buffer = Buffer.allocUnsafe(LOG_READ_CHUNK_BYTES);
|
|
1391
|
+
while (offset < currentSize) {
|
|
1392
|
+
const requested = Math.min(buffer.length, currentSize - offset);
|
|
1393
|
+
const bytesRead = fsModule.readSync(fd, buffer, 0, requested, offset);
|
|
1394
|
+
if (bytesRead === 0) break;
|
|
1395
|
+
onNewContent(state.logDecoder.write(buffer.subarray(0, bytesRead)));
|
|
1396
|
+
offset += bytesRead;
|
|
1397
|
+
}
|
|
1398
|
+
state.lastSize = offset;
|
|
1399
|
+
} finally {
|
|
1400
|
+
fsModule.closeSync(fd);
|
|
1401
|
+
}
|
|
1322
1402
|
}
|
|
1323
1403
|
|
|
1324
1404
|
function pollLogFileForUpdates({ agent, fsModule, ctPath, taskId, state, onNewContent }) {
|
|
@@ -1340,13 +1420,13 @@ function pollLogFileForUpdates({ agent, fsModule, ctPath, taskId, state, onNewCo
|
|
|
1340
1420
|
const currentSize = stats.size;
|
|
1341
1421
|
|
|
1342
1422
|
if (currentSize > state.lastSize) {
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1423
|
+
readLogFileDelta({
|
|
1424
|
+
fsModule,
|
|
1425
|
+
logFilePath: state.logFilePath,
|
|
1426
|
+
state,
|
|
1427
|
+
currentSize,
|
|
1428
|
+
onNewContent,
|
|
1429
|
+
});
|
|
1350
1430
|
}
|
|
1351
1431
|
} catch (err) {
|
|
1352
1432
|
const error = /** @type {Error} */ (err);
|
|
@@ -2215,7 +2295,8 @@ function createIsolatedLogState(skipStructuredResultCheck = false, nested = fals
|
|
|
2215
2295
|
tailProcess: null,
|
|
2216
2296
|
statusCheckInterval: null,
|
|
2217
2297
|
timeoutTimer: null,
|
|
2218
|
-
lineBuffer:
|
|
2298
|
+
lineBuffer: createLogRecordBuffer(),
|
|
2299
|
+
tailDecoder: new StringDecoder('utf8'),
|
|
2219
2300
|
skipStructuredResultCheck,
|
|
2220
2301
|
nested,
|
|
2221
2302
|
};
|
|
@@ -2376,9 +2457,7 @@ function settleIsolatedTerminalStatus({
|
|
|
2376
2457
|
|
|
2377
2458
|
if (finalReadResult.code === 0 && finalReadResult.stdout) {
|
|
2378
2459
|
state.fullOutput = finalReadResult.stdout;
|
|
2379
|
-
|
|
2380
|
-
if (line.trim()) onLine(line);
|
|
2381
|
-
}
|
|
2460
|
+
replayCompleteLogContent(state.fullOutput, onLine);
|
|
2382
2461
|
}
|
|
2383
2462
|
|
|
2384
2463
|
const vertexModelError =
|
|
@@ -2566,16 +2645,14 @@ function broadcastIsolatedLine({ agent, providerName, taskId, state, line }) {
|
|
|
2566
2645
|
}
|
|
2567
2646
|
|
|
2568
2647
|
function appendIsolatedContent(state, content, onLine) {
|
|
2569
|
-
state
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
for (let i = 0; i < lines.length - 1; i++) {
|
|
2573
|
-
if (lines[i].trim()) {
|
|
2574
|
-
onLine(lines[i]);
|
|
2575
|
-
}
|
|
2576
|
-
}
|
|
2648
|
+
appendContentToBuffer(state, content, onLine, true);
|
|
2649
|
+
}
|
|
2577
2650
|
|
|
2578
|
-
|
|
2651
|
+
function consumeIsolatedTailChunk(state, data, onLine) {
|
|
2652
|
+
const chunk = typeof data === 'string' ? data : state.tailDecoder.write(data);
|
|
2653
|
+
if (!chunk) return;
|
|
2654
|
+
state.fullOutput += chunk;
|
|
2655
|
+
appendIsolatedContent(state, chunk, onLine);
|
|
2579
2656
|
}
|
|
2580
2657
|
|
|
2581
2658
|
function startIsolatedTail({ agent, manager, clusterId, logFilePath, state, onLine }) {
|
|
@@ -2586,9 +2663,7 @@ function startIsolatedTail({ agent, manager, clusterId, logFilePath, state, onLi
|
|
|
2586
2663
|
]);
|
|
2587
2664
|
|
|
2588
2665
|
state.tailProcess.stdout.on('data', (data) => {
|
|
2589
|
-
|
|
2590
|
-
state.fullOutput += chunk;
|
|
2591
|
-
appendIsolatedContent(state, chunk, onLine);
|
|
2666
|
+
consumeIsolatedTailChunk(state, data, onLine);
|
|
2592
2667
|
});
|
|
2593
2668
|
|
|
2594
2669
|
state.tailProcess.stderr.on('data', (data) => {
|
|
@@ -2599,6 +2674,7 @@ function startIsolatedTail({ agent, manager, clusterId, logFilePath, state, onLi
|
|
|
2599
2674
|
});
|
|
2600
2675
|
|
|
2601
2676
|
state.tailProcess.on('close', (exitCode) => {
|
|
2677
|
+
consumeIsolatedTailChunk(state, state.tailDecoder.end(), onLine);
|
|
2602
2678
|
if (!state.taskExited) {
|
|
2603
2679
|
agent._log(`[${agent.id}] tail process exited with code ${exitCode}`);
|
|
2604
2680
|
}
|
|
@@ -3091,4 +3167,7 @@ module.exports = {
|
|
|
3091
3167
|
buildTaskRunArgs,
|
|
3092
3168
|
rebuildProviderSessionAfterCommit,
|
|
3093
3169
|
killTask,
|
|
3170
|
+
createLogRecordBuffer,
|
|
3171
|
+
appendContentToBuffer,
|
|
3172
|
+
consumeIsolatedTailChunk,
|
|
3094
3173
|
};
|
|
@@ -115,7 +115,9 @@ function addAutoApproveArgs(args: string[], options: BuildProviderCommandOptions
|
|
|
115
115
|
const features = optionFeatures(options);
|
|
116
116
|
if (options.autoApprove && features.supportsAutoApprove) {
|
|
117
117
|
const sandboxMode =
|
|
118
|
-
options.executionContext === 'docker'
|
|
118
|
+
options.executionContext === 'docker' || options.executionContext === 'benchmark'
|
|
119
|
+
? 'danger-full-access'
|
|
120
|
+
: 'workspace-write';
|
|
119
121
|
args.push('--sandbox', sandboxMode, '--config', 'approval_policy="never"');
|
|
120
122
|
}
|
|
121
123
|
}
|