@opengeni/config 0.7.10 → 0.7.13

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opengeni/config",
3
- "version": "0.7.10",
3
+ "version": "0.7.13",
4
4
  "description": "OpenGeni runtime configuration: settings resolution, deployment knobs, and config validation shared across the server packages.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -34,7 +34,7 @@
34
34
  },
35
35
  "dependencies": {
36
36
  "@opengeni/codex": "^0.2.7",
37
- "@opengeni/contracts": "^0.21.0",
37
+ "@opengeni/contracts": "^0.23.0",
38
38
  "zod": "^4.2.1"
39
39
  },
40
40
  "engines": {
package/src/index.ts CHANGED
@@ -248,9 +248,6 @@ const SettingsSchema = z.object({
248
248
  // holder of stream:control gets 403 until this flips. Keeps stream:control a
249
249
  // declared-but-inert permission so later hardening is a flag flip.
250
250
  streamControlEnabled: EnvBoolean.default(false),
251
- // Existing-session explicit tool replacement is gated until every API and
252
- // worker instance understands durable tools_provided provenance.
253
- sessionTurnToolReplacementEnabled: EnvBoolean.default(false),
254
251
  toolspaceEnabled: EnvBoolean.default(false),
255
252
  toolspaceMaxCallsPerTurn: z.coerce.number().int().positive().default(200),
256
253
  // Optional release-coherent bootstrap hint for custom rigs/connected machines
@@ -413,6 +410,11 @@ const SettingsSchema = z.object({
413
410
  dockerImage: z.string().default("opengeni-sandbox:local"),
414
411
  dockerExposedPorts: z.string().default(""),
415
412
  dockerNetwork: z.string().optional(),
413
+ // When the worker itself runs in a container and talks to a host Docker daemon,
414
+ // this directory must be bind-mounted at the exact same absolute path on both
415
+ // sides. The Agents SDK materializes the workspace here before bind-mounting it
416
+ // into the sandbox container.
417
+ dockerWorkspaceBaseDir: z.string().min(1).optional(),
416
418
  modalAppName: z.string().default("opengeni-sandbox"),
417
419
  modalImageRef: z.string().optional(),
418
420
  // Name of a Modal Secret (containing REGISTRY_USERNAME + REGISTRY_PASSWORD) used
@@ -1360,7 +1362,6 @@ export function getSettings(): Settings {
1360
1362
  delegationSecret: optional("OPENGENI_DELEGATION_SECRET"),
1361
1363
  streamTokenSecret: optional("OPENGENI_STREAM_TOKEN_SECRET"),
1362
1364
  streamControlEnabled: optional("OPENGENI_STREAM_CONTROL_ENABLED"),
1363
- sessionTurnToolReplacementEnabled: optional("OPENGENI_SESSION_TURN_TOOL_REPLACEMENT_ENABLED"),
1364
1365
  toolspaceEnabled: optional("OPENGENI_TOOLSPACE_ENABLED"),
1365
1366
  toolspaceMaxCallsPerTurn: optional("OPENGENI_TOOLSPACE_MAX_CALLS_PER_TURN"),
1366
1367
  ogtoolPackageSpec: optional("OPENGENI_OGTOOL_PACKAGE_SPEC"),
@@ -1424,6 +1425,7 @@ export function getSettings(): Settings {
1424
1425
  dockerImage: optional("OPENGENI_DOCKER_IMAGE"),
1425
1426
  dockerExposedPorts: optional("OPENGENI_DOCKER_EXPOSED_PORTS"),
1426
1427
  dockerNetwork: optional("OPENGENI_DOCKER_NETWORK"),
1428
+ dockerWorkspaceBaseDir: optional("OPENGENI_DOCKER_WORKSPACE_BASE_DIR"),
1427
1429
  modalAppName: optional("OPENGENI_MODAL_APP_NAME"),
1428
1430
  modalImageRef: optional("OPENGENI_MODAL_IMAGE_REF"),
1429
1431
  modalImageRegistrySecret: optional("OPENGENI_MODAL_IMAGE_REGISTRY_SECRET"),
@@ -2787,9 +2789,14 @@ export function stableSandboxEnvironmentForRun(
2787
2789
  };
2788
2790
  // Backend-aware HOME: a provisioned box (docker + every cloud provider) runs the
2789
2791
  // agent under the descriptor's workspaceRoot. `local` runs in-process as the host
2790
- // unix user (keep its real $HOME); `none` has no box.
2792
+ // unix user (keep its real $HOME); `selfhosted` runs on a user's machine and must
2793
+ // likewise preserve that machine's real HOME; `none` has no box.
2791
2794
  const descriptor = CAPABILITY_DESCRIPTORS[settings.sandboxBackend];
2792
- if (settings.sandboxBackend !== "none" && settings.sandboxBackend !== "local") {
2795
+ if (
2796
+ settings.sandboxBackend !== "none" &&
2797
+ settings.sandboxBackend !== "local" &&
2798
+ settings.sandboxBackend !== "selfhosted"
2799
+ ) {
2793
2800
  environment.HOME ??= descriptor.workspaceRoot;
2794
2801
  }
2795
2802
  // TOKEN-BROKER (B1): the STABLE credential FILE PATHS and CLI wrapper PATH for
@@ -2810,7 +2817,15 @@ export function stableSandboxEnvironmentForRun(
2810
2817
  environment.PATH = prependPathEntry(environment.PATH, environment.OPENGENI_GIT_CLI_WRAPPER_DIR);
2811
2818
  }
2812
2819
  if (settings.toolspaceEnabled) {
2813
- environment.OPENGENI_TOOLSPACE_TOKEN_FILE ??= `${environment.HOME ?? descriptor.workspaceRoot}/.opengeni/toolspace-token`;
2820
+ // Connected Machines do not share one control-plane-known home path. Keep a
2821
+ // stable shell-resolved pointer in the manifest; runtime expands this trusted
2822
+ // marker against the machine's own HOME for seed, renewal, and every command.
2823
+ // Never derive it from the selfhosted descriptor root (`/`), which would try
2824
+ // to write `/.opengeni` as an ordinary machine user.
2825
+ environment.OPENGENI_TOOLSPACE_TOKEN_FILE ??=
2826
+ settings.sandboxBackend === "selfhosted"
2827
+ ? "$HOME/.opengeni/toolspace-token"
2828
+ : `${environment.HOME ?? descriptor.workspaceRoot}/.opengeni/toolspace-token`;
2814
2829
  if (settings.ogtoolPackageSpec) {
2815
2830
  environment.OPENGENI_OGTOOL_PACKAGE_SPEC ??= settings.ogtoolPackageSpec;
2816
2831
  }
@@ -3230,6 +3245,7 @@ function positiveInt(value: unknown): number {
3230
3245
  function ensureBuiltInMcpServers(settings: Settings): Settings["mcpServers"] {
3231
3246
  const existing = settings.mcpServers.filter((server) => server.id !== "opengeni");
3232
3247
  const firstPartyMcpUrl = firstPartyMcpServerUrl(settings);
3248
+ const firstPartyFilesMcpUrl = firstPartyFilesMcpServerUrl(firstPartyMcpUrl);
3233
3249
  const firstPartyDocsMcpUrl = firstPartyDocumentsMcpServerUrl(firstPartyMcpUrl);
3234
3250
  const hasFiles = existing.some((server) => server.id === "files");
3235
3251
  const hasDocs = existing.some((server) => server.id === "docs");
@@ -3257,7 +3273,7 @@ function ensureBuiltInMcpServers(settings: Settings): Settings["mcpServers"] {
3257
3273
  {
3258
3274
  id: "files",
3259
3275
  name: "Files",
3260
- url: firstPartyMcpUrl,
3276
+ url: firstPartyFilesMcpUrl,
3261
3277
  allowedTools: ["files_get_download_url"],
3262
3278
  cacheToolsList: true,
3263
3279
  },
@@ -3333,6 +3349,10 @@ function firstPartyDocumentsMcpServerUrl(mcpUrl: string): string {
3333
3349
  return `${mcpUrl.replace(/\/+$/, "")}/docs`;
3334
3350
  }
3335
3351
 
3352
+ function firstPartyFilesMcpServerUrl(mcpUrl: string): string {
3353
+ return `${mcpUrl.replace(/\/+$/, "")}/files`;
3354
+ }
3355
+
3336
3356
  function validateSettings(settings: Settings): void {
3337
3357
  temporalConnectionOptions(settings);
3338
3358
  if (settings.toolspaceEnabled && !settings.delegationSecret) {