@opengeni/runtime 0.4.0 → 0.5.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/dist/{chunk-HGQ252FL.js → chunk-Q36E4MDM.js} +17 -2
- package/dist/chunk-Q36E4MDM.js.map +1 -0
- package/dist/{index-CSGkld-v.d.ts → index-BrdnxaAW.d.ts} +5 -3
- package/dist/index.d.ts +20 -3
- package/dist/index.js +25 -7
- package/dist/index.js.map +1 -1
- package/dist/sandbox/index.d.ts +1 -1
- package/dist/sandbox/index.js +1 -1
- package/package.json +1 -1
- package/src/index.ts +55 -6
- package/src/sandbox/selfhosted/session.ts +32 -4
- package/dist/chunk-HGQ252FL.js.map +0 -1
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 FinalizeRecordingResult, L as LiveModalSandboxLeaseAttribution, M as MintStreamTokenInput, v as MockAgentResponder, w as MockAgentResponderOptions, x as MockExecHandler, y as ModalOrphanSweepResult, z as ModalSandboxAttribution, N as NatsControlRpc, B as NatsRequestConnection, G as NegotiationContext, H as NumstatEntry, P as PROVIDER_REGISTRY, I as ProviderConstructionContext, J as ProviderRegistration, K as RecordingCodec, O as RecordingContentType, Q as RecordingError, S as RecordingProcess, T as RecordingUnavailableError, U as ResolvedActiveBackend, V as RoutableBackendSession, W as RoutableSandbox, X as RoutingSandboxSession, Y as RoutingSandboxSessionDeps, Z as RoutingTransitionEvent, _ as RoutingUnsupportedError, $ as SELFHOSTED_DEFAULT_TIMEOUT_MS, a0 as SELFHOSTED_RECONNECT_WINDOW_MS, a1 as SELFHOSTED_RELAY_STREAM_PATH, a2 as STREAM_PORT, a3 as STREAM_TOKEN_DEFAULT_TTL_SECONDS, a4 as SandboxChannelAService, a5 as SandboxChannelAServiceOptions, a6 as SandboxConfigError, a7 as SandboxCreatedCallback, a8 as SandboxProviderUnavailableError, a9 as SelfhostedApplyDiff, aa as SelfhostedControlError, ab as SelfhostedEditor, ac as SelfhostedEnrollment, ad as SelfhostedExecArgs, ae as SelfhostedExecResult, af as SelfhostedImageOutput, ag as SelfhostedLivenessState, ah as SelfhostedNegotiationInput, ai as SelfhostedRelayConfig, aj as SelfhostedSandboxClient, ak as SelfhostedSession, al as SelfhostedSessionBuild, am as SelfhostedSessionDeps, an as SelfhostedSessionState, ao as SelfhostedUnavailableReason, ap as StartRecordingInput, aq as StreamPortUnavailableError, ar as TERMINAL_SERVER_TIMEOUT_MS, as as TerminalServerError, at as TerminalServerUnsupportedError, au as agentErrorToControlError, av as assertDescriptorRegistryInvariants, aw as assertProviderRegistryInvariants, ax as assertSafeRelPath, ay as backendSupportsOs, az as buildDisplayStackScript, aA as buildSelfhostedBackendSession, aB as buildStreamUrl, aC as buildTerminalServerScript, aD as contentTypeForCodec, aE as createSandboxClient, aF as createSandboxClientForBackend, aG as decodeModalSnapshotId, aH as deletePriorPersistedSnapshot, aI as deleteRecordingArtifacts, aJ as deserializeSandboxSessionStateEnvelope, aK as desktopCapableBackend, aL as ensureDisplayStack, aM as ensureTerminalServer, aN as establishSandboxSessionFromEnvelope, aO as exposeStreamPort, aP as extForCodec, aQ as isExecSessionLostBanner, aR as isProviderSandboxNotFoundError, aS as isSelfhostedProviderNotFoundError, aT as isWorkspaceEscapeError, aU as makeActiveBackendResolver, aV as mintStreamToken, aW as modalSandboxAttributionEnvironment, aX as modalSandboxAttributionTags, aY as negotiateCapabilities, aZ as negotiateSelfhostedCapabilities, a_ as offlineAgentError, a$ as offlineControlResponse, b0 as parseExecBannerSessionId, b1 as parseNumstatZ, b2 as parsePorcelainV2, b3 as parseUnifiedPatch, b4 as readRecordingBytes, b5 as readWorkspaceArchiveFromEnvelopeSessionState, b6 as recordingStorageKey, b7 as restoredSandboxSessionStateFromEntry, b8 as sandboxStateEntryFromRunState, b9 as selectBackend, ba as selfhostedLiveness, bb as serializeEstablishedSandboxEnvelope, bc as setSelfhostedApplyDiff, bd as startRecording, be as stopRecording, bf as stripExecBanner, bg as subjectFor, bh as sweepModalOrphanSandboxes, bi as tagModalSandbox, bj as tearDownDisplayStack, bk as tearDownTerminalServer, bl as terminateModalSandboxById, bm as timeoutAgentError, bn as timeoutControlResponse, bo as verifyStreamToken } from '../index-
|
|
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 FinalizeRecordingResult, L as LiveModalSandboxLeaseAttribution, M as MintStreamTokenInput, v as MockAgentResponder, w as MockAgentResponderOptions, x as MockExecHandler, y as ModalOrphanSweepResult, z as ModalSandboxAttribution, N as NatsControlRpc, B as NatsRequestConnection, G as NegotiationContext, H as NumstatEntry, P as PROVIDER_REGISTRY, I as ProviderConstructionContext, J as ProviderRegistration, K as RecordingCodec, O as RecordingContentType, Q as RecordingError, S as RecordingProcess, T as RecordingUnavailableError, U as ResolvedActiveBackend, V as RoutableBackendSession, W as RoutableSandbox, X as RoutingSandboxSession, Y as RoutingSandboxSessionDeps, Z as RoutingTransitionEvent, _ as RoutingUnsupportedError, $ as SELFHOSTED_DEFAULT_TIMEOUT_MS, a0 as SELFHOSTED_RECONNECT_WINDOW_MS, a1 as SELFHOSTED_RELAY_STREAM_PATH, a2 as STREAM_PORT, a3 as STREAM_TOKEN_DEFAULT_TTL_SECONDS, a4 as SandboxChannelAService, a5 as SandboxChannelAServiceOptions, a6 as SandboxConfigError, a7 as SandboxCreatedCallback, a8 as SandboxProviderUnavailableError, a9 as SelfhostedApplyDiff, aa as SelfhostedControlError, ab as SelfhostedEditor, ac as SelfhostedEnrollment, ad as SelfhostedExecArgs, ae as SelfhostedExecResult, af as SelfhostedImageOutput, ag as SelfhostedLivenessState, ah as SelfhostedNegotiationInput, ai as SelfhostedRelayConfig, aj as SelfhostedSandboxClient, ak as SelfhostedSession, al as SelfhostedSessionBuild, am as SelfhostedSessionDeps, an as SelfhostedSessionState, ao as SelfhostedUnavailableReason, ap as StartRecordingInput, aq as StreamPortUnavailableError, ar as TERMINAL_SERVER_TIMEOUT_MS, as as TerminalServerError, at as TerminalServerUnsupportedError, au as agentErrorToControlError, av as assertDescriptorRegistryInvariants, aw as assertProviderRegistryInvariants, ax as assertSafeRelPath, ay as backendSupportsOs, az as buildDisplayStackScript, aA as buildSelfhostedBackendSession, aB as buildStreamUrl, aC as buildTerminalServerScript, aD as contentTypeForCodec, aE as createSandboxClient, aF as createSandboxClientForBackend, aG as decodeModalSnapshotId, aH as deletePriorPersistedSnapshot, aI as deleteRecordingArtifacts, aJ as deserializeSandboxSessionStateEnvelope, aK as desktopCapableBackend, aL as ensureDisplayStack, aM as ensureTerminalServer, aN as establishSandboxSessionFromEnvelope, aO as exposeStreamPort, aP as extForCodec, aQ as isExecSessionLostBanner, aR as isProviderSandboxNotFoundError, aS as isSelfhostedProviderNotFoundError, aT as isWorkspaceEscapeError, aU as makeActiveBackendResolver, aV as mintStreamToken, aW as modalSandboxAttributionEnvironment, aX as modalSandboxAttributionTags, aY as negotiateCapabilities, aZ as negotiateSelfhostedCapabilities, a_ as offlineAgentError, a$ as offlineControlResponse, b0 as parseExecBannerSessionId, b1 as parseNumstatZ, b2 as parsePorcelainV2, b3 as parseUnifiedPatch, b4 as readRecordingBytes, b5 as readWorkspaceArchiveFromEnvelopeSessionState, b6 as recordingStorageKey, b7 as restoredSandboxSessionStateFromEntry, b8 as sandboxStateEntryFromRunState, b9 as selectBackend, ba as selfhostedLiveness, bb as serializeEstablishedSandboxEnvelope, bc as setSelfhostedApplyDiff, bd as startRecording, be as stopRecording, bf as stripExecBanner, bg as subjectFor, bh as sweepModalOrphanSandboxes, bi as tagModalSandbox, bj as tearDownDisplayStack, bk as tearDownTerminalServer, bl as terminateModalSandboxById, bm as timeoutAgentError, bn as timeoutControlResponse, bo as verifyStreamToken } from '../index-BrdnxaAW.js';
|
|
5
5
|
import 'modal';
|
|
6
6
|
import '@opengeni/agent-proto';
|
package/dist/sandbox/index.js
CHANGED
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -937,6 +937,25 @@ export function appendSessionInstructions(composed: string, sessionInstructions?
|
|
|
937
937
|
return trimmed ? `${composed} ${trimmed}` : composed;
|
|
938
938
|
}
|
|
939
939
|
|
|
940
|
+
/**
|
|
941
|
+
* Appends the generic programmatic-tool-calling (toolspace) directive to the
|
|
942
|
+
* composed workspace + CORE instructions, joined by " ". This is GENERIC
|
|
943
|
+
* substrate prompting — the same text for every host, never per-host copy.
|
|
944
|
+
*
|
|
945
|
+
* Included ONLY when `toolspaceAvailable` is true, which the caller sets from the
|
|
946
|
+
* exact condition that gates the sandbox token mint: the toolspace feature is
|
|
947
|
+
* enabled AND a toolspace token was minted for THIS turn. That mint now happens
|
|
948
|
+
* on every backend including selfhosted (connected machines get the token too),
|
|
949
|
+
* so the block appears there as well; a turn with no minted token (feature off)
|
|
950
|
+
* has no toolspace URL/token in its sandbox and must not advertise a capability
|
|
951
|
+
* that is not there — the gate is false and this is a no-op. Placed BEFORE the
|
|
952
|
+
* per-session instructions so host/session specificity still wins over this
|
|
953
|
+
* substrate note.
|
|
954
|
+
*/
|
|
955
|
+
export function appendToolspaceInstructions(composed: string, toolspaceAvailable: boolean): string {
|
|
956
|
+
return toolspaceAvailable ? `${composed} ${TOOLSPACE_PROGRAMMATIC_DIRECTIVE}` : composed;
|
|
957
|
+
}
|
|
958
|
+
|
|
940
959
|
/**
|
|
941
960
|
* Appends the one-shot genesis title directive (genesis turn only), joined by
|
|
942
961
|
* " " and always LAST so a white-label persona template or a per-session
|
|
@@ -1030,14 +1049,21 @@ export function buildOpenGeniAgent(settings: Settings, resources: ResourceRef[],
|
|
|
1030
1049
|
// Persona composition order (all one system-level instructions string):
|
|
1031
1050
|
// 1. workspace instructionsTemplate (or deployment default) with the
|
|
1032
1051
|
// non-bypassable CORE substituted at {{core}} — composeAgentInstructions,
|
|
1033
|
-
// 2. + the
|
|
1034
|
-
//
|
|
1035
|
-
//
|
|
1036
|
-
//
|
|
1037
|
-
// the
|
|
1052
|
+
// 2. + the generic programmatic-tool-calling (toolspace) directive, ONLY
|
|
1053
|
+
// when a toolspace token was minted for this turn (feature enabled + a
|
|
1054
|
+
// per-turn seed — the mint gate, which includes selfhosted turns since
|
|
1055
|
+
// they now receive the token too) — appendToolspaceInstructions,
|
|
1056
|
+
// 3. + the per-session persona instructions (session-specific, so it
|
|
1057
|
+
// refines both the workspace persona and the substrate note),
|
|
1058
|
+
// 4. + the one-shot genesis title directive (genesis turn only).
|
|
1059
|
+
// With no toolspace token, no session instructions, and no genesis hint this
|
|
1060
|
+
// is byte-identical to the historical composed instructions.
|
|
1038
1061
|
instructions: appendGenesisTitleDirective(
|
|
1039
1062
|
appendSessionInstructions(
|
|
1040
|
-
|
|
1063
|
+
appendToolspaceInstructions(
|
|
1064
|
+
composeAgentInstructions(options.instructionsTemplate ?? settings.agentInstructionsTemplate, options.workspaceEnvironment),
|
|
1065
|
+
settings.toolspaceEnabled && Boolean(options.toolspaceTokenSeed),
|
|
1066
|
+
),
|
|
1041
1067
|
options.sessionInstructions,
|
|
1042
1068
|
),
|
|
1043
1069
|
options.genesisTitleHint,
|
|
@@ -2194,6 +2220,13 @@ export type ContextRobustnessFilterOptions = {
|
|
|
2194
2220
|
export const GENESIS_TITLE_DIRECTIVE =
|
|
2195
2221
|
"This is the first turn of a new session. Before responding to the user, call the opengeni__set_session_title tool with a concise 3-7 word title that summarizes what this session is about, then address the user's request normally.";
|
|
2196
2222
|
|
|
2223
|
+
// Generic substrate prompting for programmatic tool calling (toolspace). Same
|
|
2224
|
+
// text for every host; gated per-turn by appendToolspaceInstructions on the
|
|
2225
|
+
// presence of a minted toolspace token, so it only appears when the sandbox
|
|
2226
|
+
// actually exposes the ogtool CLI + $OPENGENI_TOOLSPACE_URL/_TOKEN_FILE.
|
|
2227
|
+
export const TOOLSPACE_PROGRAMMATIC_DIRECTIVE =
|
|
2228
|
+
"Every tool on your MCP surface is also callable programmatically from the sandbox shell, so scripts can invoke tools without a model round trip per call. Run `ogtool list` to see the available tools and their input schemas (from tools/list), then `ogtool call <tool-name> '<json-args>'`; equivalently, POST MCP JSON-RPC to $OPENGENI_TOOLSPACE_URL with the bearer token read from $OPENGENI_TOOLSPACE_TOKEN_FILE. Prefer programmatic calls for loops, polling, and bulk filtering: their results stay in the sandbox and do not consume your context window. Tools that require human approval must still be invoked normally — called programmatically they return a typed error.";
|
|
2229
|
+
|
|
2197
2230
|
/**
|
|
2198
2231
|
* callModelInputFilter that removes provider-assigned item ids (rs_/msg_/fc_…)
|
|
2199
2232
|
* from every input item immediately before each model call. Responses-API
|
|
@@ -2398,6 +2431,22 @@ export async function runAgentStream(agent: Agent<any, any>, input: PreparedAgen
|
|
|
2398
2431
|
...(runAs ? { runAs } : {}),
|
|
2399
2432
|
});
|
|
2400
2433
|
}
|
|
2434
|
+
} else {
|
|
2435
|
+
// SELFHOSTED TOOLSPACE (parity): the platform setup hooks (repository clone,
|
|
2436
|
+
// az login) and file materialization stay OFF the user's real machine — but
|
|
2437
|
+
// the toolspace token seed is the ONE piece of per-turn material that must
|
|
2438
|
+
// reach it. It writes a scoped, own-session-bound token to
|
|
2439
|
+
// $OPENGENI_TOOLSPACE_TOKEN_FILE over the SAME exec channel the clone-seed
|
|
2440
|
+
// uses (off-manifest, value never on the manifest), and it grants no more
|
|
2441
|
+
// than the machine owner's own authority (toolspace:call, this session, turn
|
|
2442
|
+
// TTL, budgeted, approval-tools excluded) — the invariant that makes it safe
|
|
2443
|
+
// to cross to a user machine when the git token is not. It is also the
|
|
2444
|
+
// machine's only path to programmatic tool calling. Seed it (only) here; the
|
|
2445
|
+
// hook list is empty when no toolspace token was minted for this turn.
|
|
2446
|
+
const toolspaceHooks = sandboxToolspaceTokenHooksForAgent(agent);
|
|
2447
|
+
if (toolspaceHooks.length > 0) {
|
|
2448
|
+
await runBeforeAgentStartHooks(setupSession, toolspaceHooks, ownedHookContext);
|
|
2449
|
+
}
|
|
2401
2450
|
}
|
|
2402
2451
|
// Keep the decoration as a safety net for any session the SDK does create/resume
|
|
2403
2452
|
// through the client during this run (it is inert for the provided session).
|
|
@@ -144,6 +144,28 @@ export interface SelfhostedImageOutput {
|
|
|
144
144
|
* (the turn pauses + retries); it is NOT a hard failure. */
|
|
145
145
|
export const SELFHOSTED_DEFAULT_TIMEOUT_MS = 30_000;
|
|
146
146
|
|
|
147
|
+
/**
|
|
148
|
+
* The ONLY manifest-environment keys exported into a selfhosted machine's exec
|
|
149
|
+
* shell. The manifest env is otherwise NOT consumed by selfhosted exec — the
|
|
150
|
+
* machine owns its own environment, and pushing HOME, GIT_ vars, and the like
|
|
151
|
+
* onto a real computer would clobber it. The toolspace pointers are the exception:
|
|
152
|
+
* `ogtool` (and the token-seed hook) need the non-secret programmatic-calling URL
|
|
153
|
+
* and the token-FILE PATH to reach the tool surface. The token VALUE never rides
|
|
154
|
+
* here — it is seeded to that file off-manifest over the same exec channel.
|
|
155
|
+
*/
|
|
156
|
+
const SELFHOSTED_EXEC_ENV_ALLOWLIST = ["OPENGENI_TOOLSPACE_URL", "OPENGENI_TOOLSPACE_TOKEN_FILE"] as const;
|
|
157
|
+
|
|
158
|
+
function selfhostedExecEnv(environment: Record<string, string>): Record<string, string> {
|
|
159
|
+
const env: Record<string, string> = {};
|
|
160
|
+
for (const key of SELFHOSTED_EXEC_ENV_ALLOWLIST) {
|
|
161
|
+
const value = environment[key];
|
|
162
|
+
if (value) {
|
|
163
|
+
env[key] = value;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return env;
|
|
167
|
+
}
|
|
168
|
+
|
|
147
169
|
/** The relay-URL shape config the session needs to build a stream endpoint. M8b
|
|
148
170
|
* wires the real relay deployment behind THIS seam so `buildStreamUrl` works
|
|
149
171
|
* unchanged behind `resolveExposedPort`. */
|
|
@@ -181,9 +203,11 @@ export interface SelfhostedSessionDeps {
|
|
|
181
203
|
* session delta; `validateNoEnvironmentDelta` throws "Live sandbox sessions cannot
|
|
182
204
|
* change manifest environment variables" on ANY env mismatch. So `state.manifest`'s
|
|
183
205
|
* `environment` MUST EQUAL the turn's environment for the delta to be empty. The
|
|
184
|
-
* selfhosted exec routes over NATS and does NOT consume
|
|
185
|
-
*
|
|
186
|
-
*
|
|
206
|
+
* selfhosted exec routes over NATS and does NOT consume this env wholesale (the
|
|
207
|
+
* machine owns its own shell), EXCEPT the allowlisted toolspace pointers it
|
|
208
|
+
* exports per exec so `ogtool` works — see SELFHOSTED_EXEC_ENV_ALLOWLIST. The
|
|
209
|
+
* manifest carries the full env for parity. Omitted → `{}` (the negotiation-only
|
|
210
|
+
* / test path, which never applies a turn manifest, so there is no delta).
|
|
187
211
|
*/
|
|
188
212
|
environment?: Record<string, string>;
|
|
189
213
|
/**
|
|
@@ -340,7 +364,11 @@ export class SelfhostedSession {
|
|
|
340
364
|
// SELFHOSTED_VIRTUAL_ROOT). Empty → the session workingDir (itself "" by
|
|
341
365
|
// default ⇒ the agent runs in its workspace_root).
|
|
342
366
|
cwd: toMachinePath(args.workdir, this.workingDir),
|
|
343
|
-
env
|
|
367
|
+
// The machine owns its own shell environment; the manifest env is NOT
|
|
368
|
+
// exported here. The ONE exception is the non-secret toolspace pointers
|
|
369
|
+
// (URL + token-file path), so a programmatic `ogtool` call and the token-
|
|
370
|
+
// seed hook can find the tool surface. See SELFHOSTED_EXEC_ENV_ALLOWLIST.
|
|
371
|
+
env: selfhostedExecEnv(this.state.environment),
|
|
344
372
|
stdin: new Uint8Array(0),
|
|
345
373
|
timeoutMs: 0,
|
|
346
374
|
};
|