@opengeni/runtime 0.6.1 → 0.7.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/dist/{chunk-DYBF7ZEB.js → chunk-RYDCVTMW.js} +1958 -207
- package/dist/chunk-RYDCVTMW.js.map +1 -0
- package/dist/{index-BTo_bZvN.d.ts → index-DIiiwQY2.d.ts} +689 -52
- package/dist/index.d.ts +296 -123
- package/dist/index.js +1907 -809
- package/dist/index.js.map +1 -1
- package/dist/sandbox/index.d.ts +1 -1
- package/dist/sandbox/index.js +79 -3
- package/package.json +21 -20
- package/src/codex-tool-search.ts +185 -31
- package/src/context-compaction.ts +78 -243
- package/src/history-sanitizer.ts +172 -20
- package/src/index.ts +2687 -920
- package/src/metrics.ts +28 -2
- package/src/sandbox/capabilities.ts +12 -3
- package/src/sandbox/channel-a.ts +420 -72
- package/src/sandbox/display-stack.ts +18 -4
- package/src/sandbox/errors.ts +13 -0
- package/src/sandbox/index.ts +398 -112
- package/src/sandbox/op-correlation.ts +70 -0
- package/src/sandbox/providers/index.ts +9 -3
- package/src/sandbox/providers/modal.ts +84 -14
- package/src/sandbox/providers/selfhosted.ts +1 -4
- package/src/sandbox/recording.ts +146 -90
- package/src/sandbox/routing/backend-resolver.ts +144 -10
- package/src/sandbox/routing/routing-session.ts +129 -25
- package/src/sandbox/select.ts +60 -8
- package/src/sandbox/selfhosted/capabilities.ts +59 -25
- package/src/sandbox/selfhosted/control-rpc.ts +160 -28
- package/src/sandbox/selfhosted/fault-rendering.ts +226 -0
- package/src/sandbox/selfhosted/op-observer.ts +54 -0
- package/src/sandbox/selfhosted/op-stream.ts +801 -0
- package/src/sandbox/selfhosted/op-testing.ts +468 -0
- package/src/sandbox/selfhosted/op-transport.ts +151 -0
- package/src/sandbox/selfhosted/retry-policy.ts +177 -0
- package/src/sandbox/selfhosted/session.ts +498 -55
- package/src/sandbox/selfhosted/testing.ts +60 -19
- package/src/sandbox/stream-port.ts +17 -5
- package/src/sandbox/stream-token.ts +8 -2
- package/src/sandbox/terminal-server.ts +18 -4
- package/src/sandbox-computer.ts +332 -70
- package/src/usage-telemetry.ts +73 -0
- package/dist/chunk-DYBF7ZEB.js.map +0 -1
- package/src/image-history.ts +0 -149
- package/src/screenshot-omitted-card.ts +0 -15
package/dist/sandbox/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { collectSandboxEnvironment, parseExposedPorts } from '@opengeni/config';
|
|
2
2
|
export { CAPABILITY_DESCRIPTORS, CapabilityDescriptor, DESKTOP_STREAM_PORT, StreamTokenPayload, StreamTokenPayload as StreamTokenPayloadType, TERMINAL_STREAM_PORT } from '@opengeni/contracts';
|
|
3
3
|
import '@openai/agents/sandbox';
|
|
4
|
-
export { A as ActiveBackendResolverDeps, a as ActiveBackendUnresolvableError, b as ActivePointer, C as ChannelAConflictError, c as ChannelAEmitter, d as ChannelAExecArgs, e as ChannelAExecResult, f as ChannelANotFoundError, g as ChannelASession, h as ChannelAUnsupportedError, i as ChannelAValidationError, j as ControlRpc, D as DEFAULT_DESKTOP_GEOMETRY, k as DISPLAY_STACK_TIMEOUT_MS, l as DesktopGeometry, m as DisplayStackError, n as DisplayStackUnsupportedError, E as EnsureDisplayStackOptions, o as EnsureDisplayStackResult, p as EnsureTerminalServerOptions, q as EnsureTerminalServerResult, r as EstablishedSandboxSession, s as ExposeStreamPortInput, t as ExposeStreamPortResult, u as ExposedPortEndpoint, F as
|
|
4
|
+
export { A as ActiveBackendResolverDeps, a as ActiveBackendUnresolvableError, b as ActivePointer, B as BackendUnresolvableCode, C as ChannelAConflictError, c as ChannelAEmitter, d as ChannelAExecArgs, e as ChannelAExecResult, f as ChannelANotFoundError, g as ChannelASession, h as ChannelAUnsupportedError, i as ChannelAValidationError, j as ControlRpc, D as DEFAULT_DESKTOP_GEOMETRY, k as DISPLAY_STACK_TIMEOUT_MS, l as DesktopGeometry, m as DisplayStackError, n as DisplayStackUnsupportedError, E as EnsureDisplayStackOptions, o as EnsureDisplayStackResult, p as EnsureTerminalServerOptions, q as EnsureTerminalServerResult, r as EstablishedSandboxSession, s as ExposeStreamPortInput, t as ExposeStreamPortResult, u as ExposedPortEndpoint, F as FAULT_FIELD_WHAT_HAPPENED, v as FAULT_FIELD_WHAT_PRESERVED, w as FAULT_FIELD_WHAT_TO_TRY, x as FAULT_FIELD_WHICH_LAYER, L as LiveModalSandboxLeaseAttribution, M as MintStreamTokenInput, y as MockAgentResponder, z as MockAgentResponderOptions, G as MockExecHandler, H as ModalModuleLoader, I as ModalOrphanSweepResult, J as ModalSandboxAttribution, N as NEVER_SENT_DETAIL_KEY, K as NatsControlRpc, O as NatsOpStreamConnection, P as NatsOpStreamTransport, Q as NatsRequestConnection, S as NegotiationContext, T as NumstatEntry, U as OP_STREAM_ACK_INTERVAL_MS, V as OP_STREAM_DEFAULT_WINDOW_BYTES, W as OP_STREAM_RECONNECT_HOLD_MS, X as OP_STREAM_SILENCE_TIMEOUT_MS, Y as OpStreamExecOutcome, Z as OpStreamJournal, _ as OpStreamSubscription, $ as OpStreamTransport, a0 as OpStreamUnavailableError, a1 as PROVIDER_REGISTRY, a2 as ProviderConstructionContext, a3 as ProviderRegistration, a4 as REPOSITORY_DISCOVERY_LIMIT, a5 as RecordingArtifactMetadata, a6 as RecordingCodec, a7 as RecordingContentType, a8 as RecordingError, a9 as RecordingProcess, aa as RecordingUnavailableError, ab as RepositoryDiscoveryDegradedReason, ac as RepositoryDiscoveryResult, ad as ResolvedActiveBackend, ae as RoutableBackendSession, af as RoutableSandbox, ag as RoutingSandboxSession, ah as RoutingSandboxSessionDeps, ai as RoutingTransitionEvent, aj as RoutingUnsupportedError, ak as SELFHOSTED_DEFAULT_TIMEOUT_MS, al as SELFHOSTED_DRAINING_MAX_RETRIES, am as SELFHOSTED_EXEC_DRAINING_MAX_RETRIES, an as SELFHOSTED_IDEMPOTENT_READONLY_OPS, ao as SELFHOSTED_INFRASTRUCTURE_FAULT_CLASSES, ap as SELFHOSTED_NEVER_SENT_MAX_RETRIES, aq as SELFHOSTED_RECONNECT_WINDOW_MS, ar as SELFHOSTED_RELAY_STREAM_PATH, as as SELFHOSTED_RETRY_BACKOFF_BASE_MS, at as SELFHOSTED_RETRY_BACKOFF_CAP_MS, au as SELFHOSTED_RETRY_BACKOFF_FACTOR, av as SELFHOSTED_TIMEOUT_MAX_RETRIES, aw as STREAM_PORT, ax as STREAM_TOKEN_DEFAULT_TTL_SECONDS, ay as SandboxChannelAService, az as SandboxChannelAServiceOptions, aA as SandboxConfigError, aB as SandboxCreatedCallback, aC as SandboxProviderUnavailableError, aD as SandboxResumeStateUnavailableError, aE as SelfhostedApplyDiff, aF as SelfhostedControlError, aG as SelfhostedEditor, aH as SelfhostedEnrollment, aI as SelfhostedExecArgs, aJ as SelfhostedExecResult, aK as SelfhostedImageOutput, aL as SelfhostedLivenessState, aM as SelfhostedNegotiationInput, aN as SelfhostedOpObservation, aO as SelfhostedOpObserver, aP as SelfhostedOpStreamDeps, aQ as SelfhostedRelayConfig, aR as SelfhostedRetryClock, aS as SelfhostedRetryDecision, aT as SelfhostedSandboxClient, aU as SelfhostedSession, aV as SelfhostedSessionBuild, aW as SelfhostedSessionDeps, aX as SelfhostedSessionState, aY as SelfhostedUnavailableReason, aZ as StartRecordingInput, a_ as StreamPortUnavailableError, a$ as SwapTargetEstablishability, b0 as TERMINAL_SERVER_TIMEOUT_MS, b1 as TerminalServerError, b2 as TerminalServerUnsupportedError, b3 as agentErrorToControlError, b4 as assertDescriptorRegistryInvariants, b5 as assertProviderRegistryInvariants, b6 as assertSafeRelPath, b7 as backendSupportsOs, b8 as buildDisplayStackScript, b9 as buildSelfhostedBackendSession, ba as buildStreamUrl, bb as buildTerminalServerScript, bc as contentTypeForCodec, bd as createSandboxClient, be as createSandboxClientForBackend, bf as decideSelfhostedRetry, bg as decodeModalSnapshotId, bh as defaultSelfhostedRetryClock, bi as deletePriorPersistedSnapshot, bj as deleteRecordingArtifacts, bk as deserializeSandboxSessionStateEnvelope, bl as desktopCapableBackend, bm as drainingExhaustedError, bn as drainingMessage, bo as ensureDisplayStack, bp as ensureModalRegistryImage, bq as ensureTerminalServer, br as establishSandboxSessionFromEnvelope, bs as execDeadlineHint, bt as exposeStreamPort, bu as extForCodec, bv as inspectRecordingArtifact, bw as isExecSessionLostBanner, bx as isProviderSandboxNotFoundError, by as isSelfhostedProviderNotFoundError, bz as isWorkspaceEscapeError, bA as makeActiveBackendResolver, bB as mintStreamToken, bC as modalSandboxAttributionEnvironment, bD as modalSandboxAttributionTags, bE as negotiateCapabilities, bF as negotiateSelfhostedCapabilities, bG as nextDurableOpId, bH as offlineAgentError, bI as offlineControlResponse, bJ as opAckSubject, bK as opFrameSubject, bL as parseExecBannerSessionId, bM as parseNumstatZ, bN as parsePorcelainV2, bO as parseUnifiedPatch, bP as payloadTooLargeMessage, bQ as readWorkspaceArchiveFromEnvelopeSessionState, bR as recordingStorageKey, bS as renderSelfhostedFault, bT as restoredSandboxSessionStateFromEntry, bU as runWithToolCallCorrelation, bV as sandboxStateEntryFromRunState, bW as sanitizeOpIdToken, bX as selectBackend, bY as selfhostedFaultClass, bZ as selfhostedLiveness, b_ as selfhostedRetryBackoffMs, b$ as serializeEstablishedSandboxEnvelope, c0 as setSelfhostedApplyDiff, c1 as startRecording, c2 as stopRecording, c3 as stripExecBanner, c4 as subjectFor, c5 as swapTargetEstablishability, c6 as sweepModalOrphanSandboxes, c7 as tagModalSandbox, c8 as tearDownDisplayStack, c9 as tearDownTerminalServer, ca as terminateModalSandboxById, cb as timeoutAgentError, cc as timeoutControlResponse, cd as uploadRecordingArtifact, ce as verifyStreamToken } from '../index-DIiiwQY2.js';
|
|
5
5
|
import 'modal';
|
|
6
6
|
import '@opengeni/agent-proto';
|
package/dist/sandbox/index.js
CHANGED
|
@@ -10,21 +10,43 @@ import {
|
|
|
10
10
|
DISPLAY_STACK_TIMEOUT_MS,
|
|
11
11
|
DisplayStackError,
|
|
12
12
|
DisplayStackUnsupportedError,
|
|
13
|
+
FAULT_FIELD_WHAT_HAPPENED,
|
|
14
|
+
FAULT_FIELD_WHAT_PRESERVED,
|
|
15
|
+
FAULT_FIELD_WHAT_TO_TRY,
|
|
16
|
+
FAULT_FIELD_WHICH_LAYER,
|
|
13
17
|
MockAgentResponder,
|
|
18
|
+
NEVER_SENT_DETAIL_KEY,
|
|
14
19
|
NatsControlRpc,
|
|
20
|
+
NatsOpStreamTransport,
|
|
21
|
+
OP_STREAM_ACK_INTERVAL_MS,
|
|
22
|
+
OP_STREAM_DEFAULT_WINDOW_BYTES,
|
|
23
|
+
OP_STREAM_RECONNECT_HOLD_MS,
|
|
24
|
+
OP_STREAM_SILENCE_TIMEOUT_MS,
|
|
25
|
+
OpStreamUnavailableError,
|
|
15
26
|
PROVIDER_REGISTRY,
|
|
27
|
+
REPOSITORY_DISCOVERY_LIMIT,
|
|
16
28
|
RecordingError,
|
|
17
29
|
RecordingUnavailableError,
|
|
18
30
|
RoutingSandboxSession,
|
|
19
31
|
RoutingUnsupportedError,
|
|
20
32
|
SELFHOSTED_DEFAULT_TIMEOUT_MS,
|
|
33
|
+
SELFHOSTED_DRAINING_MAX_RETRIES,
|
|
34
|
+
SELFHOSTED_EXEC_DRAINING_MAX_RETRIES,
|
|
35
|
+
SELFHOSTED_IDEMPOTENT_READONLY_OPS,
|
|
36
|
+
SELFHOSTED_INFRASTRUCTURE_FAULT_CLASSES,
|
|
37
|
+
SELFHOSTED_NEVER_SENT_MAX_RETRIES,
|
|
21
38
|
SELFHOSTED_RECONNECT_WINDOW_MS,
|
|
22
39
|
SELFHOSTED_RELAY_STREAM_PATH,
|
|
40
|
+
SELFHOSTED_RETRY_BACKOFF_BASE_MS,
|
|
41
|
+
SELFHOSTED_RETRY_BACKOFF_CAP_MS,
|
|
42
|
+
SELFHOSTED_RETRY_BACKOFF_FACTOR,
|
|
43
|
+
SELFHOSTED_TIMEOUT_MAX_RETRIES,
|
|
23
44
|
STREAM_PORT,
|
|
24
45
|
STREAM_TOKEN_DEFAULT_TTL_SECONDS,
|
|
25
46
|
SandboxChannelAService,
|
|
26
47
|
SandboxConfigError,
|
|
27
48
|
SandboxProviderUnavailableError,
|
|
49
|
+
SandboxResumeStateUnavailableError,
|
|
28
50
|
SelfhostedControlError,
|
|
29
51
|
SelfhostedSandboxClient,
|
|
30
52
|
SelfhostedSession,
|
|
@@ -47,17 +69,23 @@ import {
|
|
|
47
69
|
contentTypeForCodec,
|
|
48
70
|
createSandboxClient,
|
|
49
71
|
createSandboxClientForBackend,
|
|
72
|
+
decideSelfhostedRetry,
|
|
50
73
|
decodeModalSnapshotId,
|
|
74
|
+
defaultSelfhostedRetryClock,
|
|
51
75
|
deletePriorPersistedSnapshot,
|
|
52
76
|
deleteRecordingArtifacts,
|
|
53
77
|
deserializeSandboxSessionStateEnvelope,
|
|
54
78
|
desktopCapableBackend,
|
|
79
|
+
drainingExhaustedError,
|
|
80
|
+
drainingMessage,
|
|
55
81
|
ensureDisplayStack,
|
|
56
82
|
ensureModalRegistryImage,
|
|
57
83
|
ensureTerminalServer,
|
|
58
84
|
establishSandboxSessionFromEnvelope,
|
|
85
|
+
execDeadlineHint,
|
|
59
86
|
exposeStreamPort,
|
|
60
87
|
extForCodec,
|
|
88
|
+
inspectRecordingArtifact,
|
|
61
89
|
isExecSessionLostBanner,
|
|
62
90
|
isProviderSandboxNotFoundError,
|
|
63
91
|
isSelfhostedProviderNotFoundError,
|
|
@@ -68,26 +96,35 @@ import {
|
|
|
68
96
|
modalSandboxAttributionTags,
|
|
69
97
|
negotiateCapabilities,
|
|
70
98
|
negotiateSelfhostedCapabilities,
|
|
99
|
+
nextDurableOpId,
|
|
71
100
|
offlineAgentError,
|
|
72
101
|
offlineControlResponse,
|
|
102
|
+
opAckSubject,
|
|
103
|
+
opFrameSubject,
|
|
73
104
|
parseExecBannerSessionId,
|
|
74
105
|
parseExposedPorts,
|
|
75
106
|
parseNumstatZ,
|
|
76
107
|
parsePorcelainV2,
|
|
77
108
|
parseUnifiedPatch,
|
|
78
|
-
|
|
109
|
+
payloadTooLargeMessage,
|
|
79
110
|
readWorkspaceArchiveFromEnvelopeSessionState,
|
|
80
111
|
recordingStorageKey,
|
|
112
|
+
renderSelfhostedFault,
|
|
81
113
|
restoredSandboxSessionStateFromEntry,
|
|
114
|
+
runWithToolCallCorrelation,
|
|
82
115
|
sandboxStateEntryFromRunState,
|
|
116
|
+
sanitizeOpIdToken,
|
|
83
117
|
selectBackend,
|
|
118
|
+
selfhostedFaultClass,
|
|
84
119
|
selfhostedLiveness,
|
|
120
|
+
selfhostedRetryBackoffMs,
|
|
85
121
|
serializeEstablishedSandboxEnvelope,
|
|
86
122
|
setSelfhostedApplyDiff,
|
|
87
123
|
startRecording,
|
|
88
124
|
stopRecording,
|
|
89
125
|
stripExecBanner,
|
|
90
126
|
subjectFor,
|
|
127
|
+
swapTargetEstablishability,
|
|
91
128
|
sweepModalOrphanSandboxes,
|
|
92
129
|
tagModalSandbox,
|
|
93
130
|
tearDownDisplayStack,
|
|
@@ -95,8 +132,9 @@ import {
|
|
|
95
132
|
terminateModalSandboxById,
|
|
96
133
|
timeoutAgentError,
|
|
97
134
|
timeoutControlResponse,
|
|
135
|
+
uploadRecordingArtifact,
|
|
98
136
|
verifyStreamToken
|
|
99
|
-
} from "../chunk-
|
|
137
|
+
} from "../chunk-RYDCVTMW.js";
|
|
100
138
|
export {
|
|
101
139
|
ActiveBackendUnresolvableError,
|
|
102
140
|
CAPABILITY_DESCRIPTORS,
|
|
@@ -109,21 +147,43 @@ export {
|
|
|
109
147
|
DISPLAY_STACK_TIMEOUT_MS,
|
|
110
148
|
DisplayStackError,
|
|
111
149
|
DisplayStackUnsupportedError,
|
|
150
|
+
FAULT_FIELD_WHAT_HAPPENED,
|
|
151
|
+
FAULT_FIELD_WHAT_PRESERVED,
|
|
152
|
+
FAULT_FIELD_WHAT_TO_TRY,
|
|
153
|
+
FAULT_FIELD_WHICH_LAYER,
|
|
112
154
|
MockAgentResponder,
|
|
155
|
+
NEVER_SENT_DETAIL_KEY,
|
|
113
156
|
NatsControlRpc,
|
|
157
|
+
NatsOpStreamTransport,
|
|
158
|
+
OP_STREAM_ACK_INTERVAL_MS,
|
|
159
|
+
OP_STREAM_DEFAULT_WINDOW_BYTES,
|
|
160
|
+
OP_STREAM_RECONNECT_HOLD_MS,
|
|
161
|
+
OP_STREAM_SILENCE_TIMEOUT_MS,
|
|
162
|
+
OpStreamUnavailableError,
|
|
114
163
|
PROVIDER_REGISTRY,
|
|
164
|
+
REPOSITORY_DISCOVERY_LIMIT,
|
|
115
165
|
RecordingError,
|
|
116
166
|
RecordingUnavailableError,
|
|
117
167
|
RoutingSandboxSession,
|
|
118
168
|
RoutingUnsupportedError,
|
|
119
169
|
SELFHOSTED_DEFAULT_TIMEOUT_MS,
|
|
170
|
+
SELFHOSTED_DRAINING_MAX_RETRIES,
|
|
171
|
+
SELFHOSTED_EXEC_DRAINING_MAX_RETRIES,
|
|
172
|
+
SELFHOSTED_IDEMPOTENT_READONLY_OPS,
|
|
173
|
+
SELFHOSTED_INFRASTRUCTURE_FAULT_CLASSES,
|
|
174
|
+
SELFHOSTED_NEVER_SENT_MAX_RETRIES,
|
|
120
175
|
SELFHOSTED_RECONNECT_WINDOW_MS,
|
|
121
176
|
SELFHOSTED_RELAY_STREAM_PATH,
|
|
177
|
+
SELFHOSTED_RETRY_BACKOFF_BASE_MS,
|
|
178
|
+
SELFHOSTED_RETRY_BACKOFF_CAP_MS,
|
|
179
|
+
SELFHOSTED_RETRY_BACKOFF_FACTOR,
|
|
180
|
+
SELFHOSTED_TIMEOUT_MAX_RETRIES,
|
|
122
181
|
STREAM_PORT,
|
|
123
182
|
STREAM_TOKEN_DEFAULT_TTL_SECONDS,
|
|
124
183
|
SandboxChannelAService,
|
|
125
184
|
SandboxConfigError,
|
|
126
185
|
SandboxProviderUnavailableError,
|
|
186
|
+
SandboxResumeStateUnavailableError,
|
|
127
187
|
SelfhostedControlError,
|
|
128
188
|
SelfhostedSandboxClient,
|
|
129
189
|
SelfhostedSession,
|
|
@@ -146,17 +206,23 @@ export {
|
|
|
146
206
|
contentTypeForCodec,
|
|
147
207
|
createSandboxClient,
|
|
148
208
|
createSandboxClientForBackend,
|
|
209
|
+
decideSelfhostedRetry,
|
|
149
210
|
decodeModalSnapshotId,
|
|
211
|
+
defaultSelfhostedRetryClock,
|
|
150
212
|
deletePriorPersistedSnapshot,
|
|
151
213
|
deleteRecordingArtifacts,
|
|
152
214
|
deserializeSandboxSessionStateEnvelope,
|
|
153
215
|
desktopCapableBackend,
|
|
216
|
+
drainingExhaustedError,
|
|
217
|
+
drainingMessage,
|
|
154
218
|
ensureDisplayStack,
|
|
155
219
|
ensureModalRegistryImage,
|
|
156
220
|
ensureTerminalServer,
|
|
157
221
|
establishSandboxSessionFromEnvelope,
|
|
222
|
+
execDeadlineHint,
|
|
158
223
|
exposeStreamPort,
|
|
159
224
|
extForCodec,
|
|
225
|
+
inspectRecordingArtifact,
|
|
160
226
|
isExecSessionLostBanner,
|
|
161
227
|
isProviderSandboxNotFoundError,
|
|
162
228
|
isSelfhostedProviderNotFoundError,
|
|
@@ -167,26 +233,35 @@ export {
|
|
|
167
233
|
modalSandboxAttributionTags,
|
|
168
234
|
negotiateCapabilities,
|
|
169
235
|
negotiateSelfhostedCapabilities,
|
|
236
|
+
nextDurableOpId,
|
|
170
237
|
offlineAgentError,
|
|
171
238
|
offlineControlResponse,
|
|
239
|
+
opAckSubject,
|
|
240
|
+
opFrameSubject,
|
|
172
241
|
parseExecBannerSessionId,
|
|
173
242
|
parseExposedPorts,
|
|
174
243
|
parseNumstatZ,
|
|
175
244
|
parsePorcelainV2,
|
|
176
245
|
parseUnifiedPatch,
|
|
177
|
-
|
|
246
|
+
payloadTooLargeMessage,
|
|
178
247
|
readWorkspaceArchiveFromEnvelopeSessionState,
|
|
179
248
|
recordingStorageKey,
|
|
249
|
+
renderSelfhostedFault,
|
|
180
250
|
restoredSandboxSessionStateFromEntry,
|
|
251
|
+
runWithToolCallCorrelation,
|
|
181
252
|
sandboxStateEntryFromRunState,
|
|
253
|
+
sanitizeOpIdToken,
|
|
182
254
|
selectBackend,
|
|
255
|
+
selfhostedFaultClass,
|
|
183
256
|
selfhostedLiveness,
|
|
257
|
+
selfhostedRetryBackoffMs,
|
|
184
258
|
serializeEstablishedSandboxEnvelope,
|
|
185
259
|
setSelfhostedApplyDiff,
|
|
186
260
|
startRecording,
|
|
187
261
|
stopRecording,
|
|
188
262
|
stripExecBanner,
|
|
189
263
|
subjectFor,
|
|
264
|
+
swapTargetEstablishability,
|
|
190
265
|
sweepModalOrphanSandboxes,
|
|
191
266
|
tagModalSandbox,
|
|
192
267
|
tearDownDisplayStack,
|
|
@@ -194,6 +269,7 @@ export {
|
|
|
194
269
|
terminateModalSandboxById,
|
|
195
270
|
timeoutAgentError,
|
|
196
271
|
timeoutControlResponse,
|
|
272
|
+
uploadRecordingArtifact,
|
|
197
273
|
verifyStreamToken
|
|
198
274
|
};
|
|
199
275
|
//# sourceMappingURL=index.js.map
|
package/package.json
CHANGED
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opengeni/runtime",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"type": "module",
|
|
3
|
+
"version": "0.7.1",
|
|
5
4
|
"license": "Apache-2.0",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "git+https://github.com/Cloudgeni-ai/opengeni.git",
|
|
8
|
+
"directory": "packages/runtime"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist",
|
|
12
|
+
"src"
|
|
13
|
+
],
|
|
14
|
+
"type": "module",
|
|
6
15
|
"main": "./dist/index.js",
|
|
7
16
|
"module": "./dist/index.js",
|
|
8
17
|
"types": "./dist/index.d.ts",
|
|
@@ -16,32 +25,24 @@
|
|
|
16
25
|
"import": "./dist/sandbox/index.js"
|
|
17
26
|
}
|
|
18
27
|
},
|
|
19
|
-
"files": [
|
|
20
|
-
"dist",
|
|
21
|
-
"src"
|
|
22
|
-
],
|
|
23
28
|
"publishConfig": {
|
|
24
29
|
"access": "public",
|
|
25
30
|
"provenance": true
|
|
26
31
|
},
|
|
27
32
|
"scripts": {
|
|
28
33
|
"build": "tsup",
|
|
29
|
-
"typecheck": "
|
|
34
|
+
"typecheck": "tsgo --noEmit",
|
|
30
35
|
"prepublishOnly": "bash ../../scripts/prepublish-guard"
|
|
31
36
|
},
|
|
32
37
|
"dependencies": {
|
|
33
|
-
"@
|
|
34
|
-
"@
|
|
35
|
-
"@
|
|
36
|
-
"@
|
|
37
|
-
"@
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
|
|
42
|
-
"repository": {
|
|
43
|
-
"type": "git",
|
|
44
|
-
"url": "git+https://github.com/Cloudgeni-ai/opengeni.git",
|
|
45
|
-
"directory": "packages/runtime"
|
|
38
|
+
"@noble/hashes": "^1.8.0",
|
|
39
|
+
"@openai/agents": "0.13.3",
|
|
40
|
+
"@openai/agents-extensions": "0.13.3",
|
|
41
|
+
"@opengeni/agent-proto": "^0.3.0",
|
|
42
|
+
"@opengeni/codex": "^0.2.3",
|
|
43
|
+
"@opengeni/config": "^0.5.1",
|
|
44
|
+
"@opengeni/contracts": "^0.10.0",
|
|
45
|
+
"modal": "0.7.6",
|
|
46
|
+
"openai": "6.47.0"
|
|
46
47
|
}
|
|
47
48
|
}
|
package/src/codex-tool-search.ts
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
// from model context), searches by capability, and only the matched tools are
|
|
11
11
|
// disclosed back and become callable.
|
|
12
12
|
//
|
|
13
|
-
// PROVEN LIVE (Phase 0 probe against /codex/responses on gpt-5.
|
|
13
|
+
// PROVEN LIVE (Phase 0 probe against /codex/responses on gpt-5.6-sol): the backend
|
|
14
14
|
// HONORS `defer_loading:true` on function tools — 50 fat tools dropped input_tokens
|
|
15
15
|
// 6766 → 108 — AND makes a tool callable purely because a prior `tool_search_output`
|
|
16
16
|
// disclosed it (V3). The model emits `tool_search_call` on our slug.
|
|
@@ -33,13 +33,15 @@ const DEFAULT_SEARCH_LIMIT = 8;
|
|
|
33
33
|
const MAX_SEARCH_LIMIT = 20;
|
|
34
34
|
|
|
35
35
|
/** True for a materialized codex_apps connector function tool. */
|
|
36
|
-
export function isCodexAppsFunctionTool(
|
|
36
|
+
export function isCodexAppsFunctionTool(
|
|
37
|
+
tool: unknown,
|
|
38
|
+
): tool is Tool & { name: string; deferLoading?: boolean } {
|
|
37
39
|
return (
|
|
38
|
-
!!tool
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
!!tool &&
|
|
41
|
+
typeof tool === "object" &&
|
|
42
|
+
(tool as { type?: unknown }).type === "function" &&
|
|
43
|
+
typeof (tool as { name?: unknown }).name === "string" &&
|
|
44
|
+
(tool as { name: string }).name.startsWith(CODEX_APPS_TOOL_PREFIX)
|
|
43
45
|
);
|
|
44
46
|
}
|
|
45
47
|
|
|
@@ -47,10 +49,48 @@ export function isCodexAppsFunctionTool(tool: unknown): tool is Tool & { name: s
|
|
|
47
49
|
// should match on capability words, not drown in glue words (parity with
|
|
48
50
|
// codex-rs, whose search normalizes tokens server-side).
|
|
49
51
|
const STOPWORDS = new Set([
|
|
50
|
-
"a",
|
|
51
|
-
"
|
|
52
|
-
"
|
|
53
|
-
"
|
|
52
|
+
"a",
|
|
53
|
+
"an",
|
|
54
|
+
"the",
|
|
55
|
+
"and",
|
|
56
|
+
"or",
|
|
57
|
+
"of",
|
|
58
|
+
"to",
|
|
59
|
+
"in",
|
|
60
|
+
"on",
|
|
61
|
+
"for",
|
|
62
|
+
"with",
|
|
63
|
+
"by",
|
|
64
|
+
"at",
|
|
65
|
+
"is",
|
|
66
|
+
"are",
|
|
67
|
+
"be",
|
|
68
|
+
"do",
|
|
69
|
+
"does",
|
|
70
|
+
"my",
|
|
71
|
+
"me",
|
|
72
|
+
"your",
|
|
73
|
+
"you",
|
|
74
|
+
"it",
|
|
75
|
+
"its",
|
|
76
|
+
"this",
|
|
77
|
+
"that",
|
|
78
|
+
"from",
|
|
79
|
+
"as",
|
|
80
|
+
"up",
|
|
81
|
+
"out",
|
|
82
|
+
"all",
|
|
83
|
+
"some",
|
|
84
|
+
"any",
|
|
85
|
+
"can",
|
|
86
|
+
"will",
|
|
87
|
+
"would",
|
|
88
|
+
"should",
|
|
89
|
+
"want",
|
|
90
|
+
"need",
|
|
91
|
+
"please",
|
|
92
|
+
"user",
|
|
93
|
+
"users",
|
|
54
94
|
]);
|
|
55
95
|
|
|
56
96
|
/** Light suffix stemmer so "emails"/"email", "creating"/"create" co-match (min-stem guards, no over-stripping). */
|
|
@@ -75,9 +115,15 @@ function tokenize(text: string): string[] {
|
|
|
75
115
|
/** The searchable text of a connector tool: name (weighted ×2) + description + param names. */
|
|
76
116
|
function toolSearchText(tool: Tool): string {
|
|
77
117
|
const raw = (tool as { name?: string }).name ?? "";
|
|
78
|
-
const name = raw.startsWith(CODEX_APPS_TOOL_PREFIX)
|
|
79
|
-
|
|
80
|
-
|
|
118
|
+
const name = raw.startsWith(CODEX_APPS_TOOL_PREFIX)
|
|
119
|
+
? raw.slice(CODEX_APPS_TOOL_PREFIX.length)
|
|
120
|
+
: raw;
|
|
121
|
+
const description =
|
|
122
|
+
typeof (tool as { description?: unknown }).description === "string"
|
|
123
|
+
? (tool as { description: string }).description
|
|
124
|
+
: "";
|
|
125
|
+
const params = (tool as { parameters?: { properties?: Record<string, unknown> } }).parameters
|
|
126
|
+
?.properties;
|
|
81
127
|
const paramNames = params && typeof params === "object" ? Object.keys(params).join(" ") : "";
|
|
82
128
|
return `${name} ${name} ${description} ${paramNames}`;
|
|
83
129
|
}
|
|
@@ -127,12 +173,20 @@ export function bm25RankTools(tools: Tool[], query: string, limit: number): Tool
|
|
|
127
173
|
function parseSearchArgs(raw: unknown): { query: string; limit: number } {
|
|
128
174
|
let obj: Record<string, unknown> = {};
|
|
129
175
|
try {
|
|
130
|
-
obj =
|
|
176
|
+
obj =
|
|
177
|
+
typeof raw === "string"
|
|
178
|
+
? raw.length
|
|
179
|
+
? JSON.parse(raw)
|
|
180
|
+
: {}
|
|
181
|
+
: raw && typeof raw === "object"
|
|
182
|
+
? (raw as Record<string, unknown>)
|
|
183
|
+
: {};
|
|
131
184
|
} catch {
|
|
132
185
|
obj = {};
|
|
133
186
|
}
|
|
134
187
|
const query = typeof obj.query === "string" ? obj.query : "";
|
|
135
|
-
const limitRaw =
|
|
188
|
+
const limitRaw =
|
|
189
|
+
typeof obj.limit === "number" && Number.isFinite(obj.limit) ? obj.limit : DEFAULT_SEARCH_LIMIT;
|
|
136
190
|
return { query, limit: Math.max(1, Math.min(MAX_SEARCH_LIMIT, Math.round(limitRaw))) };
|
|
137
191
|
}
|
|
138
192
|
|
|
@@ -147,10 +201,12 @@ function parseSearchArgs(raw: unknown): { query: string; limit: number } {
|
|
|
147
201
|
*/
|
|
148
202
|
export function renderSearchToolDescription(connectorNamespaces: ReadonlySet<string>): string {
|
|
149
203
|
const base =
|
|
150
|
-
"Search the user's connected app tools by capability. "
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
const sources = Array.from(connectorNamespaces)
|
|
204
|
+
"Search the user's connected app tools by capability. " +
|
|
205
|
+
'Describe in plain language WHAT you need to do (for example: "send an email", "create a calendar event") ' +
|
|
206
|
+
"rather than guessing exact tool names. Returns the matching connector tools, which then become callable.";
|
|
207
|
+
const sources = Array.from(connectorNamespaces)
|
|
208
|
+
.filter((n) => typeof n === "string" && n.length > 0)
|
|
209
|
+
.sort();
|
|
154
210
|
if (sources.length === 0) {
|
|
155
211
|
return `${base}\nConnected sources: none currently available.`;
|
|
156
212
|
}
|
|
@@ -160,7 +216,10 @@ export function renderSearchToolDescription(connectorNamespaces: ReadonlySet<str
|
|
|
160
216
|
const SEARCH_TOOL_PARAMETERS = {
|
|
161
217
|
type: "object",
|
|
162
218
|
properties: {
|
|
163
|
-
query: {
|
|
219
|
+
query: {
|
|
220
|
+
type: "string",
|
|
221
|
+
description: "Plain-language description of the capability you need.",
|
|
222
|
+
},
|
|
164
223
|
limit: { type: "number", description: "Maximum number of tools to return (default 8)." },
|
|
165
224
|
},
|
|
166
225
|
required: ["query"],
|
|
@@ -173,7 +232,10 @@ const SEARCH_TOOL_PARAMETERS = {
|
|
|
173
232
|
* return — the SDK emits the disclosing `tool_search_output` and flips the loaded
|
|
174
233
|
* gate; returning copies would throw). Stateless — reads the pool per call.
|
|
175
234
|
*/
|
|
176
|
-
function codexToolSearchExecutor(args: {
|
|
235
|
+
function codexToolSearchExecutor(args: {
|
|
236
|
+
availableTools?: Tool[];
|
|
237
|
+
toolCall?: { arguments?: unknown };
|
|
238
|
+
}): Tool[] {
|
|
177
239
|
const deferred = (args.availableTools ?? []).filter(isCodexAppsFunctionTool);
|
|
178
240
|
if (deferred.length === 0) return [];
|
|
179
241
|
const { query, limit } = parseSearchArgs(args.toolCall?.arguments);
|
|
@@ -182,16 +244,79 @@ function codexToolSearchExecutor(args: { availableTools?: Tool[]; toolCall?: { a
|
|
|
182
244
|
|
|
183
245
|
const NO_NAMESPACES: ReadonlySet<string> = new Set();
|
|
184
246
|
|
|
185
|
-
/**
|
|
186
|
-
|
|
247
|
+
/** True when the namespace set contains at least one usable (non-empty string) source — mirrors {@link renderSearchToolDescription}'s filter, so it is TRUE exactly when the render produces the "following sources" list and FALSE when it produces "none currently available". */
|
|
248
|
+
function hasConnectorSources(connectorNamespaces: ReadonlySet<string>): boolean {
|
|
249
|
+
for (const namespace of connectorNamespaces) {
|
|
250
|
+
if (typeof namespace === "string" && namespace.length > 0) {
|
|
251
|
+
return true;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
return false;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* A per-TURN freeze cell for the tool_search description (AM-8). The connector Set
|
|
259
|
+
* `installCodexToolSearch` reads is LIVE and by-reference — it fills as the turn's
|
|
260
|
+
* codex_apps tools/list resolves and can change between a turn's model calls.
|
|
261
|
+
* Re-rendering the description per call from a changed Set flips the tools block,
|
|
262
|
+
* and because tools precede the history in the request prefix, ANY change misses the
|
|
263
|
+
* ENTIRE conversation prefix from that point on — a proven prompt-cache breaker.
|
|
264
|
+
*
|
|
265
|
+
* We therefore freeze the description ONCE, at the first model call whose Set has
|
|
266
|
+
* been populated (connectors discovered), and reuse that frozen string for the rest
|
|
267
|
+
* of the turn — trading a slightly staler connector list for a byte-stable prefix.
|
|
268
|
+
* The freeze is created per {@link installCodexToolSearch} (once per turn) and shared
|
|
269
|
+
* by reference into every clone re-install, so all of a turn's clones agree.
|
|
270
|
+
*/
|
|
271
|
+
export type CodexToolSearchDescriptionFreeze = { value: string | null };
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Resolve the tool_search description for this model call, honoring the per-turn
|
|
275
|
+
* freeze (AM-8):
|
|
276
|
+
* - Already frozen ⇒ return the frozen string (byte-stable for the rest of the turn).
|
|
277
|
+
* - Not yet frozen + connectors DISCOVERED (non-empty Set) ⇒ render and FREEZE it,
|
|
278
|
+
* locking the discovered list against a later same-turn Set mutation.
|
|
279
|
+
* - Not yet frozen + Set still EMPTY ⇒ render live ("none currently available") but
|
|
280
|
+
* do NOT freeze. This is the load-bearing safety of AM-8: the Set fills lazily and
|
|
281
|
+
* best-effort, so an empty Set means "not discovered yet", not "no connectors".
|
|
282
|
+
* Freezing "none" here would silently disable the turn's connectors (capability
|
|
283
|
+
* loss). Leaving it unfrozen is still byte-stable while the Set stays empty (the
|
|
284
|
+
* empty render is a constant), and lets a later call freeze the real list once it
|
|
285
|
+
* resolves — at most ONE prefix transition, versus today's per-call churn.
|
|
286
|
+
* With no freeze cell (the default / direct callers + tests) this is a live render,
|
|
287
|
+
* byte-for-byte the pre-AM-8 behavior.
|
|
288
|
+
*/
|
|
289
|
+
function resolveSearchToolDescription(
|
|
290
|
+
connectorNamespaces: ReadonlySet<string>,
|
|
291
|
+
freeze?: CodexToolSearchDescriptionFreeze,
|
|
292
|
+
): string {
|
|
293
|
+
if (freeze?.value != null) {
|
|
294
|
+
return freeze.value;
|
|
295
|
+
}
|
|
296
|
+
const rendered = renderSearchToolDescription(connectorNamespaces);
|
|
297
|
+
if (freeze && hasConnectorSources(connectorNamespaces)) {
|
|
298
|
+
freeze.value = rendered;
|
|
299
|
+
}
|
|
300
|
+
return rendered;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/** Build the client-executed tool_search tool from an already-rendered description. */
|
|
304
|
+
function buildCodexToolSearchToolFromDescription(description: string): Tool {
|
|
187
305
|
return toolSearchTool({
|
|
188
306
|
execution: "client",
|
|
189
|
-
description
|
|
307
|
+
description,
|
|
190
308
|
parameters: SEARCH_TOOL_PARAMETERS as unknown as Record<string, unknown>,
|
|
191
309
|
execute: codexToolSearchExecutor as never,
|
|
192
310
|
}) as unknown as Tool;
|
|
193
311
|
}
|
|
194
312
|
|
|
313
|
+
/** Build the client-executed tool_search tool that discloses codex_apps connectors on demand. */
|
|
314
|
+
export function buildCodexToolSearchTool(
|
|
315
|
+
connectorNamespaces: ReadonlySet<string> = NO_NAMESPACES,
|
|
316
|
+
): Tool {
|
|
317
|
+
return buildCodexToolSearchToolFromDescription(renderSearchToolDescription(connectorNamespaces));
|
|
318
|
+
}
|
|
319
|
+
|
|
195
320
|
/** True for the built-in tool_search tool (so we never add a second one). */
|
|
196
321
|
function isToolSearchTool(tool: unknown): boolean {
|
|
197
322
|
const t = tool as { name?: unknown; providerData?: { type?: unknown } } | null;
|
|
@@ -214,16 +339,26 @@ function isToolSearchTool(tool: unknown): boolean {
|
|
|
214
339
|
* reflects the LIVE connector namespaces, so an empty turn reads
|
|
215
340
|
* "none currently available".
|
|
216
341
|
*/
|
|
217
|
-
export function applyCodexToolSearch(
|
|
342
|
+
export function applyCodexToolSearch(
|
|
343
|
+
tools: Tool[],
|
|
344
|
+
connectorNamespaces: ReadonlySet<string> = NO_NAMESPACES,
|
|
345
|
+
descriptionFreeze?: CodexToolSearchDescriptionFreeze,
|
|
346
|
+
): Tool[] {
|
|
218
347
|
for (const tool of tools) {
|
|
219
|
-
if (
|
|
348
|
+
if (
|
|
349
|
+
isCodexAppsFunctionTool(tool) &&
|
|
350
|
+
(tool as { deferLoading?: boolean }).deferLoading !== true
|
|
351
|
+
) {
|
|
220
352
|
(tool as { deferLoading?: boolean }).deferLoading = true;
|
|
221
353
|
}
|
|
222
354
|
}
|
|
223
355
|
if (tools.some(isToolSearchTool)) {
|
|
224
356
|
return tools;
|
|
225
357
|
}
|
|
226
|
-
|
|
358
|
+
// AM-8: render through the per-turn freeze so the tools-block prefix stays
|
|
359
|
+
// byte-stable across a turn's model calls once connectors are discovered.
|
|
360
|
+
const description = resolveSearchToolDescription(connectorNamespaces, descriptionFreeze);
|
|
361
|
+
return [...tools, buildCodexToolSearchToolFromDescription(description)];
|
|
227
362
|
}
|
|
228
363
|
|
|
229
364
|
type CloneCapableAgent = {
|
|
@@ -251,15 +386,34 @@ type CloneCapableAgent = {
|
|
|
251
386
|
* (prepareAgentTools), so by the time the wrapper post-processes getAllTools the
|
|
252
387
|
* current turn's connector sources are known.
|
|
253
388
|
*/
|
|
254
|
-
export function installCodexToolSearch(
|
|
389
|
+
export function installCodexToolSearch(
|
|
390
|
+
agent: CloneCapableAgent,
|
|
391
|
+
connectorNamespaces: ReadonlySet<string> = NO_NAMESPACES,
|
|
392
|
+
): void {
|
|
393
|
+
// ONE freeze cell per install (i.e. per turn), shared BY REFERENCE into every
|
|
394
|
+
// clone re-install below so the whole turn — the built agent and every clone the
|
|
395
|
+
// sandbox runtime resolves tools on — agrees on the same frozen description
|
|
396
|
+
// (AM-8). Created here, at the top-level install, never per clone.
|
|
397
|
+
installCodexToolSearchWithFreeze(agent, connectorNamespaces, { value: null });
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
function installCodexToolSearchWithFreeze(
|
|
401
|
+
agent: CloneCapableAgent,
|
|
402
|
+
connectorNamespaces: ReadonlySet<string>,
|
|
403
|
+
descriptionFreeze: CodexToolSearchDescriptionFreeze,
|
|
404
|
+
): void {
|
|
255
405
|
const originalGetAllTools = agent.getAllTools.bind(agent);
|
|
256
406
|
agent.getAllTools = (async (runContext: unknown) =>
|
|
257
|
-
applyCodexToolSearch(
|
|
407
|
+
applyCodexToolSearch(
|
|
408
|
+
await originalGetAllTools(runContext),
|
|
409
|
+
connectorNamespaces,
|
|
410
|
+
descriptionFreeze,
|
|
411
|
+
)) as typeof agent.getAllTools;
|
|
258
412
|
const originalClone = agent.clone?.bind(agent);
|
|
259
413
|
if (originalClone) {
|
|
260
414
|
const cloneWithToolSearch: NonNullable<CloneCapableAgent["clone"]> = (config: unknown) => {
|
|
261
415
|
const cloned = originalClone(config);
|
|
262
|
-
|
|
416
|
+
installCodexToolSearchWithFreeze(cloned, connectorNamespaces, descriptionFreeze);
|
|
263
417
|
return cloned;
|
|
264
418
|
};
|
|
265
419
|
agent.clone = cloneWithToolSearch;
|