@rivus/gateway 0.17.0 → 0.18.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.
@@ -6,7 +6,7 @@ import { RIVUS_MEMORY_TOOL_PLUGIN_ID, RIVUS_RUNTIME_TOOL_IDS, createRivusMemoryT
6
6
  import { homedir } from "node:os";
7
7
  import { basename, dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
8
8
  import { fileURLToPath, pathToFileURL } from "node:url";
9
- import { Cause, Effect, Either, Exit } from "effect";
9
+ import { Cause, Deferred, Effect, Exit, Result, Semaphore } from "effect";
10
10
  import { lstat, mkdir, open, readFile, readdir, realpath, rmdir, stat, unlink, writeFile } from "node:fs/promises";
11
11
  import { randomUUID } from "node:crypto";
12
12
  import { assertPathWithin, isPathWithin } from "@rivus/platform/filesystem";
@@ -540,7 +540,7 @@ function checkManifest$1(home) {
540
540
  },
541
541
  manifest
542
542
  };
543
- }), Effect.catchAll((error) => Effect.succeed({ check: {
543
+ }), Effect.catch((error) => Effect.succeed({ check: {
544
544
  message: `deployment manifest is invalid: ${formatError(error)}`,
545
545
  name: "manifest",
546
546
  status: "fail"
@@ -556,16 +556,16 @@ function checkModules(home, manifest, resolveModule, resolvePluginModule) {
556
556
  return Effect.gen(function* () {
557
557
  const missing = [];
558
558
  for (const specifier of specifiers) {
559
- const result = yield* toEffect(() => resolveModule(specifier)).pipe(Effect.either);
560
- if (result._tag === "Left") missing.push(`${specifier} (${formatError(result.left)})`);
559
+ const result = yield* toEffect(() => resolveModule(specifier)).pipe(Effect.result);
560
+ if (result._tag === "Failure") missing.push(`${specifier} (${formatError(result.failure)})`);
561
561
  }
562
562
  for (const plugin of manifest.plugins) {
563
563
  const result = yield* toEffect(() => resolvePluginModule({
564
564
  deploymentRoot: home.directory,
565
565
  module: plugin.module,
566
566
  pluginId: plugin.id
567
- })).pipe(Effect.either);
568
- if (result._tag === "Left") missing.push(`${plugin.module} (${formatError(result.left)})`);
567
+ })).pipe(Effect.result);
568
+ if (result._tag === "Failure") missing.push(`${plugin.module} (${formatError(result.failure)})`);
569
569
  }
570
570
  return missing.length === 0 ? {
571
571
  message: "Bootstrap, Plugin, Pi, and Feishu modules resolve from the global installation",
@@ -609,7 +609,7 @@ function checkCredentials$1(home, manifest, env, envFilePath) {
609
609
  };
610
610
  },
611
611
  catch: toError$2
612
- }).pipe(Effect.catchAll((error) => Effect.succeed({
612
+ }).pipe(Effect.catch((error) => Effect.succeed({
613
613
  message: `enabled Endpoint credentials are incomplete: ${formatError(error)}`,
614
614
  name: "credentials",
615
615
  status: "fail"
@@ -700,16 +700,16 @@ function asError$1(error) {
700
700
  function diagnoseRivusHome(input, options) {
701
701
  return Effect.gen(function* () {
702
702
  const checks = [checkNode$1(input.nodeVersion)];
703
- const loaded = yield* options.load(input.directory).pipe(Effect.either);
704
- if (Either.isLeft(loaded)) {
703
+ const loaded = yield* options.load(input.directory).pipe(Effect.result);
704
+ if (Result.isFailure(loaded)) {
705
705
  checks.push({
706
- message: `Rivus Home is invalid: ${loaded.left.message}`,
706
+ message: `Rivus Home is invalid: ${loaded.failure.message}`,
707
707
  name: "home",
708
708
  status: "fail"
709
709
  }, blockedCheck("workspace", "Workspace"), blockedCheck("manifest", "manifest"), blockedCheck("modules", "modules"), blockedCheck("credentials", "credentials"));
710
710
  return report(input.directory, checks);
711
711
  }
712
- const home = loaded.right;
712
+ const home = loaded.success;
713
713
  checks.push({
714
714
  message: "config.json is valid and contained in Rivus Home",
715
715
  name: "home",
@@ -1219,8 +1219,8 @@ function checkManifest(directory) {
1219
1219
  deploymentRoot: directory,
1220
1220
  module: plugin.module,
1221
1221
  pluginId: plugin.id
1222
- }).pipe(Effect.either);
1223
- if (Either.isLeft(result)) missingModules.push(plugin.module);
1222
+ }).pipe(Effect.result);
1223
+ if (Result.isFailure(result)) missingModules.push(plugin.module);
1224
1224
  }
1225
1225
  if (missingModules.length > 0) return { check: {
1226
1226
  message: `manifest Plugin modules are missing: ${missingModules.join(", ")}`,
@@ -1235,7 +1235,7 @@ function checkManifest(directory) {
1235
1235
  },
1236
1236
  manifest
1237
1237
  };
1238
- })), Effect.catchAll((error) => Effect.succeed({ check: {
1238
+ })), Effect.catch((error) => Effect.succeed({ check: {
1239
1239
  message: `deployment manifest is invalid: ${error.message}`,
1240
1240
  name: "manifest",
1241
1241
  status: "fail"
@@ -2869,7 +2869,7 @@ const DEFAULT_RUNTIME_DISPOSE_TIMEOUT_MS = 1e4;
2869
2869
  function createEffectRuntimePool(options) {
2870
2870
  const runtimes = createRuntimeCache();
2871
2871
  const active = /* @__PURE__ */ new Map();
2872
- const lifecycle = Effect.unsafeMakeSemaphore(1);
2872
+ const lifecycle = Semaphore.makeUnsafe(1);
2873
2873
  const existingRuntime = (instance) => Effect.gen(function* () {
2874
2874
  const selected = yield* runtimes.getExisting(instance.instanceId);
2875
2875
  if (!selected || !(yield* runtimes.isCurrent(instance.instanceId, selected.entry))) return;
@@ -3121,10 +3121,10 @@ function resolveRivusDeployment(input) {
3121
3121
  return plugin;
3122
3122
  },
3123
3123
  catch: toDeploymentFailure
3124
- })), Effect.either);
3125
- if (Either.isLeft(loaded)) {
3126
- const message = formatDeploymentFailure(loaded.left);
3127
- if (declaration.required) return yield* Effect.fail(new RivusPluginLoadError(declaration.id, declaration.module, `required plugin ${declaration.id} failed to load: ${message}`, { cause: loaded.left }));
3124
+ })), Effect.result);
3125
+ if (Result.isFailure(loaded)) {
3126
+ const message = formatDeploymentFailure(loaded.failure);
3127
+ if (declaration.required) return yield* Effect.fail(new RivusPluginLoadError(declaration.id, declaration.module, `required plugin ${declaration.id} failed to load: ${message}`, { cause: loaded.failure }));
3128
3128
  const status = Object.freeze({
3129
3129
  error: message,
3130
3130
  id: declaration.id,
@@ -3141,7 +3141,7 @@ function resolveRivusDeployment(input) {
3141
3141
  module: declaration.module,
3142
3142
  required: declaration.required,
3143
3143
  status: "loaded",
3144
- version: loaded.right.manifest.version
3144
+ version: loaded.success.manifest.version
3145
3145
  });
3146
3146
  pluginStatuses.push(status);
3147
3147
  statusByPlugin.set(declaration.id, status);
@@ -3175,23 +3175,23 @@ function resolveRivusDeployment(input) {
3175
3175
  }) : baseDefinition;
3176
3176
  },
3177
3177
  catch: toDeploymentFailure
3178
- }).pipe(Effect.either);
3179
- if (Either.isLeft(resolved)) {
3178
+ }).pipe(Effect.result);
3179
+ if (Result.isFailure(resolved)) {
3180
3180
  const declaration = input.manifest.plugins.find(({ id }) => id === agent.pluginId);
3181
- if (declaration.required) return yield* Effect.fail(new RivusPluginLoadError(declaration.id, declaration.module, `deployment ${agent.agentId} failed to resolve: ${resolved.left.message}`, { cause: resolved.left }));
3181
+ if (declaration.required) return yield* Effect.fail(new RivusPluginLoadError(declaration.id, declaration.module, `deployment ${agent.agentId} failed to resolve: ${resolved.failure.message}`, { cause: resolved.failure }));
3182
3182
  agentStatuses.push(Object.freeze({
3183
3183
  agentId: agent.agentId,
3184
3184
  pluginId: agent.pluginId,
3185
3185
  profileId: agent.profileId,
3186
- reason: resolved.left.message,
3186
+ reason: resolved.failure.message,
3187
3187
  status: "disabled"
3188
3188
  }));
3189
3189
  continue;
3190
3190
  }
3191
- definitions.push(resolved.right);
3191
+ definitions.push(resolved.success);
3192
3192
  agentStatuses.push(Object.freeze({
3193
3193
  agentId: agent.agentId,
3194
- definition: resolved.right,
3194
+ definition: resolved.success,
3195
3195
  pluginId: agent.pluginId,
3196
3196
  profileId: agent.profileId,
3197
3197
  status: "enabled"
@@ -3841,13 +3841,20 @@ async function createRivusDeploymentCliProcess(factory, context) {
3841
3841
  deployment,
3842
3842
  digest: createSha256Digest
3843
3843
  })));
3844
- })).pipe(Effect.flatMap((control) => Effect.gen(function* () {
3845
- const [cached, invalidate] = yield* Effect.cachedInvalidateWithTTL(Effect.suspend(() => adapters.createRecoveryControl ? adapters.createRecoveryControl() : Effect.fail(/* @__PURE__ */ new Error("Deployment bootstrap does not expose Recovery Control"))), Infinity);
3844
+ })).pipe(Effect.map((control) => {
3845
+ let opening;
3846
3846
  return {
3847
3847
  control,
3848
- openRecovery: cached.pipe(Effect.onExit((exit) => Exit.isFailure(exit) && !Cause.isInterruptedOnly(exit.cause) ? invalidate : Effect.void))
3848
+ openRecovery: Effect.uninterruptible(Effect.suspend(() => {
3849
+ if (opening) return Deferred.await(opening);
3850
+ const current = Deferred.makeUnsafe();
3851
+ opening = current;
3852
+ return Effect.suspend(() => adapters.createRecoveryControl ? adapters.createRecoveryControl() : Effect.fail(/* @__PURE__ */ new Error("Deployment bootstrap does not expose Recovery Control"))).pipe(Effect.onExit((exit) => Effect.sync(() => {
3853
+ if (Exit.isFailure(exit) && opening === current) opening = void 0;
3854
+ }).pipe(Effect.andThen(Deferred.done(current, exit)))));
3855
+ }))
3849
3856
  };
3850
- })))));
3857
+ }))));
3851
3858
  daemon = constructed.control;
3852
3859
  openRecovery = constructed.openRecovery;
3853
3860
  } catch (constructionError) {
@@ -3864,7 +3871,7 @@ async function createRivusDeploymentCliProcess(factory, context) {
3864
3871
  }))]).pipe(Effect.map((exits) => exits.filter(Exit.isFailure).map((exit) => Cause.squash(exit.cause))));
3865
3872
  const startDeployment = Effect.uninterruptible(Effect.suspend(() => {
3866
3873
  if (adaptersDisposed) return Effect.fail(/* @__PURE__ */ new Error("Rivus deployment process cannot restart after its adapters have been disposed"));
3867
- return Effect.suspend(() => daemon.start()).pipe(Effect.catchAllCause((cause) => {
3874
+ return Effect.suspend(() => daemon.start()).pipe(Effect.catchCause((cause) => {
3868
3875
  const startError = Cause.squash(cause);
3869
3876
  return cleanupErrors.pipe(Effect.flatMap((errors) => Effect.fail(errors.length > 0 ? new AggregateError([startError, ...errors], "deployment startup and cleanup failed") : startError)));
3870
3877
  }));
@@ -3893,7 +3900,7 @@ async function createRivusDeploymentCliProcess(factory, context) {
3893
3900
  sessionKey: command.sessionKey,
3894
3901
  text: command.text
3895
3902
  }).pipe(Effect.map(readPromptFinalText));
3896
- }).pipe(Effect.catchAllCause((cause) => Effect.fail(Cause.squash(cause))))
3903
+ }).pipe(Effect.catchCause((cause) => Effect.fail(Cause.squash(cause))))
3897
3904
  };
3898
3905
  const replayReceiveMessage = adapters.replayReceiveMessage;
3899
3906
  if (replayReceiveMessage) process.replayReceiveMessage = (payload, options) => Effect.suspend(() => daemon.running() ? Effect.void : startDeployment).pipe(Effect.flatMap(() => replayReceiveMessage((input) => daemon.handleDefault(input), payload, options)));
@@ -4069,7 +4076,7 @@ function runRivusDaemonCli(options) {
4069
4076
  yield* daemon.start();
4070
4077
  options.stdout.write(RIVUS_DAEMON_STARTED_MESSAGE);
4071
4078
  return 0;
4072
- }).pipe(Effect.catchAll((error) => Effect.sync(() => {
4079
+ }).pipe(Effect.catch((error) => Effect.sync(() => {
4073
4080
  options.stderr.write(formatRivusDaemonLine(formatRivusDaemonError(error)));
4074
4081
  return 1;
4075
4082
  })));
@@ -4189,7 +4196,7 @@ function runModelCommand(options) {
4189
4196
  return Effect.tryPromise({
4190
4197
  try: () => client.execute(parsed),
4191
4198
  catch: (error) => error
4192
- }).pipe(Effect.tap((response) => Effect.sync(() => writeModelResponse(options.stdout, response))), Effect.map((response) => modelManagementExitCode(response)), Effect.catchAll((error) => Effect.sync(() => {
4199
+ }).pipe(Effect.tap((response) => Effect.sync(() => writeModelResponse(options.stdout, response))), Effect.map((response) => modelManagementExitCode(response)), Effect.catch((error) => Effect.sync(() => {
4193
4200
  writeModelResponse(options.stdout, modelTransportFailure(error));
4194
4201
  return 1;
4195
4202
  })));
@@ -4217,7 +4224,7 @@ function modelTransportFailure(error) {
4217
4224
  };
4218
4225
  }
4219
4226
  function runSetupCommand(options) {
4220
- return withOptionalDirectoryArgument(options, "setup", (argument) => resolveHomeDirectoryEffect(options, argument).pipe(Effect.flatMap((directory) => options.homeApi.setup(directory).pipe(Effect.tap(() => Effect.sync(() => options.stdout.write(renderRivusSetupSuccess(directory)))), Effect.as(0))), Effect.catchAll((error) => writeError(options, error))));
4227
+ return withOptionalDirectoryArgument(options, "setup", (argument) => resolveHomeDirectoryEffect(options, argument).pipe(Effect.flatMap((directory) => options.homeApi.setup(directory).pipe(Effect.tap(() => Effect.sync(() => options.stdout.write(renderRivusSetupSuccess(directory)))), Effect.as(0))), Effect.catch((error) => writeError(options, error))));
4221
4228
  }
4222
4229
  function runHomeDaemonCommand(options, command, daemonArgs) {
4223
4230
  if (hasRivusHomeCommandArguments(options.argv.slice(1))) return Effect.sync(() => {
@@ -4241,7 +4248,7 @@ function runHomeDaemonCommand(options, command, daemonArgs) {
4241
4248
  RIVUS_HOME: home.directory
4242
4249
  },
4243
4250
  pluginPackageManifestPath: options.pluginPackageManifestPath ?? gatewayPackageManifestPath
4244
- })), Effect.catchAll((error) => writeError(options, error)));
4251
+ })), Effect.catch((error) => writeError(options, error)));
4245
4252
  }
4246
4253
  function runInitCommand(options) {
4247
4254
  return withOptionalDirectoryArgument(options, "init", (argument) => {
@@ -4253,7 +4260,7 @@ function runInitCommand(options) {
4253
4260
  templateDirectory: gatewayTemplateDirectory
4254
4261
  }),
4255
4262
  catch: (error) => error
4256
- }).pipe(Effect.tap((result) => Effect.sync(() => options.stdout.write(renderRivusProjectInitializationSuccess(result.directory)))), Effect.as(0), Effect.catchAll((error) => writeError(options, error)));
4263
+ }).pipe(Effect.tap((result) => Effect.sync(() => options.stdout.write(renderRivusProjectInitializationSuccess(result.directory)))), Effect.as(0), Effect.catch((error) => writeError(options, error)));
4257
4264
  });
4258
4265
  }
4259
4266
  function withOptionalDirectoryArgument(options, command, run) {
@@ -4286,14 +4293,14 @@ function runDoctorCommand(options) {
4286
4293
  env: options.env,
4287
4294
  ...parsed.envFilePath ? { envFilePath: parsed.envFilePath } : {},
4288
4295
  nodeVersion: options.nodeVersion
4289
- })), Effect.map((report) => writeDoctorReport(options.stdout, report, "Home")), Effect.catchAll((error) => writeError(options, error)));
4296
+ })), Effect.map((report) => writeDoctorReport(options.stdout, report, "Home")), Effect.catch((error) => writeError(options, error)));
4290
4297
  const projectDirectory = parsed.directory;
4291
4298
  return diagnoseRivusProject({
4292
4299
  directory: resolve(options.cwd, projectDirectory),
4293
4300
  env: options.env,
4294
4301
  ...parsed.envFilePath ? { envFilePath: parsed.envFilePath } : {},
4295
4302
  nodeVersion: options.nodeVersion
4296
- }).pipe(Effect.map((report) => writeDoctorReport(options.stdout, report, "project")), Effect.catchAll((error) => writeError(options, error)));
4303
+ }).pipe(Effect.map((report) => writeDoctorReport(options.stdout, report, "project")), Effect.catch((error) => writeError(options, error)));
4297
4304
  }
4298
4305
  function resolveHomeDirectoryEffect(options, argument) {
4299
4306
  return Effect.try({
@@ -1,7 +1,7 @@
1
1
  import { isRivusRuntimeToolId } from "@rivus/runtime";
2
2
  import { dirname, isAbsolute } from "node:path";
3
3
  import { fileURLToPath } from "node:url";
4
- import { Cause, Deferred, Effect, Exit } from "effect";
4
+ import { Cause, Deferred, Effect, Exit, Semaphore } from "effect";
5
5
  import { chmod, mkdir, open, readFile, rename, stat, unlink } from "node:fs/promises";
6
6
  import { randomUUID } from "node:crypto";
7
7
  import { createConnection, createServer } from "node:net";
@@ -1199,18 +1199,18 @@ function parseLockOwner(value) {
1199
1199
  //#endregion
1200
1200
  //#region src/platform/project/setup/release-descriptor.ts
1201
1201
  const RIVUS_RELEASE_DESCRIPTOR = Object.freeze({
1202
- version: "0.17.0",
1202
+ version: "0.18.1",
1203
1203
  dependencies: Object.freeze({
1204
1204
  "@earendil-works/pi-coding-agent": "0.84.4",
1205
1205
  "@larksuiteoapi/node-sdk": "1.74.0",
1206
- effect: "^3.22.2"
1206
+ effect: "^4.0.0"
1207
1207
  })
1208
1208
  });
1209
1209
  //#endregion
1210
1210
  //#region src/platform/runtime-pool/runtime-cache.ts
1211
1211
  function createRuntimeCache() {
1212
1212
  const entries = /* @__PURE__ */ new Map();
1213
- const serial = Effect.unsafeMakeSemaphore(1);
1213
+ const serial = Semaphore.makeUnsafe(1);
1214
1214
  const reserve = (key) => serial.withPermits(1)(Effect.gen(function* () {
1215
1215
  const current = entries.get(key);
1216
1216
  if (current) return {
@@ -1237,7 +1237,7 @@ function createRuntimeCache() {
1237
1237
  const initialization = create().pipe(Effect.tapError(() => serial.withPermits(1)(Effect.sync(() => {
1238
1238
  if (entries.get(entry.key) === entry) entries.delete(entry.key);
1239
1239
  }))), Effect.exit, Effect.flatMap((exit) => Deferred.done(entry.deferred, exit)), Effect.asVoid);
1240
- yield* Effect.forkDaemon(initialization);
1240
+ yield* Effect.forkDetach(initialization, { uninterruptible: "inherit" });
1241
1241
  }));
1242
1242
  const getOrCreate = (key, create) => Effect.uninterruptibleMask((restore) => Effect.gen(function* () {
1243
1243
  const selected = yield* reserve(key);
@@ -1272,15 +1272,16 @@ function disposeRuntimeCacheEntries(options) {
1272
1272
  const disposal = Effect.gen(function* () {
1273
1273
  const completions = yield* Effect.forEach(options.entries, (entry) => Effect.gen(function* () {
1274
1274
  const completion = yield* Deferred.make();
1275
- yield* Effect.forkDaemon(Deferred.await(entry.deferred).pipe(Effect.flatMap(options.dispose), Effect.exit, Effect.flatMap((exit) => Deferred.succeed(completion, exit)), Effect.asVoid));
1275
+ yield* Effect.forkDetach(Deferred.await(entry.deferred).pipe(Effect.flatMap(options.dispose), Effect.exit, Effect.flatMap((exit) => Deferred.succeed(completion, exit)), Effect.asVoid), { uninterruptible: "inherit" });
1276
1276
  return completion;
1277
1277
  }), { concurrency: "unbounded" });
1278
1278
  const failures = (yield* Effect.forEach(completions, Deferred.await, { concurrency: "unbounded" })).filter(Exit.isFailure).map(({ cause }) => Cause.squash(cause));
1279
1279
  if (failures.length > 0) return yield* Effect.fail(new AggregateError(failures, options.failureMessage));
1280
1280
  });
1281
- return options.timeout ? disposal.pipe(Effect.timeoutFail({
1282
- duration: options.timeout.milliseconds,
1283
- onTimeout: options.timeout.onTimeout
1281
+ const timeout = options.timeout;
1282
+ return timeout ? disposal.pipe(Effect.timeoutOrElse({
1283
+ duration: timeout.milliseconds,
1284
+ orElse: () => Effect.fail(timeout.onTimeout())
1284
1285
  })) : disposal;
1285
1286
  }
1286
1287
  function invokeRuntimeControl(runtime, control) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rivus/gateway",
3
- "version": "0.17.0",
3
+ "version": "0.18.1",
4
4
  "description": "Message gateway, channels, host binding, automation, and daemon assembly for Rivus.",
5
5
  "type": "module",
6
6
  "license": "GPL-3.0-only",
@@ -52,11 +52,12 @@
52
52
  "LICENSE"
53
53
  ],
54
54
  "dependencies": {
55
- "@rivus/platform": "0.17.0",
56
- "@rivus/runtime": "0.17.0",
55
+ "@rivus/platform": "0.18.1",
56
+ "@rivus/runtime": "0.18.1",
57
57
  "@larksuiteoapi/node-sdk": "1.74.0",
58
58
  "axios": "1.20.0",
59
- "effect": "^3.22.2",
59
+ "effect": "^4.0.0",
60
+ "get-east-asian-width": "1.6.0",
60
61
  "marked": "18.0.14",
61
62
  "@resvg/resvg-js": "2.6.2"
62
63
  },