@naylence/agent-sdk 0.3.12 → 0.3.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.
Files changed (41) hide show
  1. package/README.md +30 -0
  2. package/dist/browser/index.js +1167 -439
  3. package/dist/browser/index.js.map +1 -1
  4. package/dist/cjs/naylence/agent/agent-proxy.js.map +1 -1
  5. package/dist/cjs/naylence/agent/agent.js.map +1 -1
  6. package/dist/cjs/naylence/agent/background-task-agent.js.map +1 -1
  7. package/dist/cjs/naylence/agent/base-agent.js.map +1 -1
  8. package/dist/cjs/public-api.d.ts +7 -0
  9. package/dist/cjs/public-api.js +26 -0
  10. package/dist/cjs/public-api.js.map +1 -0
  11. package/dist/cjs/version.d.ts +1 -1
  12. package/dist/cjs/version.js +1 -1
  13. package/dist/esm/naylence/agent/agent-proxy.d.ts +148 -0
  14. package/dist/esm/naylence/agent/agent-proxy.js +130 -0
  15. package/dist/esm/naylence/agent/agent-proxy.js.map +1 -1
  16. package/dist/esm/naylence/agent/agent.d.ts +194 -2
  17. package/dist/esm/naylence/agent/agent.js +123 -0
  18. package/dist/esm/naylence/agent/agent.js.map +1 -1
  19. package/dist/esm/naylence/agent/background-task-agent.d.ts +164 -0
  20. package/dist/esm/naylence/agent/background-task-agent.js +150 -0
  21. package/dist/esm/naylence/agent/background-task-agent.js.map +1 -1
  22. package/dist/esm/naylence/agent/base-agent.d.ts +171 -0
  23. package/dist/esm/naylence/agent/base-agent.js +170 -1
  24. package/dist/esm/naylence/agent/base-agent.js.map +1 -1
  25. package/dist/esm/public-api.d.ts +15 -0
  26. package/dist/esm/public-api.js +16 -0
  27. package/dist/esm/public-api.js.map +1 -0
  28. package/dist/esm/version.d.ts +1 -1
  29. package/dist/esm/version.js +2 -2
  30. package/dist/types/naylence/agent/agent-proxy.d.ts +148 -0
  31. package/dist/types/naylence/agent/agent-proxy.d.ts.map +1 -1
  32. package/dist/types/naylence/agent/agent.d.ts +194 -2
  33. package/dist/types/naylence/agent/agent.d.ts.map +1 -1
  34. package/dist/types/naylence/agent/background-task-agent.d.ts +164 -0
  35. package/dist/types/naylence/agent/background-task-agent.d.ts.map +1 -1
  36. package/dist/types/naylence/agent/base-agent.d.ts +171 -0
  37. package/dist/types/naylence/agent/base-agent.d.ts.map +1 -1
  38. package/dist/types/public-api.d.ts +16 -0
  39. package/dist/types/public-api.d.ts.map +1 -0
  40. package/dist/types/version.d.ts +1 -1
  41. package/package.json +7 -2
@@ -15277,6 +15277,7 @@
15277
15277
  "./node/admission/direct-admission-client-factory.js",
15278
15278
  "./node/admission/noop-admission-client-factory.js",
15279
15279
  "./node/admission/welcome-service-client-factory.js",
15280
+ "./node/default-connection-retry-policy-factory.js",
15280
15281
  "./node/default-node-identity-policy-factory.js",
15281
15282
  "./node/node-factory.js",
15282
15283
  "./node/node-identity-policy-profile-factory.js",
@@ -15355,6 +15356,7 @@
15355
15356
  "./node/admission/direct-admission-client-factory.js": () => Promise.resolve().then(function () { return directAdmissionClientFactory; }),
15356
15357
  "./node/admission/noop-admission-client-factory.js": () => Promise.resolve().then(function () { return noopAdmissionClientFactory; }),
15357
15358
  "./node/admission/welcome-service-client-factory.js": () => Promise.resolve().then(function () { return welcomeServiceClientFactory; }),
15359
+ "./node/default-connection-retry-policy-factory.js": () => Promise.resolve().then(function () { return defaultConnectionRetryPolicyFactory; }),
15358
15360
  "./node/default-node-identity-policy-factory.js": () => Promise.resolve().then(function () { return defaultNodeIdentityPolicyFactory; }),
15359
15361
  "./node/node-factory.js": () => Promise.resolve().then(function () { return nodeFactory; }),
15360
15362
  "./node/node-identity-policy-profile-factory.js": () => Promise.resolve().then(function () { return nodeIdentityPolicyProfileFactory; }),
@@ -15665,12 +15667,12 @@
15665
15667
  }
15666
15668
 
15667
15669
  // This file is auto-generated during build - do not edit manually
15668
- // Generated from package.json version: 0.3.15
15670
+ // Generated from package.json version: 0.3.16
15669
15671
  /**
15670
15672
  * The package version, injected at build time.
15671
15673
  * @internal
15672
15674
  */
15673
- const VERSION$2 = '0.3.15';
15675
+ const VERSION$2 = '0.3.16';
15674
15676
 
15675
15677
  let initialized$1 = false;
15676
15678
  const runtimePlugin = {
@@ -16401,7 +16403,7 @@
16401
16403
  * Provides functionality similar to Python's asyncio TaskSpawner with proper
16402
16404
  * error handling, cancellation, and graceful shutdown capabilities.
16403
16405
  */
16404
- const logger$1g = getLogger('naylence.fame.util.task_spawner');
16406
+ const logger$1h = getLogger('naylence.fame.util.task_spawner');
16405
16407
  function firstDefined(source, keys) {
16406
16408
  for (const key of keys) {
16407
16409
  if (Object.prototype.hasOwnProperty.call(source, key)) {
@@ -16562,7 +16564,7 @@
16562
16564
  const taskId = `task-${++this._taskCounter}`;
16563
16565
  const taskName = normalizedOptions.name || `unnamed-${taskId}`;
16564
16566
  const timeout = normalizedOptions.timeout ?? this._config.defaultTimeout;
16565
- logger$1g.debug('starting_background_task', {
16567
+ logger$1h.debug('starting_background_task', {
16566
16568
  task_name: taskName,
16567
16569
  task_id: taskId,
16568
16570
  });
@@ -16579,7 +16581,7 @@
16579
16581
  task.promise
16580
16582
  .then(() => {
16581
16583
  if (!this._suppressCompletionLogging) {
16582
- logger$1g.debug('task_completed_successfully', {
16584
+ logger$1h.debug('task_completed_successfully', {
16583
16585
  task_name: taskName,
16584
16586
  task_id: taskId,
16585
16587
  duration_ms: Date.now() - task.startTime,
@@ -16633,7 +16635,7 @@
16633
16635
  error.name === 'AbortError' ||
16634
16636
  error.message === 'Task cancelled' ||
16635
16637
  error.message === 'Aborted') {
16636
- logger$1g.debug('task_cancelled', {
16638
+ logger$1h.debug('task_cancelled', {
16637
16639
  task_name: taskName,
16638
16640
  note: 'Task cancelled as requested',
16639
16641
  });
@@ -16641,7 +16643,7 @@
16641
16643
  }
16642
16644
  // Handle timeout
16643
16645
  if (error instanceof TaskTimeoutError) {
16644
- logger$1g.warning('task_timed_out', {
16646
+ logger$1h.warning('task_timed_out', {
16645
16647
  task_name: taskName,
16646
16648
  error: error.message,
16647
16649
  });
@@ -16653,7 +16655,7 @@
16653
16655
  // Handle known WebSocket shutdown race condition (similar to Python version)
16654
16656
  if (error.message.includes("await wasn't used with future") ||
16655
16657
  error.message.includes('WebSocket closed during receive')) {
16656
- logger$1g.debug('task_shutdown_race_condition_handled', {
16658
+ logger$1h.debug('task_shutdown_race_condition_handled', {
16657
16659
  task_name: taskName,
16658
16660
  note: 'Normal WebSocket close timing during shutdown - not an error',
16659
16661
  });
@@ -16663,7 +16665,7 @@
16663
16665
  if (error.name === 'FameTransportClose' ||
16664
16666
  error.message.includes('normal closure') ||
16665
16667
  error.message.includes('Connection closed')) {
16666
- logger$1g.debug('task_shutdown_completed_normally', {
16668
+ logger$1h.debug('task_shutdown_completed_normally', {
16667
16669
  task_name: taskName,
16668
16670
  note: 'Task closed normally during shutdown',
16669
16671
  });
@@ -16671,7 +16673,7 @@
16671
16673
  }
16672
16674
  // Handle PKCE redirect "errors" as info
16673
16675
  if (error.name === 'OAuth2PkceRedirectInitiatedError') {
16674
- logger$1g.debug('background_task_redirecting', {
16676
+ logger$1h.debug('background_task_redirecting', {
16675
16677
  task_name: taskName,
16676
16678
  note: 'Task interrupted for PKCE redirect',
16677
16679
  });
@@ -16684,14 +16686,14 @@
16684
16686
  // Log retriable errors as warnings (they'll be retried by upstream logic)
16685
16687
  // Log non-retriable errors as errors (fatal failures)
16686
16688
  if (isRetriableError) {
16687
- logger$1g.warning('background_task_failed', {
16689
+ logger$1h.warning('background_task_failed', {
16688
16690
  task_name: taskName,
16689
16691
  error: error.message,
16690
16692
  retriable: true,
16691
16693
  });
16692
16694
  }
16693
16695
  else {
16694
- logger$1g.error('background_task_failed', {
16696
+ logger$1h.error('background_task_failed', {
16695
16697
  task_name: taskName,
16696
16698
  error: error.message,
16697
16699
  stack: error.stack,
@@ -16710,11 +16712,11 @@
16710
16712
  async shutdownTasks(options = {}) {
16711
16713
  const { gracePeriod, cancelHanging, joinTimeout } = normalizeShutdownOptions(options);
16712
16714
  if (this._tasks.size === 0) {
16713
- logger$1g.debug('shutdown_tasks_no_tasks_to_shutdown');
16715
+ logger$1h.debug('shutdown_tasks_no_tasks_to_shutdown');
16714
16716
  return;
16715
16717
  }
16716
16718
  this._suppressCompletionLogging = true;
16717
- logger$1g.debug('shutting_down_tasks', {
16719
+ logger$1h.debug('shutting_down_tasks', {
16718
16720
  task_count: this._tasks.size,
16719
16721
  task_names: Array.from(this._tasks.values()).map((t) => t.name),
16720
16722
  grace_period_ms: gracePeriod,
@@ -16729,7 +16731,7 @@
16729
16731
  if (cancelHanging) {
16730
16732
  const stillRunning = tasks.filter((task) => task.getState() === TaskState.RUNNING && !completed.has(task));
16731
16733
  if (stillRunning.length > 0) {
16732
- logger$1g.debug('tasks_did_not_complete_within_grace_period', {
16734
+ logger$1h.debug('tasks_did_not_complete_within_grace_period', {
16733
16735
  hanging_count: stillRunning.length,
16734
16736
  });
16735
16737
  // Wait for them to finish with individual timeouts
@@ -16739,7 +16741,7 @@
16739
16741
  }
16740
16742
  catch (error) {
16741
16743
  if (error instanceof TaskTimeoutError) {
16742
- logger$1g.warning('task_did_not_shutdown', {
16744
+ logger$1h.warning('task_did_not_shutdown', {
16743
16745
  task_name: task.name || task.id,
16744
16746
  join_timeout_ms: joinTimeout,
16745
16747
  });
@@ -16750,7 +16752,7 @@
16750
16752
  }
16751
16753
  else if (!(error instanceof TaskCancelledError)) {
16752
16754
  /* istanbul ignore next - unreachable defensive branch */
16753
- logger$1g.error('task_raised_during_cancellation', {
16755
+ logger$1h.error('task_raised_during_cancellation', {
16754
16756
  task_name: task.name || task.id,
16755
16757
  error: error instanceof Error ? error.message : String(error),
16756
16758
  });
@@ -17368,7 +17370,7 @@
17368
17370
  * condition/promise and ensure at most one notifier coroutine exists for a
17369
17371
  * flow at any time.
17370
17372
  */
17371
- const logger$1f = getLogger('naylence.fame.flow.flow_controller');
17373
+ const logger$1g = getLogger('naylence.fame.flow.flow_controller');
17372
17374
  /**
17373
17375
  * Simple condition variable implementation for TypeScript/Node.js
17374
17376
  * Similar to Python's asyncio.Condition
@@ -17502,7 +17504,7 @@
17502
17504
  const newBalance = Math.max(0, Math.min(this.initialWindow, prev + delta));
17503
17505
  this.credits.set(flowId, newBalance);
17504
17506
  const crossedZero = prev <= 0 && newBalance > 0;
17505
- logger$1f.debug('flow_controller_add_credits', {
17507
+ logger$1g.debug('flow_controller_add_credits', {
17506
17508
  flow_id: flowId,
17507
17509
  delta,
17508
17510
  prev_balance: prev,
@@ -17522,12 +17524,12 @@
17522
17524
  async acquire(flowId) {
17523
17525
  this.ensureFlow(flowId);
17524
17526
  const condition = this.conditions.get(flowId);
17525
- logger$1f.debug('flow_controller_acquire_attempt', {
17527
+ logger$1g.debug('flow_controller_acquire_attempt', {
17526
17528
  flow_id: flowId,
17527
17529
  current_balance: this.credits.get(flowId),
17528
17530
  });
17529
17531
  while (this.credits.get(flowId) <= 0) {
17530
- logger$1f.debug('flow_controller_waiting_for_credits', {
17532
+ logger$1g.debug('flow_controller_waiting_for_credits', {
17531
17533
  flow_id: flowId,
17532
17534
  current_balance: this.credits.get(flowId),
17533
17535
  });
@@ -17535,12 +17537,12 @@
17535
17537
  }
17536
17538
  const newBalance = this.credits.get(flowId) - 1;
17537
17539
  this.credits.set(flowId, newBalance);
17538
- logger$1f.debug('flow_controller_acquire_success', {
17540
+ logger$1g.debug('flow_controller_acquire_success', {
17539
17541
  flow_id: flowId,
17540
17542
  new_balance: newBalance,
17541
17543
  });
17542
17544
  if (newBalance <= this.lowWatermark) {
17543
- logger$1f.debug('flow_controller_acquire_below_low_watermark', {
17545
+ logger$1g.debug('flow_controller_acquire_below_low_watermark', {
17544
17546
  flow_id: flowId,
17545
17547
  low_watermark: this.lowWatermark,
17546
17548
  });
@@ -17564,7 +17566,7 @@
17564
17566
  const current = this.credits.get(flowId);
17565
17567
  const remaining = Math.max(current - credits, 0);
17566
17568
  this.credits.set(flowId, remaining);
17567
- logger$1f.debug('flow_controller_consume', {
17569
+ logger$1g.debug('flow_controller_consume', {
17568
17570
  flow_id: flowId,
17569
17571
  requested: credits,
17570
17572
  prev_balance: current,
@@ -17590,7 +17592,7 @@
17590
17592
  this.windowIds.delete(flowId);
17591
17593
  this.credits.set(flowId, this.initialWindow);
17592
17594
  this.wakeWaiters(flowId);
17593
- logger$1f.debug('flow_controller_flow_reset', {
17595
+ logger$1g.debug('flow_controller_flow_reset', {
17594
17596
  flow_id: flowId,
17595
17597
  reset_balance: this.initialWindow,
17596
17598
  });
@@ -17971,7 +17973,7 @@
17971
17973
  return new EnvCredentialProvider(resolved.varName);
17972
17974
  }
17973
17975
  }
17974
- const FACTORY_META$1b = {
17976
+ const FACTORY_META$1c = {
17975
17977
  base: CREDENTIAL_PROVIDER_FACTORY_BASE_TYPE,
17976
17978
  key: 'EnvCredentialProvider',
17977
17979
  };
@@ -17979,7 +17981,7 @@
17979
17981
  var envCredentialProviderFactory = /*#__PURE__*/Object.freeze({
17980
17982
  __proto__: null,
17981
17983
  EnvCredentialProviderFactory: EnvCredentialProviderFactory,
17982
- FACTORY_META: FACTORY_META$1b,
17984
+ FACTORY_META: FACTORY_META$1c,
17983
17985
  default: EnvCredentialProviderFactory,
17984
17986
  normalizeEnvConfig: normalizeEnvConfig
17985
17987
  });
@@ -18077,14 +18079,14 @@
18077
18079
  return new PromptCredentialProvider(resolved.credentialName);
18078
18080
  }
18079
18081
  }
18080
- const FACTORY_META$1a = {
18082
+ const FACTORY_META$1b = {
18081
18083
  base: CREDENTIAL_PROVIDER_FACTORY_BASE_TYPE,
18082
18084
  key: 'PromptCredentialProvider',
18083
18085
  };
18084
18086
 
18085
18087
  var promptCredentialProviderFactory = /*#__PURE__*/Object.freeze({
18086
18088
  __proto__: null,
18087
- FACTORY_META: FACTORY_META$1a,
18089
+ FACTORY_META: FACTORY_META$1b,
18088
18090
  PromptCredentialProviderFactory: PromptCredentialProviderFactory,
18089
18091
  default: PromptCredentialProviderFactory,
18090
18092
  normalizePromptConfig: normalizePromptConfig
@@ -18138,14 +18140,14 @@
18138
18140
  return new SecretStoreCredentialProvider(resolved.secretName);
18139
18141
  }
18140
18142
  }
18141
- const FACTORY_META$19 = {
18143
+ const FACTORY_META$1a = {
18142
18144
  base: CREDENTIAL_PROVIDER_FACTORY_BASE_TYPE,
18143
18145
  key: 'SecretStoreCredentialProvider',
18144
18146
  };
18145
18147
 
18146
18148
  var secretStoreCredentialProviderFactory = /*#__PURE__*/Object.freeze({
18147
18149
  __proto__: null,
18148
- FACTORY_META: FACTORY_META$19,
18150
+ FACTORY_META: FACTORY_META$1a,
18149
18151
  SecretStoreCredentialProviderFactory: SecretStoreCredentialProviderFactory,
18150
18152
  default: SecretStoreCredentialProviderFactory,
18151
18153
  normalizeSecretStoreConfig: normalizeSecretStoreConfig
@@ -18194,14 +18196,14 @@
18194
18196
  return new StaticCredentialProvider(resolved.credentialValue);
18195
18197
  }
18196
18198
  }
18197
- const FACTORY_META$18 = {
18199
+ const FACTORY_META$19 = {
18198
18200
  base: CREDENTIAL_PROVIDER_FACTORY_BASE_TYPE,
18199
18201
  key: 'StaticCredentialProvider',
18200
18202
  };
18201
18203
 
18202
18204
  var staticCredentialProviderFactory = /*#__PURE__*/Object.freeze({
18203
18205
  __proto__: null,
18204
- FACTORY_META: FACTORY_META$18,
18206
+ FACTORY_META: FACTORY_META$19,
18205
18207
  StaticCredentialProviderFactory: StaticCredentialProviderFactory,
18206
18208
  default: StaticCredentialProviderFactory,
18207
18209
  normalizeStaticConfig: normalizeStaticConfig
@@ -19412,7 +19414,7 @@
19412
19414
  return value;
19413
19415
  }
19414
19416
 
19415
- const logger$1d = getLogger('naylence.fame.node.binding_manager');
19417
+ const logger$1e = getLogger('naylence.fame.node.binding_manager');
19416
19418
  const SYSTEM_INBOX$3 = '__sys__';
19417
19419
  const DEFAULT_ACK_TIMEOUT_MS = 20000;
19418
19420
  class BindingStoreEntryRecord {
@@ -19498,7 +19500,7 @@
19498
19500
  if (!this.bindings.has(key)) {
19499
19501
  const binding = this.bindingFactory(new FameAddress(key));
19500
19502
  this.bindings.set(key, binding);
19501
- logger$1d.debug('restored_binding', { address: key });
19503
+ logger$1e.debug('restored_binding', { address: key });
19502
19504
  }
19503
19505
  }
19504
19506
  if (!this.hasUpstream) {
@@ -19508,13 +19510,13 @@
19508
19510
  await this.readvertiseCapabilitiesUpstream();
19509
19511
  }
19510
19512
  async bind(participant, capabilities) {
19511
- logger$1d.debug('binding_participant', { participant });
19513
+ logger$1e.debug('binding_participant', { participant });
19512
19514
  const { prefixAddress, addresses, propagateAddress, capabilityAddress } = this.computeBindingAddresses(participant);
19513
19515
  for (const address of addresses) {
19514
19516
  if (!this.bindings.has(address)) {
19515
19517
  const binding = this.bindingFactory(new FameAddress(address));
19516
19518
  this.bindings.set(address, binding);
19517
- logger$1d.debug('bound_address', { address, participant });
19519
+ logger$1e.debug('bound_address', { address, participant });
19518
19520
  }
19519
19521
  }
19520
19522
  let propagatedAddress = null;
@@ -19543,7 +19545,7 @@
19543
19545
  await this.unbindAddressUpstream(propagatedAddress);
19544
19546
  }
19545
19547
  catch (rollbackError) {
19546
- logger$1d.error('bind_rollback_failed', {
19548
+ logger$1e.error('bind_rollback_failed', {
19547
19549
  address: propagatedAddress.toString(),
19548
19550
  error: rollbackError.message,
19549
19551
  });
@@ -19562,7 +19564,7 @@
19562
19564
  physicalPath: null,
19563
19565
  });
19564
19566
  }
19565
- logger$1d.debug('bind_success', {
19567
+ logger$1e.debug('bind_success', {
19566
19568
  participant,
19567
19569
  address: prefixAddress.toString(),
19568
19570
  capabilities,
@@ -19598,7 +19600,7 @@
19598
19600
  await this.bindingStore.delete(address);
19599
19601
  }
19600
19602
  }
19601
- logger$1d.debug('unbind_success', {
19603
+ logger$1e.debug('unbind_success', {
19602
19604
  participant,
19603
19605
  address: prefixAddress.toString(),
19604
19606
  totalBindings: this.bindings.size,
@@ -19628,7 +19630,7 @@
19628
19630
  await this.bindAddressUpstream(new FameAddress(address));
19629
19631
  }
19630
19632
  catch (error) {
19631
- logger$1d.error('rebind_failed', {
19633
+ logger$1e.error('rebind_failed', {
19632
19634
  address,
19633
19635
  error: error.message,
19634
19636
  });
@@ -19647,7 +19649,7 @@
19647
19649
  await this.advertiseCapabilities(new FameAddress(address), Array.from(capabilities));
19648
19650
  }
19649
19651
  catch (error) {
19650
- logger$1d.error('capability_replay_failed', {
19652
+ logger$1e.error('capability_replay_failed', {
19651
19653
  address,
19652
19654
  error: error.message,
19653
19655
  });
@@ -19914,7 +19916,7 @@
19914
19916
  }
19915
19917
  }
19916
19918
 
19917
- const logger$1c = getLogger('naylence.fame.node.response_context_manager');
19919
+ const logger$1d = getLogger('naylence.fame.node.response_context_manager');
19918
19920
  function cloneSecurityContext(source) {
19919
19921
  if (!source) {
19920
19922
  return undefined;
@@ -19942,7 +19944,7 @@
19942
19944
  security: responseSecurity,
19943
19945
  expectedResponseType: FameResponseType.NONE,
19944
19946
  };
19945
- logger$1c.debug('created_response_context', {
19947
+ logger$1d.debug('created_response_context', {
19946
19948
  request_id: requestEnvelope.id,
19947
19949
  inherited_crypto_level: responseSecurity?.inboundCryptoLevel ?? null,
19948
19950
  channel_id: responseSecurity?.cryptoChannelId ?? null,
@@ -19962,14 +19964,14 @@
19962
19964
  responseContext.fromSystemId = this.getId();
19963
19965
  }
19964
19966
  // Envelope-level metadata is intentionally omitted to defer to context usage.
19965
- logger$1c.debug('ensured_response_metadata', {
19967
+ logger$1d.debug('ensured_response_metadata', {
19966
19968
  response_id: responseEnvelope.id,
19967
19969
  request_id: requestEnvelope.id,
19968
19970
  });
19969
19971
  }
19970
19972
  }
19971
19973
 
19972
- const logger$1b = getLogger('naylence.fame.node.streaming_response_handler');
19974
+ const logger$1c = getLogger('naylence.fame.node.streaming_response_handler');
19973
19975
  function isObject$1(value) {
19974
19976
  return typeof value === 'object' && value !== null;
19975
19977
  }
@@ -20088,12 +20090,12 @@
20088
20090
  }
20089
20091
  async handleStreamingFameMessageResponses(responses, requestEnvelope, requestContext) {
20090
20092
  const asyncResponses = toAsyncIterable(responses);
20091
- logger$1b.debug('handling_streaming_fame_message_responses', {
20093
+ logger$1c.debug('handling_streaming_fame_message_responses', {
20092
20094
  request_id: requestEnvelope.id,
20093
20095
  });
20094
20096
  for await (const response of asyncResponses) {
20095
20097
  if (!response?.envelope) {
20096
- logger$1b.warning('invalid_streaming_response_type', {
20098
+ logger$1c.warning('invalid_streaming_response_type', {
20097
20099
  request_id: requestEnvelope.id,
20098
20100
  actual_type: typeof response,
20099
20101
  });
@@ -20107,7 +20109,7 @@
20107
20109
  }
20108
20110
  async handleStreamingResponse(result, requestEnvelope, requestContext, replyTo, requestId) {
20109
20111
  const iterable = toAsyncIterable(result);
20110
- logger$1b.debug('handling_streaming_response', {
20112
+ logger$1c.debug('handling_streaming_response', {
20111
20113
  request_id: requestId,
20112
20114
  reply_to: replyTo,
20113
20115
  });
@@ -20118,7 +20120,7 @@
20118
20120
  await this.sendRpcResponse(null, requestEnvelope, requestContext, replyTo, requestId);
20119
20121
  }
20120
20122
  catch (error) {
20121
- logger$1b.error('streaming_response_handler_error', {
20123
+ logger$1c.error('streaming_response_handler_error', {
20122
20124
  request_id: requestId,
20123
20125
  error: error instanceof Error ? error.message : String(error),
20124
20126
  });
@@ -20145,7 +20147,7 @@
20145
20147
  });
20146
20148
  const responseContext = this.responseContextManager.createResponseContext(requestEnvelope, requestContext);
20147
20149
  this.responseContextManager.ensureResponseMetadata(responseEnvelope, requestEnvelope, responseContext);
20148
- logger$1b.debug('sending_streaming_rpc_response', {
20150
+ logger$1c.debug('sending_streaming_rpc_response', {
20149
20151
  request_id: requestId,
20150
20152
  response_envelope_id: responseEnvelope.id,
20151
20153
  reply_to: replyTo,
@@ -20158,7 +20160,7 @@
20158
20160
  }
20159
20161
  }
20160
20162
 
20161
- const logger$1a = getLogger('naylence.fame.node.channel_polling_manager');
20163
+ const logger$1b = getLogger('naylence.fame.node.channel_polling_manager');
20162
20164
  class ChannelPollingManager {
20163
20165
  constructor(deliverWrapper, responseContextManager, streamingResponseHandler) {
20164
20166
  this.deliverWrapper = deliverWrapper;
@@ -20166,7 +20168,7 @@
20166
20168
  this.streamingResponseHandler = streamingResponseHandler;
20167
20169
  }
20168
20170
  async startPollingLoop(serviceName, channel, handler, stopState, pollTimeoutMs = DEFAULT_POLLING_TIMEOUT_MS) {
20169
- logger$1a.debug('poll_loop_started', {
20171
+ logger$1b.debug('poll_loop_started', {
20170
20172
  recipient: serviceName,
20171
20173
  });
20172
20174
  try {
@@ -20174,7 +20176,7 @@
20174
20176
  while (true) {
20175
20177
  if (this.isStopRequested(stopState) && !draining) {
20176
20178
  draining = true;
20177
- logger$1a.debug('poll_loop_draining_pending_messages', {
20179
+ logger$1b.debug('poll_loop_draining_pending_messages', {
20178
20180
  recipient: serviceName,
20179
20181
  });
20180
20182
  }
@@ -20184,7 +20186,7 @@
20184
20186
  }
20185
20187
  catch (error) {
20186
20188
  if (error instanceof FameTransportClose) {
20187
- logger$1a.debug('channel_closed', {
20189
+ logger$1b.debug('channel_closed', {
20188
20190
  recipient: serviceName,
20189
20191
  message: error.message,
20190
20192
  });
@@ -20197,7 +20199,7 @@
20197
20199
  continue;
20198
20200
  }
20199
20201
  if (error instanceof Error && error.name === 'AbortError') {
20200
- logger$1a.debug('listener_cancelled', {
20202
+ logger$1b.debug('listener_cancelled', {
20201
20203
  recipient: serviceName,
20202
20204
  });
20203
20205
  throw error;
@@ -20209,13 +20211,13 @@
20209
20211
  continue;
20210
20212
  }
20211
20213
  if (error instanceof Error && error.message === 'Channel is closed') {
20212
- logger$1a.debug('channel_closed', {
20214
+ logger$1b.debug('channel_closed', {
20213
20215
  recipient: serviceName,
20214
20216
  });
20215
20217
  break;
20216
20218
  }
20217
20219
  if (error instanceof Error && error.name === 'TaskCancelledError') {
20218
- logger$1a.debug('listener_cancelled', {
20220
+ logger$1b.debug('listener_cancelled', {
20219
20221
  recipient: serviceName,
20220
20222
  });
20221
20223
  throw error;
@@ -20227,12 +20229,12 @@
20227
20229
  continue;
20228
20230
  }
20229
20231
  if (error instanceof Error && error.message.includes('closed')) {
20230
- logger$1a.debug('channel_closed', {
20232
+ logger$1b.debug('channel_closed', {
20231
20233
  recipient: serviceName,
20232
20234
  });
20233
20235
  break;
20234
20236
  }
20235
- logger$1a.error('transport_error', {
20237
+ logger$1b.error('transport_error', {
20236
20238
  recipient: serviceName,
20237
20239
  error: error instanceof Error ? error.message : String(error),
20238
20240
  });
@@ -20248,7 +20250,7 @@
20248
20250
  }
20249
20251
  }
20250
20252
  finally {
20251
- logger$1a.debug('poll_loop_exiting', {
20253
+ logger$1b.debug('poll_loop_exiting', {
20252
20254
  recipient: serviceName,
20253
20255
  });
20254
20256
  }
@@ -20261,7 +20263,7 @@
20261
20263
  await this.processHandlerResult(result, envelope, deliveryContext, serviceName);
20262
20264
  }
20263
20265
  catch (error) {
20264
- logger$1a.error('handler_crashed', {
20266
+ logger$1b.error('handler_crashed', {
20265
20267
  recipient: serviceName,
20266
20268
  error: error instanceof Error ? error.message : String(error),
20267
20269
  });
@@ -20275,7 +20277,7 @@
20275
20277
  return;
20276
20278
  }
20277
20279
  if (this.streamingResponseHandler.isStreamingFameMessageResponse(result)) {
20278
- logger$1a.debug('handling_streaming_fame_message_responses', {
20280
+ logger$1b.debug('handling_streaming_fame_message_responses', {
20279
20281
  service_name: serviceName,
20280
20282
  envelope_id: envelope.id,
20281
20283
  });
@@ -20283,7 +20285,7 @@
20283
20285
  }
20284
20286
  }
20285
20287
  async handleMessageResponse(response, requestEnvelope, requestContext, serviceName) {
20286
- logger$1a.debug('delivering_envelope_response_message', {
20288
+ logger$1b.debug('delivering_envelope_response_message', {
20287
20289
  service_name: serviceName,
20288
20290
  response_envelope_id: response.envelope.id,
20289
20291
  });
@@ -20303,7 +20305,7 @@
20303
20305
  }
20304
20306
  }
20305
20307
 
20306
- const logger$19 = getLogger('naylence.fame.node.rpc_server_handler');
20308
+ const logger$1a = getLogger('naylence.fame.node.rpc_server_handler');
20307
20309
  function isPlainRecord$6(value) {
20308
20310
  if (typeof value !== 'object' || value === null) {
20309
20311
  return false;
@@ -20347,13 +20349,13 @@
20347
20349
  }
20348
20350
  async handleRpcRequest(envelope, handlerContext, handler, serviceName) {
20349
20351
  if (!this.isDataFrame(envelope.frame)) {
20350
- logger$19.warning('rpc_request_missing_data_frame', {
20352
+ logger$1a.warning('rpc_request_missing_data_frame', {
20351
20353
  service_name: serviceName,
20352
20354
  envelope_id: envelope.id,
20353
20355
  });
20354
20356
  return;
20355
20357
  }
20356
- logger$19.debug('rpc_request_received', {
20358
+ logger$1a.debug('rpc_request_received', {
20357
20359
  service_name: serviceName,
20358
20360
  envelope_id: envelope.id,
20359
20361
  trace_id: envelope.traceId,
@@ -20365,7 +20367,7 @@
20365
20367
  request = parseRequest(envelope.frame.payload);
20366
20368
  params = cloneParams(request.params);
20367
20369
  const paramKeys = Object.keys(params);
20368
- logger$19.debug('parsed_rpc_request', {
20370
+ logger$1a.debug('parsed_rpc_request', {
20369
20371
  service_name: serviceName,
20370
20372
  method: request.method,
20371
20373
  request_id: request.id,
@@ -20374,7 +20376,7 @@
20374
20376
  });
20375
20377
  }
20376
20378
  catch (error) {
20377
- logger$19.warning('request_decode_error', {
20379
+ logger$1a.warning('request_decode_error', {
20378
20380
  service_name: serviceName,
20379
20381
  envelope_id: envelope.id,
20380
20382
  error: error instanceof Error ? error.message : String(error),
@@ -20382,7 +20384,7 @@
20382
20384
  return;
20383
20385
  }
20384
20386
  if (request.id == null) {
20385
- logger$19.warning('request_missing_id', {
20387
+ logger$1a.warning('request_missing_id', {
20386
20388
  service_name: serviceName,
20387
20389
  envelope_id: envelope.id,
20388
20390
  });
@@ -20390,7 +20392,7 @@
20390
20392
  }
20391
20393
  const replyTo = this.resolveReplyTo(envelope, params);
20392
20394
  if (!replyTo) {
20393
- logger$19.warning('missing_reply_to', {
20395
+ logger$1a.warning('missing_reply_to', {
20394
20396
  service_name: serviceName,
20395
20397
  envelope_id: envelope.id,
20396
20398
  request_id: request.id,
@@ -20399,13 +20401,13 @@
20399
20401
  }
20400
20402
  let handlerResult;
20401
20403
  try {
20402
- logger$19.debug('calling_rpc_handler', {
20404
+ logger$1a.debug('calling_rpc_handler', {
20403
20405
  service_name: serviceName,
20404
20406
  method: request.method,
20405
20407
  request_id: request.id,
20406
20408
  });
20407
20409
  handlerResult = await handler(request.method, params);
20408
- logger$19.debug('rpc_handler_returned', {
20410
+ logger$1a.debug('rpc_handler_returned', {
20409
20411
  service_name: serviceName,
20410
20412
  method: request.method,
20411
20413
  request_id: request.id,
@@ -20414,7 +20416,7 @@
20414
20416
  });
20415
20417
  }
20416
20418
  catch (error) {
20417
- logger$19.error('rpc_handler_error', {
20419
+ logger$1a.error('rpc_handler_error', {
20418
20420
  service_name: serviceName,
20419
20421
  request_id: request.id,
20420
20422
  envelope_id: envelope.id,
@@ -20424,7 +20426,7 @@
20424
20426
  return this.createTraditionalResponse(response, request.id, envelope, replyTo, handlerContext, serviceName);
20425
20427
  }
20426
20428
  if (isFameMessageResponse(handlerResult)) {
20427
- logger$19.debug('returning_response_message', {
20429
+ logger$1a.debug('returning_response_message', {
20428
20430
  service_name: serviceName,
20429
20431
  request_id: request.id,
20430
20432
  response_envelope_id: handlerResult.envelope.id,
@@ -20432,7 +20434,7 @@
20432
20434
  return handlerResult;
20433
20435
  }
20434
20436
  if (this.streamingResponseHandler.isStreamingResult(handlerResult)) {
20435
- logger$19.debug('handling_streaming_response', {
20437
+ logger$1a.debug('handling_streaming_response', {
20436
20438
  service_name: serviceName,
20437
20439
  request_id: request.id,
20438
20440
  envelope_id: envelope.id,
@@ -20461,7 +20463,7 @@
20461
20463
  return null;
20462
20464
  }
20463
20465
  async createTraditionalResponse(payload, requestId, requestEnvelope, replyTo, handlerContext, serviceName) {
20464
- logger$19.debug('creating_traditional_response_envelope', {
20466
+ logger$1a.debug('creating_traditional_response_envelope', {
20465
20467
  service_name: serviceName,
20466
20468
  request_id: requestId,
20467
20469
  envelope_id: requestEnvelope.id,
@@ -20485,7 +20487,7 @@
20485
20487
  if (requestEnvelope.id) {
20486
20488
  responseContext.meta['response-to-id'] = requestEnvelope.id;
20487
20489
  }
20488
- logger$19.debug('returning_traditional_response', {
20490
+ logger$1a.debug('returning_traditional_response', {
20489
20491
  service_name: serviceName,
20490
20492
  request_id: requestId,
20491
20493
  envelope_id: requestEnvelope.id,
@@ -20550,7 +20552,7 @@
20550
20552
  return code;
20551
20553
  }
20552
20554
 
20553
- const logger$18 = getLogger('naylence.fame.node.rpc_client_manager');
20555
+ const logger$19 = getLogger('naylence.fame.node.rpc_client_manager');
20554
20556
  function isPlainRecord$5(value) {
20555
20557
  if (typeof value !== 'object' || value === null) {
20556
20558
  return false;
@@ -20767,7 +20769,7 @@
20767
20769
  const metaReason = tracked.meta?.['nack_reason'];
20768
20770
  const formattedMessage = formatDeliveryErrorMessage(typeof metaCode === 'string' ? metaCode : 'DELIVERY_ERROR', reason ??
20769
20771
  (typeof metaReason === 'string' ? metaReason : undefined));
20770
- logger$18.debug('pending_request_rejected_by_delivery_nack', {
20772
+ logger$19.debug('pending_request_rejected_by_delivery_nack', {
20771
20773
  envelope_id: envelopeId,
20772
20774
  request_id: requestId,
20773
20775
  code: typeof metaCode === 'string' ? metaCode : 'DELIVERY_ERROR',
@@ -20790,7 +20792,7 @@
20790
20792
  this.trackerWithEvents.removeEventHandler?.(this.trackerEventHandler);
20791
20793
  }
20792
20794
  catch (error) {
20793
- logger$18.debug('rpc_tracker_handler_remove_failed', {
20795
+ logger$19.debug('rpc_tracker_handler_remove_failed', {
20794
20796
  error: error instanceof Error ? error.message : String(error),
20795
20797
  });
20796
20798
  }
@@ -20833,7 +20835,7 @@
20833
20835
  this.rpcListenerAddress = await this.listenCallback(recipient, handler);
20834
20836
  this.rpcBound = true;
20835
20837
  this.boundPhysicalPath = currentPhysicalPath;
20836
- logger$18.debug('rpc_reply_listener_bound', {
20838
+ logger$19.debug('rpc_reply_listener_bound', {
20837
20839
  reply_recipient: recipient,
20838
20840
  reply_address: this.rpcReplyAddress?.toString(),
20839
20841
  listener_address: this.rpcListenerAddress?.toString(),
@@ -20927,7 +20929,7 @@
20927
20929
  const finalizePromise = this.notifyStreamClosed(envelopeId);
20928
20930
  if (finalizePromise) {
20929
20931
  finalizePromise.catch((notifyError) => {
20930
- logger$18.debug('stream_tracker_finalize_failed', {
20932
+ logger$19.debug('stream_tracker_finalize_failed', {
20931
20933
  request_id: requestId,
20932
20934
  envelope_id: envelopeId,
20933
20935
  error: notifyError instanceof Error
@@ -20988,7 +20990,7 @@
20988
20990
  return iterator;
20989
20991
  }
20990
20992
  async sendRpcRequest(requestId, envelope, expectedResponseType, timeoutMs) {
20991
- logger$18.debug('sending_rpc_request', {
20993
+ logger$19.debug('sending_rpc_request', {
20992
20994
  envp_id: envelope.id,
20993
20995
  corr_id: envelope.corrId,
20994
20996
  request_id: requestId,
@@ -21004,7 +21006,7 @@
21004
21006
  }
21005
21007
  }
21006
21008
  catch (error) {
21007
- logger$18.warning('delivery_tracker_track_failed', {
21009
+ logger$19.warning('delivery_tracker_track_failed', {
21008
21010
  request_id: requestId,
21009
21011
  error: error instanceof Error ? error.message : String(error),
21010
21012
  });
@@ -21017,14 +21019,14 @@
21017
21019
  await this.deliverWrapper()(envelope, context);
21018
21020
  }
21019
21021
  async handleReplyEnvelope(envelope) {
21020
- logger$18.debug('handle_reply_envelope_received', {
21022
+ logger$19.debug('handle_reply_envelope_received', {
21021
21023
  envelope_id: envelope.id,
21022
21024
  corr_id: envelope.corrId,
21023
21025
  frame_type: envelope.frame?.['type'],
21024
21026
  });
21025
21027
  let requestId = envelope.corrId ?? envelope.id;
21026
21028
  if (!requestId) {
21027
- logger$18.warning('reply_envelope_missing_corr_id', {
21029
+ logger$19.warning('reply_envelope_missing_corr_id', {
21028
21030
  envelope_id: envelope.id,
21029
21031
  });
21030
21032
  return;
@@ -21042,12 +21044,12 @@
21042
21044
  }
21043
21045
  }
21044
21046
  if (!entry) {
21045
- logger$18.debug('no_pending_request_for_reply', {
21047
+ logger$19.debug('no_pending_request_for_reply', {
21046
21048
  request_id: requestId,
21047
21049
  });
21048
21050
  return;
21049
21051
  }
21050
- logger$18.debug('handle_reply_envelope', {
21052
+ logger$19.debug('handle_reply_envelope', {
21051
21053
  envelope_id: envelope.id,
21052
21054
  request_id: requestId,
21053
21055
  corr_id: envelope.corrId,
@@ -21060,7 +21062,7 @@
21060
21062
  const ackIndicatesSuccess = frame.ok === true ||
21061
21063
  (frame.ok === undefined && !frame.code && !frame.reason);
21062
21064
  if (ackIndicatesSuccess) {
21063
- logger$18.debug('pending_request_delivery_acknowledged', {
21065
+ logger$19.debug('pending_request_delivery_acknowledged', {
21064
21066
  request_id: requestId,
21065
21067
  envelope_id: envelope.id,
21066
21068
  ref_id: frame.refId ?? null,
@@ -21088,7 +21090,7 @@
21088
21090
  entry.timer = null;
21089
21091
  }
21090
21092
  if (!this.isDataFrame(envelope.frame)) {
21091
- logger$18.warning('unexpected_reply_frame_type', {
21093
+ logger$19.warning('unexpected_reply_frame_type', {
21092
21094
  request_id: requestId,
21093
21095
  frame_type: envelope.frame?.['type'],
21094
21096
  });
@@ -21154,7 +21156,7 @@
21154
21156
  return;
21155
21157
  }
21156
21158
  Promise.resolve(this.deliveryTracker.onStreamItem(envelopeId, envelope)).catch((error) => {
21157
- logger$18.debug('stream_tracker_push_failed', {
21159
+ logger$19.debug('stream_tracker_push_failed', {
21158
21160
  envelope_id: envelopeId,
21159
21161
  error: error instanceof Error ? error.message : String(error),
21160
21162
  });
@@ -21269,7 +21271,7 @@
21269
21271
  return mailbox;
21270
21272
  }
21271
21273
 
21272
- const logger$17 = getLogger('naylence.fame.node.envelope_listener_manager');
21274
+ const logger$18 = getLogger('naylence.fame.node.envelope_listener_manager');
21273
21275
  const SYSTEM_INBOX$2 = '__sys__';
21274
21276
  class EnvelopeListener {
21275
21277
  constructor(stopFn, task) {
@@ -21277,7 +21279,7 @@
21277
21279
  this.task = task;
21278
21280
  }
21279
21281
  stop() {
21280
- logger$17.debug('stopping_listener', {
21282
+ logger$18.debug('stopping_listener', {
21281
21283
  task_name: this.task.name,
21282
21284
  });
21283
21285
  try {
@@ -21285,7 +21287,7 @@
21285
21287
  if (maybeCleanup &&
21286
21288
  typeof maybeCleanup.then === 'function') {
21287
21289
  void maybeCleanup.catch((error) => {
21288
- logger$17.debug('listener_stop_cleanup_failed', {
21290
+ logger$18.debug('listener_stop_cleanup_failed', {
21289
21291
  task_name: this.task.name,
21290
21292
  error: error instanceof Error ? error.message : String(error),
21291
21293
  });
@@ -21293,7 +21295,7 @@
21293
21295
  }
21294
21296
  }
21295
21297
  catch (error) {
21296
- logger$17.debug('listener_stop_cleanup_failed', {
21298
+ logger$18.debug('listener_stop_cleanup_failed', {
21297
21299
  task_name: this.task.name,
21298
21300
  error: error instanceof Error ? error.message : String(error),
21299
21301
  });
@@ -21323,7 +21325,7 @@
21323
21325
  envelope.replyTo = formatAddress(SYSTEM_INBOX$2, this.nodeLike.physicalPath);
21324
21326
  }
21325
21327
  catch (error) {
21326
- logger$17.warning('default_reply_to_assignment_failed', {
21328
+ logger$18.warning('default_reply_to_assignment_failed', {
21327
21329
  envelope_id: envelope.id,
21328
21330
  service_name: envelope.capabilities?.[0] ?? null,
21329
21331
  error: error instanceof Error ? error.message : String(error),
@@ -21348,7 +21350,7 @@
21348
21350
  if (serviceName === SYSTEM_INBOX$2) {
21349
21351
  continue;
21350
21352
  }
21351
- logger$17.debug('stopping_listener_for_service', {
21353
+ logger$18.debug('stopping_listener_for_service', {
21352
21354
  service_name: serviceName,
21353
21355
  });
21354
21356
  entry.listener.stop();
@@ -21358,7 +21360,7 @@
21358
21360
  catch (error) {
21359
21361
  if (!(error instanceof Error) ||
21360
21362
  error.name !== 'TaskCancelledError') {
21361
- logger$17.debug('listener_task_stopped', {
21363
+ logger$18.debug('listener_task_stopped', {
21362
21364
  service_name: serviceName,
21363
21365
  error: error instanceof Error ? error.message : String(error),
21364
21366
  });
@@ -21366,7 +21368,7 @@
21366
21368
  }
21367
21369
  }
21368
21370
  if (systemEntry) {
21369
- logger$17.debug('stopping_listener_for_service', {
21371
+ logger$18.debug('stopping_listener_for_service', {
21370
21372
  service_name: SYSTEM_INBOX$2,
21371
21373
  });
21372
21374
  systemEntry.listener.stop();
@@ -21376,7 +21378,7 @@
21376
21378
  catch (error) {
21377
21379
  if (!(error instanceof Error) ||
21378
21380
  error.name !== 'TaskCancelledError') {
21379
- logger$17.debug('listener_task_stopped', {
21381
+ logger$18.debug('listener_task_stopped', {
21380
21382
  service_name: SYSTEM_INBOX$2,
21381
21383
  error: error instanceof Error ? error.message : String(error),
21382
21384
  });
@@ -21393,13 +21395,13 @@
21393
21395
  }
21394
21396
  async recoverUnhandledInboundEnvelopes() {
21395
21397
  if (typeof this.deliveryTracker.listInbound !== 'function') {
21396
- logger$17.debug('delivery_tracker_missing_inbound_listing');
21398
+ logger$18.debug('delivery_tracker_missing_inbound_listing');
21397
21399
  return;
21398
21400
  }
21399
21401
  const failedInbound = await this.deliveryTracker.listInbound((env) => env.status === EnvelopeStatus.RECEIVED ||
21400
21402
  env.status === EnvelopeStatus.FAILED_TO_HANDLE);
21401
21403
  if (!failedInbound.length) {
21402
- logger$17.debug('no_failed_inbound_envelopes_to_recover');
21404
+ logger$18.debug('no_failed_inbound_envelopes_to_recover');
21403
21405
  return;
21404
21406
  }
21405
21407
  const grouped = new Map();
@@ -21416,7 +21418,7 @@
21416
21418
  this.pendingRecoveryEnvelopes.set(serviceName, envelopes);
21417
21419
  }
21418
21420
  });
21419
- logger$17.debug('discovered_failed_inbound_envelopes', {
21421
+ logger$18.debug('discovered_failed_inbound_envelopes', {
21420
21422
  total: failedInbound.length,
21421
21423
  services: Array.from(grouped.keys()),
21422
21424
  });
@@ -21426,7 +21428,7 @@
21426
21428
  const pollTimeoutMs = options.pollTimeoutMs ??
21427
21429
  options.poll_timeout_ms ??
21428
21430
  DEFAULT_POLLING_TIMEOUT_MS;
21429
- logger$17.debug('listen_start', {
21431
+ logger$18.debug('listen_start', {
21430
21432
  recipient: serviceName,
21431
21433
  poll_timeout_ms: pollTimeoutMs ?? DEFAULT_POLLING_TIMEOUT_MS,
21432
21434
  });
@@ -21457,7 +21459,7 @@
21457
21459
  tracked?.mailboxType === MailboxType.OUTBOX ||
21458
21460
  envelope.frame?.['type'] === 'DeliveryAck';
21459
21461
  if (!shouldInvoke) {
21460
- logger$17.debug('skipping_listener_handler', {
21462
+ logger$18.debug('skipping_listener_handler', {
21461
21463
  recipient: serviceName,
21462
21464
  envelope_id: envelope.id,
21463
21465
  tracked_status: tracked?.status,
@@ -21471,13 +21473,13 @@
21471
21473
  ? undefined
21472
21474
  : (tracked ?? undefined);
21473
21475
  if (trackedForHandler && trackedForHandler.attempt > 0) {
21474
- logger$17.info('resuming_handler_retry_after_restart', {
21476
+ logger$18.info('resuming_handler_retry_after_restart', {
21475
21477
  envelope_id: envelope.id,
21476
21478
  current_attempts: trackedForHandler.attempt,
21477
21479
  service_name: serviceName,
21478
21480
  });
21479
21481
  }
21480
- logger$17.debug('forwarding_to_listener_handler', {
21482
+ logger$18.debug('forwarding_to_listener_handler', {
21481
21483
  recipient: serviceName,
21482
21484
  envelope_id: envelope.id,
21483
21485
  frame_type: envelope.frame?.['type'],
@@ -21496,7 +21498,7 @@
21496
21498
  await channel.send(null);
21497
21499
  }
21498
21500
  catch (error) {
21499
- logger$17.debug('listener_stop_signal_failed', {
21501
+ logger$18.debug('listener_stop_signal_failed', {
21500
21502
  service_name: serviceName,
21501
21503
  error: error instanceof Error ? error.message : String(error),
21502
21504
  });
@@ -21505,7 +21507,7 @@
21505
21507
  await this.listenersLock.runExclusive(async () => {
21506
21508
  const existing = this.listeners.get(serviceName);
21507
21509
  if (existing) {
21508
- logger$17.debug('replacing_envelope_listener', { recipient: serviceName });
21510
+ logger$18.debug('replacing_envelope_listener', { recipient: serviceName });
21509
21511
  existing.listener.stop();
21510
21512
  try {
21511
21513
  await existing.listener.task.promise;
@@ -21523,13 +21525,13 @@
21523
21525
  return binding.address;
21524
21526
  }
21525
21527
  async listenRpc(serviceName, handler, options = {}) {
21526
- logger$17.debug('rpc_listen_start', { service_name: serviceName });
21528
+ logger$18.debug('rpc_listen_start', { service_name: serviceName });
21527
21529
  const rpcHandler = async (envelope, context) => {
21528
21530
  const result = await this.rpcServerHandler.handleRpcRequest(envelope, context, handler, serviceName);
21529
21531
  return result ?? null;
21530
21532
  };
21531
21533
  const address = await this.listen(serviceName, rpcHandler, options);
21532
- logger$17.debug('rpc_listen_bound', {
21534
+ logger$18.debug('rpc_listen_bound', {
21533
21535
  service_name: serviceName,
21534
21536
  address: address.toString(),
21535
21537
  });
@@ -21598,12 +21600,12 @@
21598
21600
  return cached;
21599
21601
  });
21600
21602
  if (!envelopes.length) {
21601
- logger$17.debug('no_cached_recovery_for_service', {
21603
+ logger$18.debug('no_cached_recovery_for_service', {
21602
21604
  service_name: serviceName,
21603
21605
  });
21604
21606
  return;
21605
21607
  }
21606
- logger$17.debug('recovering_unhandled_envelopes_on_listen', {
21608
+ logger$18.debug('recovering_unhandled_envelopes_on_listen', {
21607
21609
  service_name: serviceName,
21608
21610
  count: envelopes.length,
21609
21611
  envelope_ids: envelopes.map((trackedEnvelope) => trackedEnvelope.envelopeId),
@@ -21614,7 +21616,7 @@
21614
21616
  async recoverServiceEnvelopes(serviceName, envelopes, handler) {
21615
21617
  for (const tracked of envelopes) {
21616
21618
  try {
21617
- logger$17.warning('recovering_unhandled_envelope', {
21619
+ logger$18.warning('recovering_unhandled_envelope', {
21618
21620
  envelope_id: tracked.envelopeId,
21619
21621
  service_name: serviceName,
21620
21622
  current_attempts: tracked.attempt,
@@ -21623,13 +21625,13 @@
21623
21625
  const originalEnvelope = tracked.originalEnvelope;
21624
21626
  const receiverPolicy = this.nodeLike.deliveryPolicy?.receiverRetryPolicy ?? undefined;
21625
21627
  await this.executeHandlerWithRetries(handler, originalEnvelope, undefined, receiverPolicy, tracked, serviceName);
21626
- logger$17.debug('envelope_recovery_completed', {
21628
+ logger$18.debug('envelope_recovery_completed', {
21627
21629
  envelope_id: tracked.envelopeId,
21628
21630
  service_name: serviceName,
21629
21631
  });
21630
21632
  }
21631
21633
  catch (error) {
21632
- logger$17.error('envelope_recovery_failed', {
21634
+ logger$18.error('envelope_recovery_failed', {
21633
21635
  envelope_id: tracked.envelopeId,
21634
21636
  service_name: serviceName,
21635
21637
  error: error instanceof Error ? error.message : String(error),
@@ -21675,7 +21677,7 @@
21675
21677
  await this.deliveryTracker.onEnvelopeHandled(trackedEnvelope);
21676
21678
  }
21677
21679
  if (currentAttempt > 0) {
21678
- logger$17.info('handler_retry_succeeded', {
21680
+ logger$18.info('handler_retry_succeeded', {
21679
21681
  envelope_id: envelope.id,
21680
21682
  attempt: currentAttempt + 1,
21681
21683
  total_attempts: currentAttempt + 1,
@@ -21691,7 +21693,7 @@
21691
21693
  await this.deliveryTracker.onEnvelopeHandleFailed(inboxName, trackedEnvelope, context, error instanceof Error ? error : new Error(String(error)), isFinalAttempt);
21692
21694
  }
21693
21695
  if (isFinalAttempt) {
21694
- logger$17.error('handler_execution_failed_exhausted_retries', {
21696
+ logger$18.error('handler_execution_failed_exhausted_retries', {
21695
21697
  envelope_id: envelope.id,
21696
21698
  total_attempts: attemptNumber,
21697
21699
  max_retries: retryPolicy?.maxRetries ?? 0,
@@ -21700,7 +21702,7 @@
21700
21702
  break;
21701
21703
  }
21702
21704
  const delayMs = retryPolicy?.nextDelayMs(attemptNumber) ?? 0;
21703
- logger$17.warning('handler_execution_failed_will_retry', {
21705
+ logger$18.warning('handler_execution_failed_will_retry', {
21704
21706
  envelope_id: envelope.id,
21705
21707
  attempt: attemptNumber,
21706
21708
  max_retries: retryPolicy?.maxRetries ?? 0,
@@ -21730,7 +21732,7 @@
21730
21732
  }
21731
21733
  }
21732
21734
 
21733
- const logger$16 = getLogger('naylence.fame.delivery.default_delivery_tracker');
21735
+ const logger$17 = getLogger('naylence.fame.delivery.default_delivery_tracker');
21734
21736
  const STREAM_END = Symbol('stream-end');
21735
21737
  const SWEEPER_TICK = Symbol('tracker-sweeper-tick');
21736
21738
  function createDeferred$2() {
@@ -21949,7 +21951,7 @@
21949
21951
  const expectedResponseType = options.expectedResponseType;
21950
21952
  const tracked = await this.lock.runExclusive(async () => {
21951
21953
  if (this.ackFutures.has(envelope.id)) {
21952
- logger$16.debug('tracker_envelope_already_tracked', {
21954
+ logger$17.debug('tracker_envelope_already_tracked', {
21953
21955
  envp_id: envelope.id,
21954
21956
  });
21955
21957
  return null;
@@ -21959,7 +21961,7 @@
21959
21961
  if (expectedResponseType & FameResponseType.REPLY ||
21960
21962
  expectedResponseType & FameResponseType.STREAM) {
21961
21963
  if (existingEnvId && existingEnvId !== envelope.id) {
21962
- logger$16.debug('envelope_already_tracked_for_replies', {
21964
+ logger$17.debug('envelope_already_tracked_for_replies', {
21963
21965
  envp_id: envelope.id,
21964
21966
  corr_id: corrId,
21965
21967
  expected_response_type: expectedResponseType,
@@ -22008,7 +22010,7 @@
22008
22010
  return null;
22009
22011
  }
22010
22012
  await this.scheduleTimer(tracked, options.retryPolicy ?? null, options.retryHandler ?? null);
22011
- logger$16.debug('tracker_registered_envelope', {
22013
+ logger$17.debug('tracker_registered_envelope', {
22012
22014
  envp_id: envelope.id,
22013
22015
  corr_id: tracked.originalEnvelope.corrId,
22014
22016
  expected_response: tracked.expectedResponseType,
@@ -22032,21 +22034,21 @@
22032
22034
  return this.awaitEnvelopeFuture(envelopeId, FameResponseType.REPLY | FameResponseType.STREAM, future, timeoutMs);
22033
22035
  }
22034
22036
  async onEnvelopeDelivered(inboxName, envelope, context) {
22035
- logger$16.debug('envelope_delivered', {
22037
+ logger$17.debug('envelope_delivered', {
22036
22038
  envp_id: envelope.id,
22037
22039
  corr_id: envelope.corrId,
22038
22040
  rtype: envelope.rtype ?? FameResponseType.NONE,
22039
22041
  frame_type: envelope.frame?.type ?? 'unknown',
22040
22042
  });
22041
22043
  if (!envelope.corrId) {
22042
- logger$16.debug('envelope_delivered_no_corr_id', {
22044
+ logger$17.debug('envelope_delivered_no_corr_id', {
22043
22045
  envelope_id: envelope.id,
22044
22046
  });
22045
22047
  return null;
22046
22048
  }
22047
22049
  if (this.isDeliveryAckFrame(envelope.frame)) {
22048
22050
  if (!envelope.frame.refId) {
22049
- logger$16.debug('envelope_delivered_no_ref_id', {
22051
+ logger$17.debug('envelope_delivered_no_ref_id', {
22050
22052
  envelope_id: envelope.id,
22051
22053
  });
22052
22054
  return null;
@@ -22083,7 +22085,7 @@
22083
22085
  await inbox.set(envelope.id, tracked);
22084
22086
  }
22085
22087
  else {
22086
- logger$16.debug('tracker_duplicate_envelope_already_handled', {
22088
+ logger$17.debug('tracker_duplicate_envelope_already_handled', {
22087
22089
  envp_id: envelope.id,
22088
22090
  status: tracked.status,
22089
22091
  });
@@ -22125,7 +22127,7 @@
22125
22127
  }
22126
22128
  if (isFinalFailure) {
22127
22129
  envelope.status = EnvelopeStatus.FAILED_TO_HANDLE;
22128
- logger$16.error('envelope_handle_failed_final', {
22130
+ logger$17.error('envelope_handle_failed_final', {
22129
22131
  inbox_name: inboxName,
22130
22132
  envp_id: envelope.originalEnvelope.id,
22131
22133
  error: error?.message ?? 'unknown',
@@ -22136,7 +22138,7 @@
22136
22138
  await inbox.delete(envelope.originalEnvelope.id);
22137
22139
  return;
22138
22140
  }
22139
- logger$16.warning('envelope_handle_failed_retry', {
22141
+ logger$17.warning('envelope_handle_failed_retry', {
22140
22142
  inbox_name: inboxName,
22141
22143
  envp_id: envelope.originalEnvelope.id,
22142
22144
  error: error?.message ?? 'unknown',
@@ -22181,14 +22183,14 @@
22181
22183
  if (handledViaFuture) {
22182
22184
  await this.markDoneSince(this.ackFutures, refId, this.ackDoneSince);
22183
22185
  await this.clearTimer(refId);
22184
- logger$16.debug('tracker_ack_resolved_without_tracked_envelope', {
22186
+ logger$17.debug('tracker_ack_resolved_without_tracked_envelope', {
22185
22187
  envp_id: envelope.id,
22186
22188
  ref_id: refId,
22187
22189
  corr_id: envelope.corrId,
22188
22190
  });
22189
22191
  return;
22190
22192
  }
22191
- logger$16.debug('tracker_ack_for_unknown_envelope', {
22193
+ logger$17.debug('tracker_ack_for_unknown_envelope', {
22192
22194
  envp_id: envelope.id,
22193
22195
  ref_id: refId,
22194
22196
  corr_id: envelope.corrId,
@@ -22196,7 +22198,7 @@
22196
22198
  return;
22197
22199
  }
22198
22200
  if (tracked.originalEnvelope.corrId !== envelope.corrId) {
22199
- logger$16.debug('tracker_ack_corr_id_mismatch', {
22201
+ logger$17.debug('tracker_ack_corr_id_mismatch', {
22200
22202
  envp_id: envelope.id,
22201
22203
  expected_corr_id: tracked.originalEnvelope.corrId,
22202
22204
  actual_corr_id: envelope.corrId,
@@ -22221,7 +22223,7 @@
22221
22223
  for (const handler of this.eventHandlers) {
22222
22224
  await handler.onEnvelopeAcked?.(tracked);
22223
22225
  }
22224
- logger$16.debug('tracker_envelope_acked', {
22226
+ logger$17.debug('tracker_envelope_acked', {
22225
22227
  envp_id: tracked.originalEnvelope.id,
22226
22228
  });
22227
22229
  }
@@ -22238,13 +22240,13 @@
22238
22240
  const outbox = this.ensureOutbox();
22239
22241
  const tracked = await outbox.get(envelope.frame.refId);
22240
22242
  if (!tracked) {
22241
- logger$16.debug('tracker_nack_for_unknown_envelope', {
22243
+ logger$17.debug('tracker_nack_for_unknown_envelope', {
22242
22244
  envp_id: envelope.id,
22243
22245
  });
22244
22246
  return;
22245
22247
  }
22246
22248
  if (tracked.originalEnvelope.corrId !== envelope.corrId) {
22247
- logger$16.debug('tracker_nack_corr_id_mismatch', {
22249
+ logger$17.debug('tracker_nack_corr_id_mismatch', {
22248
22250
  envp_id: envelope.id,
22249
22251
  expected_corr_id: tracked.originalEnvelope.corrId,
22250
22252
  actual_corr_id: envelope.corrId,
@@ -22286,7 +22288,7 @@
22286
22288
  for (const handler of this.eventHandlers) {
22287
22289
  await handler.onEnvelopeNacked?.(tracked, ackFrame.reason ?? null);
22288
22290
  }
22289
- logger$16.debug('tracker_envelope_nacked', {
22291
+ logger$17.debug('tracker_envelope_nacked', {
22290
22292
  envp_id: tracked.originalEnvelope.id,
22291
22293
  reason: ackFrame.reason,
22292
22294
  });
@@ -22333,7 +22335,7 @@
22333
22335
  for (const handler of this.eventHandlers) {
22334
22336
  await handler.onEnvelopeReplied?.(trackedEnvelope, envelope);
22335
22337
  }
22336
- logger$16.debug('tracked_envelope_replied', {
22338
+ logger$17.debug('tracked_envelope_replied', {
22337
22339
  envp_id: trackedEnvelope.originalEnvelope.id,
22338
22340
  corr_id: envelope.corrId,
22339
22341
  });
@@ -22407,7 +22409,7 @@
22407
22409
  async addToInboxDlq(trackedEnvelope, reason = null) {
22408
22410
  const dlq = this.inboxDlq;
22409
22411
  if (!dlq) {
22410
- logger$16.error('dlq_not_initialized', {
22412
+ logger$17.error('dlq_not_initialized', {
22411
22413
  envp_id: trackedEnvelope.originalEnvelope.id,
22412
22414
  });
22413
22415
  return;
@@ -22422,7 +22424,7 @@
22422
22424
  const deadLetteredAt = Date.now();
22423
22425
  setMetaWithLegacy(trackedEnvelope.meta, 'deadLetteredAtMs', 'dead_lettered_at_ms', deadLetteredAt);
22424
22426
  await dlq.set(trackedEnvelope.originalEnvelope.id, trackedEnvelope);
22425
- logger$16.warning('envelope_moved_to_dlq', {
22427
+ logger$17.warning('envelope_moved_to_dlq', {
22426
22428
  envp_id: trackedEnvelope.originalEnvelope.id,
22427
22429
  service_name: trackedEnvelope.serviceName,
22428
22430
  });
@@ -22451,7 +22453,7 @@
22451
22453
  const toDelete = Object.entries(items).filter(([, value]) => predicate ? predicate(value) : true);
22452
22454
  await Promise.all(toDelete.map(([key]) => dlq.delete(key)));
22453
22455
  if (toDelete.length) {
22454
- logger$16.debug('dlq_purged', { count: toDelete.length });
22456
+ logger$17.debug('dlq_purged', { count: toDelete.length });
22455
22457
  }
22456
22458
  return toDelete.length;
22457
22459
  }
@@ -22504,11 +22506,11 @@
22504
22506
  }
22505
22507
  this.futuresSweeper = null;
22506
22508
  }
22507
- logger$16.debug('tracker_cleanup_completed');
22509
+ logger$17.debug('tracker_cleanup_completed');
22508
22510
  }
22509
22511
  async recoverPending() {
22510
22512
  const pending = await this.listPending();
22511
- logger$16.debug('tracker_recovering_pending', { count: pending.length });
22513
+ logger$17.debug('tracker_recovering_pending', { count: pending.length });
22512
22514
  await this.lock.runExclusive(async () => {
22513
22515
  for (const tracked of pending) {
22514
22516
  if (tracked.expectedResponseType & FameResponseType.ACK) {
@@ -22534,7 +22536,7 @@
22534
22536
  for (const tracked of pending) {
22535
22537
  await this.scheduleTimer(tracked, null, null);
22536
22538
  }
22537
- logger$16.debug('tracker_recovery_completed', { count: pending.length });
22539
+ logger$17.debug('tracker_recovery_completed', { count: pending.length });
22538
22540
  }
22539
22541
  ensureOutbox() {
22540
22542
  if (!this.outbox) {
@@ -22549,7 +22551,7 @@
22549
22551
  return this.inbox;
22550
22552
  }
22551
22553
  async waitForPendingAcks() {
22552
- logger$16.debug('tracker_node_preparing_to_stop_waiting_for_pending_acks');
22554
+ logger$17.debug('tracker_node_preparing_to_stop_waiting_for_pending_acks');
22553
22555
  const outbox = this.outbox;
22554
22556
  if (!outbox) {
22555
22557
  return;
@@ -22561,7 +22563,7 @@
22561
22563
  continue;
22562
22564
  }
22563
22565
  if (!future.done) {
22564
- logger$16.debug('tracker_pending_ack_future_detected', {
22566
+ logger$17.debug('tracker_pending_ack_future_detected', {
22565
22567
  envelope_id: envelopeId,
22566
22568
  });
22567
22569
  pending.push({ envelopeId, future });
@@ -22569,10 +22571,10 @@
22569
22571
  }
22570
22572
  });
22571
22573
  if (!pending.length) {
22572
- logger$16.debug('tracker_no_pending_acks_to_wait_for');
22574
+ logger$17.debug('tracker_no_pending_acks_to_wait_for');
22573
22575
  return;
22574
22576
  }
22575
- logger$16.debug('tracker_waiting_for_pending_acks', { count: pending.length });
22577
+ logger$17.debug('tracker_waiting_for_pending_acks', { count: pending.length });
22576
22578
  for (const entry of pending) {
22577
22579
  if (!entry) {
22578
22580
  continue;
@@ -22589,19 +22591,19 @@
22589
22591
  }
22590
22592
  try {
22591
22593
  await this.awaitWithTimeout(entry.future.promise, remainingMs);
22592
- logger$16.debug('tracker_received_ack', {
22594
+ logger$17.debug('tracker_received_ack', {
22593
22595
  envelope_id: entry.envelopeId,
22594
22596
  });
22595
22597
  await outbox.delete(entry.envelopeId);
22596
22598
  }
22597
22599
  catch (error) {
22598
22600
  if (error instanceof Error && error.name === 'TimeoutError') {
22599
- logger$16.debug('tracker_ack_timeout_expired', {
22601
+ logger$17.debug('tracker_ack_timeout_expired', {
22600
22602
  envelope_id: entry.envelopeId,
22601
22603
  });
22602
22604
  }
22603
22605
  else {
22604
- logger$16.debug('tracker_ack_wait_error', {
22606
+ logger$17.debug('tracker_ack_wait_error', {
22605
22607
  envelope_id: entry.envelopeId,
22606
22608
  error: error instanceof Error ? error.message : String(error),
22607
22609
  });
@@ -22609,13 +22611,13 @@
22609
22611
  }
22610
22612
  }
22611
22613
  catch (error) {
22612
- logger$16.error('tracker_error_waiting_for_ack', {
22614
+ logger$17.error('tracker_error_waiting_for_ack', {
22613
22615
  envelope_id: entry.envelopeId,
22614
22616
  error: error instanceof Error ? error.message : String(error),
22615
22617
  });
22616
22618
  }
22617
22619
  }
22618
- logger$16.debug('tracker_finished_waiting_for_pending_acks');
22620
+ logger$17.debug('tracker_finished_waiting_for_pending_acks');
22619
22621
  }
22620
22622
  async waitForPendingAckDispatches() {
22621
22623
  while (this.pendingAckDispatches.size > 0) {
@@ -22673,7 +22675,7 @@
22673
22675
  for (const handler of this.eventHandlers) {
22674
22676
  await handler.onEnvelopeTimeout?.(currentTracked);
22675
22677
  }
22676
- logger$16.debug('tracker_envelope_timed_out', {
22678
+ logger$17.debug('tracker_envelope_timed_out', {
22677
22679
  envp_id: tracked.originalEnvelope.id,
22678
22680
  });
22679
22681
  return;
@@ -22686,7 +22688,7 @@
22686
22688
  currentTracked.timeoutAtMs = nextTimeoutAt;
22687
22689
  await outbox.set(tracked.originalEnvelope.id, currentTracked);
22688
22690
  await this.scheduleTimer(currentTracked, retryPolicy, retryHandler);
22689
- logger$16.debug('tracker_retry_deferred_during_shutdown', {
22691
+ logger$17.debug('tracker_retry_deferred_during_shutdown', {
22690
22692
  envp_id: tracked.originalEnvelope.id,
22691
22693
  defer_ms: shutdownDeferMs,
22692
22694
  });
@@ -22709,7 +22711,7 @@
22709
22711
  });
22710
22712
  }
22711
22713
  await this.scheduleTimer(currentTracked, retryPolicy, retryHandler);
22712
- logger$16.debug('envelope_delivery_retry_scheduled', {
22714
+ logger$17.debug('envelope_delivery_retry_scheduled', {
22713
22715
  envp_id: tracked.originalEnvelope.id,
22714
22716
  attempt: currentTracked.attempt,
22715
22717
  max_retries: retryPolicy.maxRetries,
@@ -22721,7 +22723,7 @@
22721
22723
  currentTracked.timeoutAtMs = currentTracked.overallTimeoutAtMs;
22722
22724
  await outbox.set(tracked.originalEnvelope.id, currentTracked);
22723
22725
  await this.scheduleTimer(currentTracked, retryPolicy, retryHandler);
22724
- logger$16.debug('envelope_retries_exhausted_waiting_until_overall_timeout', {
22726
+ logger$17.debug('envelope_retries_exhausted_waiting_until_overall_timeout', {
22725
22727
  envp_id: tracked.originalEnvelope.id,
22726
22728
  attempt: currentTracked.attempt,
22727
22729
  overall_timeout_at_ms: currentTracked.overallTimeoutAtMs,
@@ -22741,7 +22743,7 @@
22741
22743
  for (const handler of this.eventHandlers) {
22742
22744
  await handler.onEnvelopeTimeout?.(currentTracked);
22743
22745
  }
22744
- logger$16.debug('tracker_envelope_timed_out', {
22746
+ logger$17.debug('tracker_envelope_timed_out', {
22745
22747
  envp_id: tracked.originalEnvelope.id,
22746
22748
  });
22747
22749
  }
@@ -22749,7 +22751,7 @@
22749
22751
  if (error instanceof TaskCancelledError) {
22750
22752
  return;
22751
22753
  }
22752
- logger$16.error('tracker_timer_error', {
22754
+ logger$17.error('tracker_timer_error', {
22753
22755
  envp_id: tracked.originalEnvelope.id,
22754
22756
  error: error instanceof Error ? error.message : String(error),
22755
22757
  });
@@ -22804,7 +22806,7 @@
22804
22806
  if (timeoutSeconds !== null) {
22805
22807
  return await this.awaitWithTimeout(future.promise, timeoutSeconds);
22806
22808
  }
22807
- logger$16.debug('await_envelope_no_timeout_wait', {
22809
+ logger$17.debug('await_envelope_no_timeout_wait', {
22808
22810
  envelope_id: envelopeId,
22809
22811
  });
22810
22812
  return await future.promise;
@@ -22813,7 +22815,7 @@
22813
22815
  if (error instanceof Error && error.name !== 'TimeoutError') {
22814
22816
  throw error;
22815
22817
  }
22816
- logger$16.error('await_envelope_timeout_error', {
22818
+ logger$17.error('await_envelope_timeout_error', {
22817
22819
  envelope_id: envelopeId,
22818
22820
  timeout_ms: timeoutSeconds,
22819
22821
  future_done: false,
@@ -22974,7 +22976,7 @@
22974
22976
  this.replyDoneSince.delete(envId);
22975
22977
  }
22976
22978
  });
22977
- logger$16.debug('tracker_swept_completed_futures', {
22979
+ logger$17.debug('tracker_swept_completed_futures', {
22978
22980
  ack_removed: toRemoveAck.length,
22979
22981
  reply_removed: toRemoveReply.length,
22980
22982
  grace_secs: this.futGcGraceSecs,
@@ -22988,7 +22990,7 @@
22988
22990
  if (error instanceof Error && error.name === 'TimeoutError') {
22989
22991
  continue;
22990
22992
  }
22991
- logger$16.error('tracker_sweeper_error', {
22993
+ logger$17.error('tracker_sweeper_error', {
22992
22994
  error: error instanceof Error ? error.message : String(error),
22993
22995
  });
22994
22996
  }
@@ -23019,14 +23021,14 @@
23019
23021
  }
23020
23022
  const node = this.node;
23021
23023
  if (!envelope.replyTo) {
23022
- logger$16.error('cannot_send_ack_no_reply_to', { envp_id: envelope.id });
23024
+ logger$17.error('cannot_send_ack_no_reply_to', { envp_id: envelope.id });
23023
23025
  return;
23024
23026
  }
23025
23027
  if (!envelope.corrId) {
23026
- logger$16.error('cannot_send_ack_no_corr_id', { envp_id: envelope.id });
23028
+ logger$17.error('cannot_send_ack_no_corr_id', { envp_id: envelope.id });
23027
23029
  return;
23028
23030
  }
23029
- logger$16.debug('tracker_sending_ack', {
23031
+ logger$17.debug('tracker_sending_ack', {
23030
23032
  envp_id: envelope.id,
23031
23033
  ref_id: envelope.id,
23032
23034
  to: envelope.replyTo,
@@ -23046,7 +23048,7 @@
23046
23048
  .send(ackEnvelope)
23047
23049
  .then(() => undefined)
23048
23050
  .catch((error) => {
23049
- logger$16.error('tracker_ack_dispatch_failed', {
23051
+ logger$17.error('tracker_ack_dispatch_failed', {
23050
23052
  envp_id: envelope.id,
23051
23053
  error: error instanceof Error ? error.message : String(error),
23052
23054
  });
@@ -23132,7 +23134,7 @@
23132
23134
  }
23133
23135
  }
23134
23136
 
23135
- const logger$15 = getLogger('naylence.fame.node.root_session_manager');
23137
+ const logger$16 = getLogger('naylence.fame.node.root_session_manager');
23136
23138
  function resolveOption$1(options, primary, ...aliases) {
23137
23139
  const record = options;
23138
23140
  const primaryKey = primary;
@@ -23213,7 +23215,7 @@
23213
23215
  this.onAdmissionFailed =
23214
23216
  typeof onAdmissionFailed === 'function' ? onAdmissionFailed : undefined;
23215
23217
  this.enableContinuousRefresh = enableContinuousRefresh ?? true;
23216
- logger$15.debug('created_root_session_manager');
23218
+ logger$16.debug('created_root_session_manager');
23217
23219
  }
23218
23220
  get isReady() {
23219
23221
  return this.readyEvent.isSet();
@@ -23238,7 +23240,7 @@
23238
23240
  if (this.admissionTask) {
23239
23241
  return;
23240
23242
  }
23241
- logger$15.debug('root_session_manager_starting');
23243
+ logger$16.debug('root_session_manager_starting');
23242
23244
  this.stopEvent.clear();
23243
23245
  this.readyEvent.clear();
23244
23246
  const taskName = `root-admission-${this.admissionEpoch}`;
@@ -23258,10 +23260,10 @@
23258
23260
  await this.admissionTask.promise;
23259
23261
  throw new FameConnectError('Root session manager failed to become ready');
23260
23262
  }
23261
- logger$15.debug('root_session_manager_started');
23263
+ logger$16.debug('root_session_manager_started');
23262
23264
  }
23263
23265
  async stop() {
23264
- logger$15.debug('root_session_manager_stopping');
23266
+ logger$16.debug('root_session_manager_stopping');
23265
23267
  this.stopEvent.set();
23266
23268
  if (this.admissionTask) {
23267
23269
  this.admissionTask.cancel();
@@ -23273,7 +23275,7 @@
23273
23275
  await this.consumeTask(this.expiryGuardTask);
23274
23276
  this.expiryGuardTask = null;
23275
23277
  }
23276
- logger$15.debug('root_session_manager_stopped');
23278
+ logger$16.debug('root_session_manager_stopped');
23277
23279
  }
23278
23280
  async awaitReady(timeoutMs) {
23279
23281
  if (this.isReady) {
@@ -23314,12 +23316,12 @@
23314
23316
  await this.onEpochChange(epoch);
23315
23317
  }
23316
23318
  else {
23317
- logger$15.debug('epoch_change_ignored_no_handler', { epoch });
23319
+ logger$16.debug('epoch_change_ignored_no_handler', { epoch });
23318
23320
  }
23319
23321
  }
23320
23322
  static createForRootSentinel(node, admissionClient, requestedLogicals = [], enableContinuousRefresh = true, onEpochChange) {
23321
23323
  const handleWelcome = async (frame) => {
23322
- logger$15.info('root_admission_successful', {
23324
+ logger$16.info('root_admission_successful', {
23323
23325
  system_id: frame.systemId,
23324
23326
  assigned_path: frame.assignedPath ?? null,
23325
23327
  accepted_logicals: frame.acceptedLogicals ?? [],
@@ -23330,12 +23332,12 @@
23330
23332
  ? grant.purpose
23331
23333
  : undefined;
23332
23334
  if (purpose) {
23333
- logger$15.debug('received_admission_grant', { purpose });
23335
+ logger$16.debug('received_admission_grant', { purpose });
23334
23336
  }
23335
23337
  }
23336
23338
  };
23337
23339
  const handleFailure = async (error) => {
23338
- logger$15.error('root_admission_failed_permanently', {
23340
+ logger$16.error('root_admission_failed_permanently', {
23339
23341
  error: error.message,
23340
23342
  });
23341
23343
  };
@@ -23364,10 +23366,10 @@
23364
23366
  this.readyEvent.set();
23365
23367
  }
23366
23368
  if (this.hadSuccessfulAdmission) {
23367
- logger$15.debug('root_admission_refreshed');
23369
+ logger$16.debug('root_admission_refreshed');
23368
23370
  }
23369
23371
  else {
23370
- logger$15.debug('root_admission_completed');
23372
+ logger$16.debug('root_admission_completed');
23371
23373
  }
23372
23374
  this.hadSuccessfulAdmission = true;
23373
23375
  delay = RootSessionManager.BACKOFF_INITIAL;
@@ -23376,7 +23378,7 @@
23376
23378
  await this.startExpiryGuard(welcomeFrame);
23377
23379
  const expiryTriggered = await this.waitForExpiryOrStop();
23378
23380
  if (expiryTriggered && !this.stopEvent.isSet()) {
23379
- logger$15.debug('performing_scheduled_re_admission');
23381
+ logger$16.debug('performing_scheduled_re_admission');
23380
23382
  continue;
23381
23383
  }
23382
23384
  }
@@ -23388,7 +23390,7 @@
23388
23390
  }
23389
23391
  const errorObject = error instanceof Error ? error : new Error(String(error));
23390
23392
  const willRetry = attempts < RootSessionManager.RETRY_MAX_ATTEMPTS;
23391
- logger$15.warning('root_admission_failed', {
23393
+ logger$16.warning('root_admission_failed', {
23392
23394
  error: errorObject.message,
23393
23395
  attempt: attempts,
23394
23396
  will_retry: willRetry,
@@ -23406,7 +23408,7 @@
23406
23408
  }
23407
23409
  }
23408
23410
  if (attempts >= RootSessionManager.RETRY_MAX_ATTEMPTS) {
23409
- logger$15.error('root_admission_max_attempts_exceeded', {
23411
+ logger$16.error('root_admission_max_attempts_exceeded', {
23410
23412
  max_attempts: RootSessionManager.RETRY_MAX_ATTEMPTS,
23411
23413
  });
23412
23414
  }
@@ -23483,7 +23485,7 @@
23483
23485
  }
23484
23486
  async expiryGuard(welcomeFrame, signal) {
23485
23487
  if (!welcomeFrame.expiresAt) {
23486
- logger$15.debug('no_admission_expiry_configured');
23488
+ logger$16.debug('no_admission_expiry_configured');
23487
23489
  await Promise.race([this.stopEvent.wait(), this.waitForAbort(signal)]);
23488
23490
  return;
23489
23491
  }
@@ -23492,7 +23494,7 @@
23492
23494
  let delaySeconds = (expiresAt.getTime() - now.getTime()) / 1000 -
23493
23495
  RootSessionManager.JWT_REFRESH_SAFETY;
23494
23496
  delaySeconds = Math.max(delaySeconds, 0);
23495
- logger$15.debug('admission_expiry_guard_started', {
23497
+ logger$16.debug('admission_expiry_guard_started', {
23496
23498
  welcome_expires_at: expiresAt.toISOString(),
23497
23499
  delay_seconds: delaySeconds,
23498
23500
  refresh_safety_seconds: RootSessionManager.JWT_REFRESH_SAFETY,
@@ -23501,7 +23503,7 @@
23501
23503
  if (this.stopEvent.isSet() || signal?.aborted) {
23502
23504
  return;
23503
23505
  }
23504
- logger$15.debug('admission_expiry_triggered_refresh', {
23506
+ logger$16.debug('admission_expiry_triggered_refresh', {
23505
23507
  expires_at: expiresAt.toISOString(),
23506
23508
  current_time: new Date().toISOString(),
23507
23509
  seconds_before_expiry: RootSessionManager.JWT_REFRESH_SAFETY,
@@ -23516,7 +23518,7 @@
23516
23518
  return;
23517
23519
  }
23518
23520
  const errorObject = error instanceof Error ? error : new Error(String(error));
23519
- logger$15.debug('background_task_error', {
23521
+ logger$16.debug('background_task_error', {
23520
23522
  task_name: task.name,
23521
23523
  error: errorObject.message,
23522
23524
  });
@@ -23557,7 +23559,7 @@
23557
23559
  * Concrete implementations must define supported grant types and provide grant-to-connector
23558
23560
  * conversion logic.
23559
23561
  */
23560
- const logger$14 = getLogger('naylence.fame.connector.connector_factory');
23562
+ const logger$15 = getLogger('naylence.fame.connector.connector_factory');
23561
23563
  const CONNECTOR_FACTORY_BASE_TYPE = 'ConnectorFactory';
23562
23564
  /**
23563
23565
  * Abstract base class for connector factories
@@ -23593,7 +23595,7 @@
23593
23595
  }
23594
23596
  }
23595
23597
  catch (error) {
23596
- logger$14.warning(`Failed to evaluate grant with factory ${factoryInfo.constructor.name}: ${error}`);
23598
+ logger$15.warning(`Failed to evaluate grant with factory ${factoryInfo.constructor.name}: ${error}`);
23597
23599
  continue;
23598
23600
  }
23599
23601
  }
@@ -23636,7 +23638,7 @@
23636
23638
  }
23637
23639
  }
23638
23640
  catch (error) {
23639
- logger$14.warning(`Failed to create connector config from grant: ${error}`);
23641
+ logger$15.warning(`Failed to create connector config from grant: ${error}`);
23640
23642
  continue;
23641
23643
  }
23642
23644
  }
@@ -23703,20 +23705,20 @@
23703
23705
  return existing;
23704
23706
  }
23705
23707
  if (existing && !this.isGrantAware(existing)) {
23706
- logger$14.warning(`Factory ${factoryInfo.constructor.name} is registered under ${CONNECTOR_FACTORY_BASE_TYPE} but is missing grant conversion APIs; skipping.`);
23708
+ logger$15.warning(`Factory ${factoryInfo.constructor.name} is registered under ${CONNECTOR_FACTORY_BASE_TYPE} but is missing grant conversion APIs; skipping.`);
23707
23709
  return null;
23708
23710
  }
23709
23711
  try {
23710
23712
  const instance = new factoryInfo.constructor();
23711
23713
  if (!this.isGrantAware(instance)) {
23712
- logger$14.warning(`Factory ${factoryInfo.constructor.name} does not implement grant conversion APIs required by ${CONNECTOR_FACTORY_BASE_TYPE}; skipping.`);
23714
+ logger$15.warning(`Factory ${factoryInfo.constructor.name} does not implement grant conversion APIs required by ${CONNECTOR_FACTORY_BASE_TYPE}; skipping.`);
23713
23715
  return null;
23714
23716
  }
23715
23717
  factoryInfo.instance = instance;
23716
23718
  return instance;
23717
23719
  }
23718
23720
  catch (error) {
23719
- logger$14.warning(`Failed to instantiate factory ${factoryInfo.constructor.name} while resolving grant conversion APIs: ${error}`);
23721
+ logger$15.warning(`Failed to instantiate factory ${factoryInfo.constructor.name} while resolving grant conversion APIs: ${error}`);
23720
23722
  return null;
23721
23723
  }
23722
23724
  }
@@ -23819,7 +23821,7 @@
23819
23821
  this.name = 'TaskCancellationError';
23820
23822
  }
23821
23823
  }
23822
- const logger$13 = getLogger('naylence.fame.connector.base_async_connector');
23824
+ const logger$14 = getLogger('naylence.fame.connector.base_async_connector');
23823
23825
  // Environment variables
23824
23826
  const ENV_VAR_FAME_FLOW_CONTROL = 'FAME_FLOW_CONTROL';
23825
23827
  const FLOW_CONTROL_ENABLED = typeof process !== 'undefined' && process?.env
@@ -23902,7 +23904,7 @@
23902
23904
  if (this._state !== newState) {
23903
23905
  const oldState = this._state;
23904
23906
  this._state = newState;
23905
- logger$13.debug('connector_state_transition', {
23907
+ logger$14.debug('connector_state_transition', {
23906
23908
  connector_id: this._connectorFlowId,
23907
23909
  old_state: oldState,
23908
23910
  new_state: newState,
@@ -23941,12 +23943,12 @@
23941
23943
  * Stop the connector gracefully
23942
23944
  */
23943
23945
  async stop() {
23944
- logger$13.debug('stopping_connector', {
23946
+ logger$14.debug('stopping_connector', {
23945
23947
  current_state: this._state,
23946
23948
  connector_id: this._connectorFlowId,
23947
23949
  });
23948
23950
  if (!ConnectorStateUtils.canStop(this._state)) {
23949
- logger$13.debug('connector_stop_already_stopped', {
23951
+ logger$14.debug('connector_stop_already_stopped', {
23950
23952
  current_state: this._state,
23951
23953
  connector_id: this._connectorFlowId,
23952
23954
  });
@@ -23957,7 +23959,7 @@
23957
23959
  if (this._lastError) {
23958
23960
  throw this._lastError;
23959
23961
  }
23960
- logger$13.debug('connector_stopped', {
23962
+ logger$14.debug('connector_stopped', {
23961
23963
  current_state: this._state,
23962
23964
  connector_id: this._connectorFlowId,
23963
23965
  });
@@ -23966,19 +23968,19 @@
23966
23968
  * Pause the connector (suspends heartbeat and housekeeping, but keeps connection alive)
23967
23969
  */
23968
23970
  async pause() {
23969
- logger$13.debug('pausing_connector', {
23971
+ logger$14.debug('pausing_connector', {
23970
23972
  current_state: this._state,
23971
23973
  connector_id: this._connectorFlowId,
23972
23974
  });
23973
23975
  if (this._state !== ConnectorState.STARTED) {
23974
- logger$13.debug('connector_pause_invalid_state', {
23976
+ logger$14.debug('connector_pause_invalid_state', {
23975
23977
  current_state: this._state,
23976
23978
  connector_id: this._connectorFlowId,
23977
23979
  });
23978
23980
  return;
23979
23981
  }
23980
23982
  this._setState(ConnectorState.PAUSED);
23981
- logger$13.debug('connector_paused', {
23983
+ logger$14.debug('connector_paused', {
23982
23984
  current_state: this._state,
23983
23985
  connector_id: this._connectorFlowId,
23984
23986
  });
@@ -23987,19 +23989,19 @@
23987
23989
  * Resume the connector from paused state
23988
23990
  */
23989
23991
  async resume() {
23990
- logger$13.debug('resuming_connector', {
23992
+ logger$14.debug('resuming_connector', {
23991
23993
  current_state: this._state,
23992
23994
  connector_id: this._connectorFlowId,
23993
23995
  });
23994
23996
  if (this._state !== ConnectorState.PAUSED) {
23995
- logger$13.debug('connector_resume_invalid_state', {
23997
+ logger$14.debug('connector_resume_invalid_state', {
23996
23998
  current_state: this._state,
23997
23999
  connector_id: this._connectorFlowId,
23998
24000
  });
23999
24001
  return;
24000
24002
  }
24001
24003
  this._setState(ConnectorState.STARTED);
24002
- logger$13.debug('connector_resumed', {
24004
+ logger$14.debug('connector_resumed', {
24003
24005
  current_state: this._state,
24004
24006
  connector_id: this._connectorFlowId,
24005
24007
  });
@@ -24009,7 +24011,7 @@
24009
24011
  */
24010
24012
  async close(code = 1000, reason = 'normal closure') {
24011
24013
  if (!ConnectorStateUtils.canClose(this._state)) {
24012
- logger$13.warning('connector_close_invalid_state', {
24014
+ logger$14.warning('connector_close_invalid_state', {
24013
24015
  current_state: this._state,
24014
24016
  connector_id: this._connectorFlowId,
24015
24017
  });
@@ -24090,7 +24092,7 @@
24090
24092
  // Add to queue and notify send loop
24091
24093
  this._sendQueue.push(raw);
24092
24094
  // Log for debugging
24093
- logger$13.debug('send_envelope_queued', {
24095
+ logger$14.debug('send_envelope_queued', {
24094
24096
  queue_length: this._sendQueue.length,
24095
24097
  max_queue_size: this._maxQueueSize,
24096
24098
  });
@@ -24139,14 +24141,14 @@
24139
24141
  const item = this._sendQueue[0];
24140
24142
  if (!item)
24141
24143
  continue;
24142
- logger$13.debug('send_loop_processing_item', {
24144
+ logger$14.debug('send_loop_processing_item', {
24143
24145
  queue_length_before_send: this._sendQueue.length,
24144
24146
  });
24145
24147
  // Send through transport (this may block)
24146
24148
  await this._transportSendBytes(item);
24147
24149
  // Only remove from queue after successful send
24148
24150
  this._sendQueue.shift();
24149
- logger$13.debug('send_loop_item_sent', {
24151
+ logger$14.debug('send_loop_item_sent', {
24150
24152
  queue_length_after_send: this._sendQueue.length,
24151
24153
  });
24152
24154
  }
@@ -24159,14 +24161,14 @@
24159
24161
  }
24160
24162
  else if (error instanceof TaskCancellationError) {
24161
24163
  // Task cancellation is expected during shutdown - log as debug, not critical
24162
- logger$13.debug('send loop cancelled', {
24164
+ logger$14.debug('send loop cancelled', {
24163
24165
  connector: this.constructor.name,
24164
24166
  reason: error.message,
24165
24167
  });
24166
24168
  // Don't re-throw - this is normal during shutdown
24167
24169
  }
24168
24170
  else {
24169
- logger$13.critical('unexpected exception in send loop', {
24171
+ logger$14.critical('unexpected exception in send loop', {
24170
24172
  connector: this.constructor.name,
24171
24173
  error: error instanceof Error ? error.message : String(error),
24172
24174
  });
@@ -24207,7 +24209,7 @@
24207
24209
  env = JSON.parse(jsonStr);
24208
24210
  }
24209
24211
  catch (error) {
24210
- logger$13.error('Invalid envelope', {
24212
+ logger$14.error('Invalid envelope', {
24211
24213
  message: message.toString(),
24212
24214
  error: error instanceof Error ? error.message : String(error),
24213
24215
  });
@@ -24231,7 +24233,7 @@
24231
24233
  };
24232
24234
  await withEnvelopeContextAsync(envelopeContext, async () => {
24233
24235
  const prettyEnvelope = prettyModel$1(env);
24234
- logger$13.trace('connector_received_envelope', {
24236
+ logger$14.trace('connector_received_envelope', {
24235
24237
  envelope: env,
24236
24238
  pretty: prettyEnvelope,
24237
24239
  });
@@ -24260,7 +24262,7 @@
24260
24262
  if (error instanceof TaskCancellationError) {
24261
24263
  throw error;
24262
24264
  }
24263
- logger$13.error('handler_failed', {
24265
+ logger$14.error('handler_failed', {
24264
24266
  error: error instanceof Error ? error.message : String(error),
24265
24267
  envelope_id: env.id ?? null,
24266
24268
  trace_id: env.traceId ?? null,
@@ -24281,14 +24283,14 @@
24281
24283
  }
24282
24284
  else if (error instanceof TaskCancellationError) {
24283
24285
  // Task cancellation is expected during shutdown - log as debug, not critical
24284
- logger$13.debug('receive loop cancelled', {
24286
+ logger$14.debug('receive loop cancelled', {
24285
24287
  connector: this.constructor.name,
24286
24288
  reason: error.message,
24287
24289
  });
24288
24290
  // Don't re-throw - this is normal during shutdown
24289
24291
  }
24290
24292
  else {
24291
- logger$13.critical('unexpected_error_in recv_loop', {
24293
+ logger$14.critical('unexpected_error_in recv_loop', {
24292
24294
  error: error instanceof Error ? error.message : String(error),
24293
24295
  });
24294
24296
  throw error;
@@ -24304,7 +24306,7 @@
24304
24306
  async _maybeEmitCredit(flowId, traceId) {
24305
24307
  const remainingCredits = this._flowCtrl.getCredits(flowId);
24306
24308
  const needsRefill = this._flowCtrl.needsRefill(flowId);
24307
- logger$13.debug('maybe_emit_credit_check', {
24309
+ logger$14.debug('maybe_emit_credit_check', {
24308
24310
  connector_id: this._connectorFlowId,
24309
24311
  flow_id: flowId,
24310
24312
  trace_id: traceId ?? null,
@@ -24320,7 +24322,7 @@
24320
24322
  }
24321
24323
  const delta = this._initialWindow;
24322
24324
  this._flowCtrl.addCredits(flowId, delta);
24323
- logger$13.debug('maybe_emit_credit_emit', {
24325
+ logger$14.debug('maybe_emit_credit_emit', {
24324
24326
  connector_id: this._connectorFlowId,
24325
24327
  flow_id: flowId,
24326
24328
  trace_id: traceId ?? null,
@@ -24340,7 +24342,7 @@
24340
24342
  });
24341
24343
  try {
24342
24344
  await this.send(ackEnv);
24343
- logger$13.debug('maybe_emit_credit_sent', {
24345
+ logger$14.debug('maybe_emit_credit_sent', {
24344
24346
  connector_id: this._connectorFlowId,
24345
24347
  flow_id: flowId,
24346
24348
  trace_id: traceId ?? null,
@@ -24348,7 +24350,7 @@
24348
24350
  });
24349
24351
  }
24350
24352
  catch (error) {
24351
- logger$13.error('maybe_emit_credit_send_failed', {
24353
+ logger$14.error('maybe_emit_credit_send_failed', {
24352
24354
  connector_id: this._connectorFlowId,
24353
24355
  flow_id: flowId,
24354
24356
  trace_id: traceId ?? null,
@@ -24373,13 +24375,13 @@
24373
24375
  */
24374
24376
  async _shutdown(code, reason, gracePeriod, exc) {
24375
24377
  if (this._closed) {
24376
- logger$13.debug('shutdown_already_closed', {
24378
+ logger$14.debug('shutdown_already_closed', {
24377
24379
  connector_id: this._connectorFlowId,
24378
24380
  current_state: this._state,
24379
24381
  });
24380
24382
  return;
24381
24383
  }
24382
- logger$13.debug('connector_shutdown_starting', {
24384
+ logger$14.debug('connector_shutdown_starting', {
24383
24385
  connector_id: this._connectorFlowId,
24384
24386
  connector_type: this.constructor.name,
24385
24387
  code,
@@ -24409,19 +24411,19 @@
24409
24411
  this._sendPromiseResolve = undefined;
24410
24412
  }
24411
24413
  // Close transport
24412
- logger$13.debug('connector_closing_transport', {
24414
+ logger$14.debug('connector_closing_transport', {
24413
24415
  connector_id: this._connectorFlowId,
24414
24416
  connector_type: this.constructor.name,
24415
24417
  timestamp: new Date().toISOString(),
24416
24418
  });
24417
24419
  await this._transportClose(code, reason);
24418
- logger$13.debug('connector_transport_closed', {
24420
+ logger$14.debug('connector_transport_closed', {
24419
24421
  connector_id: this._connectorFlowId,
24420
24422
  connector_type: this.constructor.name,
24421
24423
  timestamp: new Date().toISOString(),
24422
24424
  });
24423
24425
  // Shutdown spawned tasks
24424
- logger$13.debug('connector_shutting_down_tasks', {
24426
+ logger$14.debug('connector_shutting_down_tasks', {
24425
24427
  connector_id: this._connectorFlowId,
24426
24428
  connector_type: this.constructor.name,
24427
24429
  grace_period_ms: effectiveGracePeriod * 1000,
@@ -24433,14 +24435,14 @@
24433
24435
  gracePeriod: effectiveGracePeriod * 1000, // Convert to milliseconds
24434
24436
  joinTimeout: this._shutdownJoinTimeout,
24435
24437
  });
24436
- logger$13.debug('connector_tasks_shutdown_complete', {
24438
+ logger$14.debug('connector_tasks_shutdown_complete', {
24437
24439
  connector_id: this._connectorFlowId,
24438
24440
  connector_type: this.constructor.name,
24439
24441
  timestamp: new Date().toISOString(),
24440
24442
  });
24441
24443
  }
24442
24444
  catch (error) {
24443
- logger$13.warning('task_shutdown_error', {
24445
+ logger$14.warning('task_shutdown_error', {
24444
24446
  connector_id: this._connectorFlowId,
24445
24447
  error: error instanceof Error ? error.message : String(error),
24446
24448
  });
@@ -24453,7 +24455,7 @@
24453
24455
  if (this._closeResolver) {
24454
24456
  this._closeResolver();
24455
24457
  }
24456
- logger$13.debug('connector_shutdown_complete', {
24458
+ logger$14.debug('connector_shutdown_complete', {
24457
24459
  connector_id: this._connectorFlowId,
24458
24460
  connector_type: this.constructor.name,
24459
24461
  final_state: this._state,
@@ -24529,7 +24531,7 @@
24529
24531
  }
24530
24532
  }
24531
24533
 
24532
- const logger$12 = getLogger('naylence.fame.connector.broadcast_channel_connector');
24534
+ const logger$13 = getLogger('naylence.fame.connector.broadcast_channel_connector');
24533
24535
  const BROADCAST_CHANNEL_CONNECTOR_TYPE = 'broadcast-channel-connector';
24534
24536
  const DEFAULT_CHANNEL$7 = 'naylence-fabric';
24535
24537
  const DEFAULT_INBOX_CAPACITY$7 = 2048;
@@ -24618,7 +24620,7 @@
24618
24620
  this.localNodeId = normalizedLocalNodeId;
24619
24621
  this.targetNodeId = BroadcastChannelConnector.normalizeTargetNodeId(config.initialTargetNodeId);
24620
24622
  this.channel = new BroadcastChannel(this.channelName);
24621
- logger$12.debug('broadcast_channel_connector_created', {
24623
+ logger$13.debug('broadcast_channel_connector_created', {
24622
24624
  channel: this.channelName,
24623
24625
  connector_id: this.connectorId,
24624
24626
  local_node_id: this.localNodeId,
@@ -24630,7 +24632,7 @@
24630
24632
  this.onMsg = (event) => {
24631
24633
  // Guard: Don't process if listener was unregistered
24632
24634
  if (!this.listenerRegistered) {
24633
- logger$12.warning('broadcast_channel_message_after_unregister', {
24635
+ logger$13.warning('broadcast_channel_message_after_unregister', {
24634
24636
  channel: this.channelName,
24635
24637
  connector_id: this.connectorId,
24636
24638
  timestamp: new Date().toISOString(),
@@ -24638,7 +24640,7 @@
24638
24640
  return;
24639
24641
  }
24640
24642
  const message = event.data;
24641
- logger$12.debug('broadcast_channel_raw_event', {
24643
+ logger$13.debug('broadcast_channel_raw_event', {
24642
24644
  channel: this.channelName,
24643
24645
  connector_id: this.connectorId,
24644
24646
  message_type: message && typeof message === 'object'
@@ -24654,7 +24656,7 @@
24654
24656
  const busMessage = message;
24655
24657
  const senderNodeId = BroadcastChannelConnector.normalizeNodeId(busMessage.senderNodeId);
24656
24658
  if (!senderNodeId) {
24657
- logger$12.debug('broadcast_channel_message_rejected', {
24659
+ logger$13.debug('broadcast_channel_message_rejected', {
24658
24660
  channel: this.channelName,
24659
24661
  connector_id: this.connectorId,
24660
24662
  reason: 'missing_sender_node_id',
@@ -24662,7 +24664,7 @@
24662
24664
  return;
24663
24665
  }
24664
24666
  if (senderNodeId === this.localNodeId) {
24665
- logger$12.debug('broadcast_channel_message_rejected', {
24667
+ logger$13.debug('broadcast_channel_message_rejected', {
24666
24668
  channel: this.channelName,
24667
24669
  connector_id: this.connectorId,
24668
24670
  reason: 'self_echo',
@@ -24676,14 +24678,14 @@
24676
24678
  }
24677
24679
  const payload = BroadcastChannelConnector.coercePayload(busMessage.payload);
24678
24680
  if (!payload) {
24679
- logger$12.debug('broadcast_channel_payload_rejected', {
24681
+ logger$13.debug('broadcast_channel_payload_rejected', {
24680
24682
  channel: this.channelName,
24681
24683
  connector_id: this.connectorId,
24682
24684
  reason: 'unrecognized_payload_type',
24683
24685
  });
24684
24686
  return;
24685
24687
  }
24686
- logger$12.debug('broadcast_channel_message_received', {
24688
+ logger$13.debug('broadcast_channel_message_received', {
24687
24689
  channel: this.channelName,
24688
24690
  sender_id: message?.senderId,
24689
24691
  sender_node_id: senderNodeId,
@@ -24712,14 +24714,14 @@
24712
24714
  }
24713
24715
  catch (error) {
24714
24716
  if (error instanceof QueueFullError) {
24715
- logger$12.warning('broadcast_channel_receive_queue_full', {
24717
+ logger$13.warning('broadcast_channel_receive_queue_full', {
24716
24718
  channel: this.channelName,
24717
24719
  inbox_capacity: this.inboxCapacity,
24718
24720
  inbox_remaining_capacity: this.inbox.remainingCapacity,
24719
24721
  });
24720
24722
  }
24721
24723
  else {
24722
- logger$12.error('broadcast_channel_receive_error', {
24724
+ logger$13.error('broadcast_channel_receive_error', {
24723
24725
  channel: this.channelName,
24724
24726
  error: error instanceof Error ? error.message : String(error),
24725
24727
  });
@@ -24733,7 +24735,7 @@
24733
24735
  // Setup visibility change monitoring
24734
24736
  this.visibilityChangeHandler = () => {
24735
24737
  const isHidden = document.hidden;
24736
- logger$12.debug('broadcast_channel_visibility_changed', {
24738
+ logger$13.debug('broadcast_channel_visibility_changed', {
24737
24739
  channel: this.channelName,
24738
24740
  connector_id: this.connectorId,
24739
24741
  visibility: isHidden ? 'hidden' : 'visible',
@@ -24742,7 +24744,7 @@
24742
24744
  // Pause/resume connector based on visibility
24743
24745
  if (isHidden && this.state === ConnectorState.STARTED) {
24744
24746
  this.pause().catch((err) => {
24745
- logger$12.warning('broadcast_channel_pause_failed', {
24747
+ logger$13.warning('broadcast_channel_pause_failed', {
24746
24748
  channel: this.channelName,
24747
24749
  connector_id: this.connectorId,
24748
24750
  error: err instanceof Error ? err.message : String(err),
@@ -24751,7 +24753,7 @@
24751
24753
  }
24752
24754
  else if (!isHidden && this.state === ConnectorState.PAUSED) {
24753
24755
  this.resume().catch((err) => {
24754
- logger$12.warning('broadcast_channel_resume_failed', {
24756
+ logger$13.warning('broadcast_channel_resume_failed', {
24755
24757
  channel: this.channelName,
24756
24758
  connector_id: this.connectorId,
24757
24759
  error: err instanceof Error ? err.message : String(err),
@@ -24765,7 +24767,7 @@
24765
24767
  // Track page lifecycle events to detect browser unload/discard
24766
24768
  if (typeof window !== 'undefined') {
24767
24769
  const lifecycleLogger = (event) => {
24768
- logger$12.debug('broadcast_channel_page_lifecycle', {
24770
+ logger$13.debug('broadcast_channel_page_lifecycle', {
24769
24771
  channel: this.channelName,
24770
24772
  connector_id: this.connectorId,
24771
24773
  event_type: event.type,
@@ -24781,7 +24783,7 @@
24781
24783
  document.addEventListener('resume', lifecycleLogger);
24782
24784
  }
24783
24785
  // Log initial state with detailed visibility info
24784
- logger$12.debug('broadcast_channel_initial_visibility', {
24786
+ logger$13.debug('broadcast_channel_initial_visibility', {
24785
24787
  channel: this.channelName,
24786
24788
  connector_id: this.connectorId,
24787
24789
  visibility: document.hidden ? 'hidden' : 'visible',
@@ -24813,14 +24815,14 @@
24813
24815
  }
24814
24816
  catch (error) {
24815
24817
  if (error instanceof QueueFullError) {
24816
- logger$12.warning('broadcast_channel_push_queue_full', {
24818
+ logger$13.warning('broadcast_channel_push_queue_full', {
24817
24819
  channel: this.channelName,
24818
24820
  inbox_capacity: this.inboxCapacity,
24819
24821
  inbox_remaining_capacity: this.inbox.remainingCapacity,
24820
24822
  });
24821
24823
  throw error;
24822
24824
  }
24823
- logger$12.error('broadcast_channel_push_failed', {
24825
+ logger$13.error('broadcast_channel_push_failed', {
24824
24826
  channel: this.channelName,
24825
24827
  error: error instanceof Error ? error.message : String(error),
24826
24828
  });
@@ -24830,7 +24832,7 @@
24830
24832
  async _transportSendBytes(data) {
24831
24833
  ensureBroadcastEnvironment();
24832
24834
  const targetNodeId = this.targetNodeId ?? '*';
24833
- logger$12.debug('broadcast_channel_message_sending', {
24835
+ logger$13.debug('broadcast_channel_message_sending', {
24834
24836
  channel: this.channelName,
24835
24837
  sender_id: this.connectorId,
24836
24838
  sender_node_id: this.localNodeId,
@@ -24851,7 +24853,7 @@
24851
24853
  return item;
24852
24854
  }
24853
24855
  async _transportClose(code, reason) {
24854
- logger$12.debug('broadcast_channel_transport_closing', {
24856
+ logger$13.debug('broadcast_channel_transport_closing', {
24855
24857
  channel: this.channelName,
24856
24858
  connector_id: this.connectorId,
24857
24859
  code,
@@ -24860,14 +24862,14 @@
24860
24862
  timestamp: new Date().toISOString(),
24861
24863
  });
24862
24864
  if (this.listenerRegistered) {
24863
- logger$12.debug('broadcast_channel_removing_listener', {
24865
+ logger$13.debug('broadcast_channel_removing_listener', {
24864
24866
  channel: this.channelName,
24865
24867
  connector_id: this.connectorId,
24866
24868
  timestamp: new Date().toISOString(),
24867
24869
  });
24868
24870
  this.channel.removeEventListener('message', this.onMsg);
24869
24871
  this.listenerRegistered = false;
24870
- logger$12.debug('broadcast_channel_listener_removed', {
24872
+ logger$13.debug('broadcast_channel_listener_removed', {
24871
24873
  channel: this.channelName,
24872
24874
  connector_id: this.connectorId,
24873
24875
  timestamp: new Date().toISOString(),
@@ -24880,13 +24882,13 @@
24880
24882
  this.visibilityChangeListenerRegistered = false;
24881
24883
  this.visibilityChangeHandler = undefined;
24882
24884
  }
24883
- logger$12.debug('broadcast_channel_closing', {
24885
+ logger$13.debug('broadcast_channel_closing', {
24884
24886
  channel: this.channelName,
24885
24887
  connector_id: this.connectorId,
24886
24888
  timestamp: new Date().toISOString(),
24887
24889
  });
24888
24890
  this.channel.close();
24889
- logger$12.debug('broadcast_channel_closed', {
24891
+ logger$13.debug('broadcast_channel_closed', {
24890
24892
  channel: this.channelName,
24891
24893
  connector_id: this.connectorId,
24892
24894
  timestamp: new Date().toISOString(),
@@ -24910,7 +24912,7 @@
24910
24912
  if (targetNodeId &&
24911
24913
  targetNodeId !== '*' &&
24912
24914
  targetNodeId !== this.localNodeId) {
24913
- logger$12.debug('broadcast_channel_message_rejected', {
24915
+ logger$13.debug('broadcast_channel_message_rejected', {
24914
24916
  channel: this.channelName,
24915
24917
  connector_id: this.connectorId,
24916
24918
  reason: 'wildcard_target_mismatch',
@@ -24926,7 +24928,7 @@
24926
24928
  if (expectedSender &&
24927
24929
  expectedSender !== '*' &&
24928
24930
  senderNodeId !== expectedSender) {
24929
- logger$12.debug('broadcast_channel_message_rejected', {
24931
+ logger$13.debug('broadcast_channel_message_rejected', {
24930
24932
  channel: this.channelName,
24931
24933
  connector_id: this.connectorId,
24932
24934
  reason: 'unexpected_sender',
@@ -24939,7 +24941,7 @@
24939
24941
  if (targetNodeId &&
24940
24942
  targetNodeId !== '*' &&
24941
24943
  targetNodeId !== this.localNodeId) {
24942
- logger$12.debug('broadcast_channel_message_rejected', {
24944
+ logger$13.debug('broadcast_channel_message_rejected', {
24943
24945
  channel: this.channelName,
24944
24946
  connector_id: this.connectorId,
24945
24947
  reason: 'unexpected_target',
@@ -24964,7 +24966,7 @@
24964
24966
  return 'unknown';
24965
24967
  }
24966
24968
  logInboxSnapshot(event, extra = {}) {
24967
- logger$12.debug(event, {
24969
+ logger$13.debug(event, {
24968
24970
  channel: this.channelName,
24969
24971
  connector_id: this.connectorId,
24970
24972
  connector_state: this.state,
@@ -24980,7 +24982,7 @@
24980
24982
  await super.start(inboundHandler);
24981
24983
  // After transitioning to STARTED, check if tab is already hidden
24982
24984
  if (typeof document !== 'undefined' && document.hidden) {
24983
- logger$12.debug('broadcast_channel_start_in_hidden_tab', {
24985
+ logger$13.debug('broadcast_channel_start_in_hidden_tab', {
24984
24986
  channel: this.channelName,
24985
24987
  connector_id: this.connectorId,
24986
24988
  document_hidden: document.hidden,
@@ -24990,7 +24992,7 @@
24990
24992
  });
24991
24993
  // Immediately pause if tab is hidden at start time
24992
24994
  await this.pause().catch((err) => {
24993
- logger$12.warning('broadcast_channel_initial_pause_failed', {
24995
+ logger$13.warning('broadcast_channel_initial_pause_failed', {
24994
24996
  channel: this.channelName,
24995
24997
  connector_id: this.connectorId,
24996
24998
  error: err instanceof Error ? err.message : String(err),
@@ -25008,7 +25010,7 @@
25008
25010
  return;
25009
25011
  }
25010
25012
  this.targetNodeId = normalized;
25011
- logger$12.debug('broadcast_channel_target_updated', {
25013
+ logger$13.debug('broadcast_channel_target_updated', {
25012
25014
  channel: this.channelName,
25013
25015
  connector_id: this.connectorId,
25014
25016
  local_node_id: this.localNodeId,
@@ -25018,7 +25020,7 @@
25018
25020
  }
25019
25021
  setWildcardTarget() {
25020
25022
  this.targetNodeId = '*';
25021
- logger$12.debug('broadcast_channel_target_updated', {
25023
+ logger$13.debug('broadcast_channel_target_updated', {
25022
25024
  channel: this.channelName,
25023
25025
  connector_id: this.connectorId,
25024
25026
  local_node_id: this.localNodeId,
@@ -25164,7 +25166,7 @@
25164
25166
  return config;
25165
25167
  }
25166
25168
 
25167
- const logger$11 = getLogger('naylence.fame.node.upstream_session_manager');
25169
+ const logger$12 = getLogger('naylence.fame.node.upstream_session_manager');
25168
25170
  function isPlainRecord$4(value) {
25169
25171
  if (typeof value !== 'object' || value === null) {
25170
25172
  return false;
@@ -25237,6 +25239,7 @@
25237
25239
  const onEpochChangeValue = pickOption$2(record, 'onEpochChange', 'on_epoch_change');
25238
25240
  const onEpochChange = typeof onEpochChangeValue === 'function' ? onEpochChangeValue : undefined;
25239
25241
  const admissionClient = pickOption$2(record, 'admissionClient', 'admission_client');
25242
+ const retryPolicy = pickOption$2(record, 'retryPolicy', 'retry_policy');
25240
25243
  return {
25241
25244
  node,
25242
25245
  attachClient,
@@ -25248,6 +25251,7 @@
25248
25251
  onAttach: validatedOnAttach,
25249
25252
  onEpochChange,
25250
25253
  admissionClient: admissionClient ?? undefined,
25254
+ retryPolicy: retryPolicy ?? undefined,
25251
25255
  };
25252
25256
  }
25253
25257
  class UpstreamSessionManager extends TaskSpawner {
@@ -25267,6 +25271,7 @@
25267
25271
  this.hadSuccessfulAttach = false;
25268
25272
  this.lastConnectorState = null;
25269
25273
  this.connectEpoch = 0;
25274
+ this.initialAttempts = 0;
25270
25275
  this._visibilityHandler = null;
25271
25276
  const options = normalizeOptions$k(optionsInput);
25272
25277
  this.node = options.node;
@@ -25280,31 +25285,34 @@
25280
25285
  this.admissionClient =
25281
25286
  options.admissionClient ?? options.node.admissionClient;
25282
25287
  this.wrappedHandler = this.makeHeartbeatEnabledHandler(options.inboundHandler);
25283
- logger$11.debug('created_upstream_session_manager', {
25288
+ // Store the connection retry policy (can be null, in which case default behavior applies)
25289
+ this.connectionRetryPolicy = options.retryPolicy ?? null;
25290
+ logger$12.debug('created_upstream_session_manager', {
25284
25291
  target_system_id: this.targetSystemId,
25292
+ has_retry_policy: this.connectionRetryPolicy !== null,
25285
25293
  });
25286
25294
  }
25287
25295
  get systemId() {
25288
25296
  return this.targetSystemId;
25289
25297
  }
25290
25298
  setupVisibilityListener() {
25291
- logger$11.debug('setup_visibility_listener_called', {
25299
+ logger$12.debug('setup_visibility_listener_called', {
25292
25300
  has_document: typeof document !== 'undefined',
25293
25301
  });
25294
25302
  if (typeof document !== 'undefined' && document.addEventListener) {
25295
25303
  this._visibilityHandler = () => {
25296
- logger$11.debug('visibility_change_event_fired', {
25304
+ logger$12.debug('visibility_change_event_fired', {
25297
25305
  state: document.visibilityState,
25298
25306
  });
25299
25307
  if (document.visibilityState === 'visible') {
25300
- logger$11.debug('visibility_change_detected_waking_up');
25308
+ logger$12.debug('visibility_change_detected_waking_up');
25301
25309
  this.wakeEvent.set();
25302
25310
  }
25303
25311
  };
25304
25312
  document.addEventListener('visibilitychange', this._visibilityHandler);
25305
25313
  }
25306
25314
  else {
25307
- logger$11.debug('setup_visibility_listener_skipped_no_document');
25315
+ logger$12.debug('setup_visibility_listener_skipped_no_document');
25308
25316
  }
25309
25317
  }
25310
25318
  teardownVisibilityListener() {
@@ -25337,13 +25345,13 @@
25337
25345
  }
25338
25346
  throw new FameConnectError('Upstream session manager failed to attach');
25339
25347
  }
25340
- logger$11.debug('upstream_session_manager_started');
25348
+ logger$12.debug('upstream_session_manager_started');
25341
25349
  }
25342
25350
  getActiveConnector() {
25343
25351
  return this.connector;
25344
25352
  }
25345
25353
  async stop() {
25346
- logger$11.debug('upstream_session_manager_stopping');
25354
+ logger$12.debug('upstream_session_manager_stopping');
25347
25355
  this.teardownVisibilityListener();
25348
25356
  this.stopEvent.set();
25349
25357
  this.currentStopSubtasks?.set();
@@ -25354,7 +25362,7 @@
25354
25362
  }
25355
25363
  catch (error) {
25356
25364
  if (!(error instanceof TaskCancelledError)) {
25357
- logger$11.debug('fsm_task_stopped_with_error', {
25365
+ logger$12.debug('fsm_task_stopped_with_error', {
25358
25366
  error: error.message,
25359
25367
  });
25360
25368
  }
@@ -25363,13 +25371,13 @@
25363
25371
  }
25364
25372
  if (this.connector) {
25365
25373
  await this.connector.stop().catch((error) => {
25366
- logger$11.debug('connector_stop_error', {
25374
+ logger$12.debug('connector_stop_error', {
25367
25375
  error: error.message,
25368
25376
  });
25369
25377
  });
25370
25378
  this.connector = null;
25371
25379
  }
25372
- logger$11.debug('upstream_session_manager_stopped');
25380
+ logger$12.debug('upstream_session_manager_stopped');
25373
25381
  }
25374
25382
  async send(envelope) {
25375
25383
  if (this.messageQueue.length >= UpstreamSessionManager.TX_QUEUE_MAX) {
@@ -25397,11 +25405,14 @@
25397
25405
  }
25398
25406
  async fsmLoop() {
25399
25407
  let delay = UpstreamSessionManager.BACKOFF_INITIAL;
25408
+ this.initialAttempts = 0;
25400
25409
  while (!this.stopEvent.isSet()) {
25401
25410
  const startTime = Date.now();
25411
+ this.initialAttempts += 1;
25402
25412
  try {
25403
25413
  await this.connectCycle();
25404
25414
  delay = UpstreamSessionManager.BACKOFF_INITIAL;
25415
+ this.initialAttempts = 0; // Reset on success
25405
25416
  }
25406
25417
  catch (error) {
25407
25418
  // Reset backoff if the connection was alive for more than 10 seconds
@@ -25411,32 +25422,38 @@
25411
25422
  if (error instanceof TaskCancelledError) {
25412
25423
  throw error;
25413
25424
  }
25425
+ // Determine if we should fail-fast or retry
25426
+ const shouldFailFast = this.shouldFailFastOnError(error);
25414
25427
  if (error instanceof FameTransportClose ||
25415
25428
  error instanceof FameConnectError) {
25416
- logger$11.warning('upstream_link_closed', {
25429
+ logger$12.warning('upstream_link_closed', {
25417
25430
  error: error.message,
25418
- will_retry: true,
25431
+ will_retry: !shouldFailFast,
25432
+ attempt: this.initialAttempts,
25433
+ has_retry_policy: this.connectionRetryPolicy !== null,
25419
25434
  });
25420
- if (!this.hadSuccessfulAttach && error instanceof FameConnectError) {
25435
+ if (shouldFailFast && error instanceof FameConnectError) {
25421
25436
  throw error;
25422
25437
  }
25423
25438
  }
25424
25439
  else {
25425
25440
  const err = error;
25426
25441
  if (err.name === 'OAuth2PkceRedirectInitiatedError') {
25427
- logger$11.info('upstream_link_redirecting', {
25442
+ logger$12.info('upstream_link_redirecting', {
25428
25443
  error: err.message,
25429
25444
  will_retry: true,
25430
25445
  });
25431
25446
  }
25432
25447
  else {
25433
- logger$11.warning('upstream_link_closed', {
25448
+ logger$12.warning('upstream_link_closed', {
25434
25449
  error: err.message,
25435
- will_retry: true,
25450
+ will_retry: !shouldFailFast,
25451
+ attempt: this.initialAttempts,
25452
+ has_retry_policy: this.connectionRetryPolicy !== null,
25436
25453
  exc_info: true,
25437
25454
  });
25438
25455
  }
25439
- if (!this.hadSuccessfulAttach) {
25456
+ if (shouldFailFast) {
25440
25457
  throw error;
25441
25458
  }
25442
25459
  }
@@ -25444,52 +25461,77 @@
25444
25461
  }
25445
25462
  }
25446
25463
  }
25464
+ /**
25465
+ * Determine whether to fail immediately or continue retrying.
25466
+ * Returns true if we should throw the error instead of retrying.
25467
+ */
25468
+ shouldFailFastOnError(error) {
25469
+ // If no policy is configured, use legacy behavior (fail-fast after first attempt)
25470
+ if (!this.connectionRetryPolicy) {
25471
+ // After first successful attach, always retry (existing behavior)
25472
+ if (this.hadSuccessfulAttach) {
25473
+ return false;
25474
+ }
25475
+ // Without a policy, fail on first error
25476
+ return true;
25477
+ }
25478
+ // Delegate decision to the policy
25479
+ const shouldRetry = this.connectionRetryPolicy.shouldRetry({
25480
+ hadSuccessfulAttach: this.hadSuccessfulAttach,
25481
+ attemptNumber: this.initialAttempts,
25482
+ error,
25483
+ });
25484
+ return !shouldRetry;
25485
+ }
25447
25486
  async applyBackoff(delay) {
25448
25487
  const jitter = Math.random() * delay;
25449
- await this.sleepWithStop(delay + jitter);
25488
+ const wasWoken = await this.sleepWithStop(delay + jitter);
25489
+ // If sleep was interrupted by visibility change (user returned to tab),
25490
+ // reset backoff to initial delay for immediate retry with fresh backoff
25491
+ if (wasWoken) {
25492
+ logger$12.debug('backoff_reset_on_visibility_change', {
25493
+ previous_delay: delay,
25494
+ new_delay: UpstreamSessionManager.BACKOFF_INITIAL,
25495
+ });
25496
+ return UpstreamSessionManager.BACKOFF_INITIAL;
25497
+ }
25450
25498
  return Math.min(delay * 2, UpstreamSessionManager.BACKOFF_CAP);
25451
25499
  }
25500
+ /**
25501
+ * Sleep for the specified duration, but can be interrupted by stop or wake events.
25502
+ * @returns true if interrupted by wake event (e.g., visibility change), false otherwise
25503
+ */
25452
25504
  async sleepWithStop(delaySeconds) {
25453
25505
  if (delaySeconds <= 0) {
25454
- return;
25455
- }
25456
- // If the document is visible, cap the backoff delay to improve UX
25457
- // This ensures that if the user is watching, we retry quickly (e.g. 1s)
25458
- // instead of waiting for the full exponential backoff (up to 30s).
25459
- let effectiveDelay = delaySeconds;
25460
- if (typeof document !== 'undefined' &&
25461
- document.visibilityState === 'visible') {
25462
- effectiveDelay = Math.min(delaySeconds, 1.0);
25463
- if (effectiveDelay < delaySeconds) {
25464
- logger$11.debug('sleep_reduced_document_visible', {
25465
- original: delaySeconds,
25466
- new: effectiveDelay,
25467
- });
25468
- }
25506
+ return false;
25469
25507
  }
25508
+ // Check if wake event is already set (e.g., visibility just changed)
25470
25509
  if (this.wakeEvent.isSet()) {
25471
25510
  this.wakeEvent.clear();
25472
- return;
25511
+ logger$12.debug('sleep_skipped_wake_event_pending');
25512
+ return true;
25473
25513
  }
25474
25514
  let timeout;
25475
25515
  const sleepPromise = new Promise((resolve) => {
25476
25516
  timeout = setTimeout(() => {
25477
25517
  timeout = undefined;
25478
25518
  resolve();
25479
- }, effectiveDelay * 1000);
25519
+ }, delaySeconds * 1000);
25480
25520
  });
25481
25521
  await Promise.race([
25482
25522
  sleepPromise,
25483
25523
  this.stopEvent.wait(),
25484
25524
  this.wakeEvent.wait(),
25485
25525
  ]);
25486
- if (this.wakeEvent.isSet()) {
25487
- logger$11.debug('sleep_interrupted_by_wake_event');
25526
+ const wasWoken = this.wakeEvent.isSet();
25527
+ if (wasWoken) {
25528
+ logger$12.debug('sleep_interrupted_by_wake_event');
25488
25529
  this.wakeEvent.clear();
25489
25530
  }
25490
25531
  if (timeout !== undefined) {
25491
25532
  clearTimeout(timeout);
25492
25533
  }
25534
+ return wasWoken;
25493
25535
  }
25494
25536
  getNodeAttachGrant(connectionGrants) {
25495
25537
  if (!connectionGrants) {
@@ -25546,7 +25588,7 @@
25546
25588
  await connector.start(this.wrappedHandler);
25547
25589
  this.connector = connector;
25548
25590
  const callbackGrants = this.node.gatherSupportedCallbackGrants();
25549
- logger$11.debug('callback_grants_before_augmentation', {
25591
+ logger$12.debug('callback_grants_before_augmentation', {
25550
25592
  count: callbackGrants.length,
25551
25593
  types: callbackGrants.map((g) => g.type),
25552
25594
  });
@@ -25556,7 +25598,7 @@
25556
25598
  const broadcastCallbackGrant = shouldAddBroadcastGrant
25557
25599
  ? this.createBroadcastCallbackGrant(grant)
25558
25600
  : null;
25559
- logger$11.debug('broadcast_callback_grant_check', {
25601
+ logger$12.debug('broadcast_callback_grant_check', {
25560
25602
  should_add: shouldAddBroadcastGrant,
25561
25603
  grant_created: !!broadcastCallbackGrant,
25562
25604
  });
@@ -25575,12 +25617,12 @@
25575
25617
  const isDuplicate = callbackGrants.some((existing) => JSON.stringify(existing) === JSON.stringify(grant));
25576
25618
  if (!isDuplicate) {
25577
25619
  callbackGrants.push(grant);
25578
- logger$11.debug('added_connection_grant_as_callback', {
25620
+ logger$12.debug('added_connection_grant_as_callback', {
25579
25621
  type: grant.type,
25580
25622
  });
25581
25623
  }
25582
25624
  else {
25583
- logger$11.debug('skipped_duplicate_connection_grant', {
25625
+ logger$12.debug('skipped_duplicate_connection_grant', {
25584
25626
  type: grant.type,
25585
25627
  });
25586
25628
  }
@@ -25592,12 +25634,12 @@
25592
25634
  if (broadcastCallbackGrant &&
25593
25635
  this.shouldAdvertiseBroadcastGrant(grant, callbackGrants)) {
25594
25636
  callbackGrants.push(broadcastCallbackGrant);
25595
- logger$11.debug('added_broadcast_callback_grant');
25637
+ logger$12.debug('added_broadcast_callback_grant');
25596
25638
  }
25597
25639
  else if (broadcastCallbackGrant) {
25598
- logger$11.debug('skipped_duplicate_broadcast_callback_grant');
25640
+ logger$12.debug('skipped_duplicate_broadcast_callback_grant');
25599
25641
  }
25600
- logger$11.debug('callback_grants_after_augmentation', {
25642
+ logger$12.debug('callback_grants_after_augmentation', {
25601
25643
  count: callbackGrants.length,
25602
25644
  types: callbackGrants.map((g) => g.type),
25603
25645
  });
@@ -25610,7 +25652,7 @@
25610
25652
  targetAware.setTargetNodeId(this.targetSystemId);
25611
25653
  }
25612
25654
  catch (error) {
25613
- logger$11.warning('broadcast_channel_target_apply_failed', {
25655
+ logger$12.warning('broadcast_channel_target_apply_failed', {
25614
25656
  error: error instanceof Error ? error.message : String(error),
25615
25657
  target_node_id: this.targetSystemId,
25616
25658
  });
@@ -25632,14 +25674,14 @@
25632
25674
  });
25633
25675
  }
25634
25676
  else {
25635
- logger$11.warning('parent_epoch_changed', { epoch });
25677
+ logger$12.warning('parent_epoch_changed', { epoch });
25636
25678
  }
25637
25679
  }
25638
25680
  if (!this.readyEvent.isSet()) {
25639
25681
  this.readyEvent.set();
25640
25682
  }
25641
25683
  if (this.messageQueue.length > 0) {
25642
- logger$11.debug('flushing_buffered_frames', {
25684
+ logger$12.debug('flushing_buffered_frames', {
25643
25685
  queue_size: this.messageQueue.length,
25644
25686
  });
25645
25687
  this.queueEvent.set();
@@ -25656,12 +25698,12 @@
25656
25698
  name: `expiry-guard-${this.connectEpoch}`,
25657
25699
  });
25658
25700
  if (this.hadSuccessfulAttach) {
25659
- logger$11.debug('reconnected_to_upstream', {
25701
+ logger$12.debug('reconnected_to_upstream', {
25660
25702
  attach_expires_at: attachInfo.attachExpiresAt?.toISOString?.() ?? null,
25661
25703
  });
25662
25704
  }
25663
25705
  else {
25664
- logger$11.debug('connected_to_upstream', {
25706
+ logger$12.debug('connected_to_upstream', {
25665
25707
  attach_expires_at: attachInfo.attachExpiresAt?.toISOString?.() ?? null,
25666
25708
  });
25667
25709
  }
@@ -25679,18 +25721,18 @@
25679
25721
  this.currentStopSubtasks = null;
25680
25722
  await Promise.allSettled(tasks.map((task) => task.promise));
25681
25723
  if (this.connector) {
25682
- logger$11.debug('upstream_stopping_old_connector', {
25724
+ logger$12.debug('upstream_stopping_old_connector', {
25683
25725
  connect_epoch: this.connectEpoch,
25684
25726
  target_system_id: this.targetSystemId,
25685
25727
  timestamp: new Date().toISOString(),
25686
25728
  });
25687
25729
  await this.connector.stop().catch((err) => {
25688
- logger$11.warning('upstream_connector_stop_error', {
25730
+ logger$12.warning('upstream_connector_stop_error', {
25689
25731
  connect_epoch: this.connectEpoch,
25690
25732
  error: err instanceof Error ? err.message : String(err),
25691
25733
  });
25692
25734
  });
25693
- logger$11.debug('upstream_old_connector_stopped', {
25735
+ logger$12.debug('upstream_old_connector_stopped', {
25694
25736
  connect_epoch: this.connectEpoch,
25695
25737
  target_system_id: this.targetSystemId,
25696
25738
  timestamp: new Date().toISOString(),
@@ -25743,7 +25785,7 @@
25743
25785
  });
25744
25786
  }
25745
25787
  catch (error) {
25746
- logger$11.debug('broadcast_callback_grant_generation_failed', {
25788
+ logger$12.debug('broadcast_callback_grant_generation_failed', {
25747
25789
  error: error instanceof Error ? error.message : String(error),
25748
25790
  });
25749
25791
  return null;
@@ -25798,7 +25840,7 @@
25798
25840
  }
25799
25841
  }
25800
25842
  async heartbeatLoop(connector, stopEvt, signal) {
25801
- logger$11.debug('starting_heartbeat_loop');
25843
+ logger$12.debug('starting_heartbeat_loop');
25802
25844
  const intervalMs = UpstreamSessionManager.HEARTBEAT_INTERVAL * 1000;
25803
25845
  const graceMs = intervalMs * UpstreamSessionManager.HEARTBEAT_GRACE;
25804
25846
  this.lastHeartbeatAckTime = Date.now();
@@ -25834,7 +25876,7 @@
25834
25876
  // Skip heartbeat if connector is paused (e.g., tab is hidden)
25835
25877
  // Keep ack time current so we don't timeout immediately after resuming
25836
25878
  if (currentState === ConnectorState.PAUSED) {
25837
- logger$11.debug('skipping_heartbeat_connector_paused', {
25879
+ logger$12.debug('skipping_heartbeat_connector_paused', {
25838
25880
  connector_state: currentState,
25839
25881
  });
25840
25882
  this.lastHeartbeatAckTime = Date.now();
@@ -25843,14 +25885,14 @@
25843
25885
  // Reset ack time if just resumed from pause (prevents immediate timeout)
25844
25886
  if (previousState === ConnectorState.PAUSED &&
25845
25887
  currentState === ConnectorState.STARTED) {
25846
- logger$11.debug('connector_just_resumed_resetting_ack_time', {
25888
+ logger$12.debug('connector_just_resumed_resetting_ack_time', {
25847
25889
  previous_state: previousState,
25848
25890
  current_state: currentState,
25849
25891
  });
25850
25892
  this.lastHeartbeatAckTime = Date.now();
25851
25893
  }
25852
25894
  const envelope = await this.makeHeartbeatEnvelope();
25853
- logger$11.debug('sending_heartbeat', {
25895
+ logger$12.debug('sending_heartbeat', {
25854
25896
  hb_corr_id: envelope.corrId,
25855
25897
  hb_env_id: envelope.id,
25856
25898
  });
@@ -25876,7 +25918,7 @@
25876
25918
  throw new FameConnectError('missed heartbeat acknowledgement');
25877
25919
  }
25878
25920
  }
25879
- logger$11.debug('completed_heartbeat_loop');
25921
+ logger$12.debug('completed_heartbeat_loop');
25880
25922
  }
25881
25923
  async messagePumpLoop(connector, stopEvt, signal) {
25882
25924
  while (!stopEvt.isSet() && !signal?.aborted) {
@@ -25893,19 +25935,19 @@
25893
25935
  if (!envelope) {
25894
25936
  continue;
25895
25937
  }
25896
- logger$11.debug('upstream_pump_sending_envelope', {
25938
+ logger$12.debug('upstream_pump_sending_envelope', {
25897
25939
  envelopeId: envelope.id,
25898
25940
  type: envelope.frame?.type,
25899
25941
  });
25900
25942
  try {
25901
25943
  await connector.send(envelope);
25902
- logger$11.debug('upstream_pump_sent_envelope', {
25944
+ logger$12.debug('upstream_pump_sent_envelope', {
25903
25945
  envelopeId: envelope.id,
25904
25946
  });
25905
25947
  }
25906
25948
  catch (error) {
25907
25949
  if (error instanceof FameMessageTooLarge) {
25908
- logger$11.error('failed_to_send_message', { error: error.message });
25950
+ logger$12.error('failed_to_send_message', { error: error.message });
25909
25951
  await this.handleMessageTooLarge(envelope, error.message);
25910
25952
  }
25911
25953
  else if (error instanceof FameTransportClose) {
@@ -25967,7 +26009,7 @@
25967
26009
  await fabric.send(ackEnvelope);
25968
26010
  }
25969
26011
  catch (error) {
25970
- logger$11.warning('failed_to_send_nack', {
26012
+ logger$12.warning('failed_to_send_nack', {
25971
26013
  error: error.message,
25972
26014
  });
25973
26015
  }
@@ -25981,7 +26023,7 @@
25981
26023
  timestamps.push(info.attachExpiresAt);
25982
26024
  }
25983
26025
  if (!timestamps.length) {
25984
- logger$11.debug('no_ttl_expiry_configured');
26026
+ logger$12.debug('no_ttl_expiry_configured');
25985
26027
  await this.waitEvent(stopEvt, signal);
25986
26028
  return;
25987
26029
  }
@@ -25990,7 +26032,7 @@
25990
26032
  let delaySeconds = (earliest.getTime() - now.getTime()) / 1000 -
25991
26033
  UpstreamSessionManager.JWT_REFRESH_SAFETY;
25992
26034
  delaySeconds = Math.max(delaySeconds, UpstreamSessionManager.JWT_REFRESH_SAFETY);
25993
- logger$11.debug('ttl_expiry_guard_started', {
26035
+ logger$12.debug('ttl_expiry_guard_started', {
25994
26036
  welcome_expires_at: welcome.frame.expiresAt ?? null,
25995
26037
  attach_expires_at: info.attachExpiresAt?.toISOString?.() ?? null,
25996
26038
  earliest_expiry: earliest.toISOString(),
@@ -26018,7 +26060,7 @@
26018
26060
  }
26019
26061
  }
26020
26062
  if (!stopEvt.isSet()) {
26021
- logger$11.debug('ttl_expiry_triggered_reconnect', {
26063
+ logger$12.debug('ttl_expiry_triggered_reconnect', {
26022
26064
  expires_at: earliest.toISOString(),
26023
26065
  current_time: new Date().toISOString(),
26024
26066
  seconds_before_expiry: UpstreamSessionManager.JWT_REFRESH_SAFETY,
@@ -26063,7 +26105,7 @@
26063
26105
  }
26064
26106
  await this.node.dispatchEnvelopeEvent('onEnvelopeReceived', this.node, env, context);
26065
26107
  if (env.frame.type === 'NodeHeartbeatAck') {
26066
- logger$11.debug('received_heartbeat_ack', {
26108
+ logger$12.debug('received_heartbeat_ack', {
26067
26109
  hb_ack_env_id: env.id,
26068
26110
  hb_ack_corr_id: env.corrId,
26069
26111
  hb_routing_epoch: env.frame.routingEpoch,
@@ -26077,7 +26119,7 @@
26077
26119
  await this.onEpochChange(epoch);
26078
26120
  }
26079
26121
  else {
26080
- logger$11.warning('parent_epoch_changed', { epoch });
26122
+ logger$12.warning('parent_epoch_changed', { epoch });
26081
26123
  }
26082
26124
  }
26083
26125
  return;
@@ -26096,7 +26138,7 @@
26096
26138
  UpstreamSessionManager.BACKOFF_INITIAL = 1; // seconds
26097
26139
  UpstreamSessionManager.BACKOFF_CAP = 30; // seconds
26098
26140
 
26099
- const logger$10 = getLogger('naylence.fame.node.admission.noop_admission_client');
26141
+ const logger$11 = getLogger('naylence.fame.node.admission.noop_admission_client');
26100
26142
  class NoopAdmissionClient {
26101
26143
  constructor(options = {}) {
26102
26144
  this.hasUpstream = false;
@@ -26110,7 +26152,7 @@
26110
26152
  const acceptedLogicals = this.autoAcceptLogicals
26111
26153
  ? [...(requestedLogicals ?? [])]
26112
26154
  : [];
26113
- logger$10.debug('noop_admission_hello', {
26155
+ logger$11.debug('noop_admission_hello', {
26114
26156
  systemId: effectiveSystemId,
26115
26157
  instanceId,
26116
26158
  requestedLogicals,
@@ -26128,7 +26170,7 @@
26128
26170
  });
26129
26171
  }
26130
26172
  async close() {
26131
- logger$10.debug('noop_admission_close');
26173
+ logger$11.debug('noop_admission_close');
26132
26174
  }
26133
26175
  }
26134
26176
 
@@ -26334,7 +26376,7 @@
26334
26376
  }
26335
26377
 
26336
26378
  const SYSTEM_INBOX$1 = '__sys__';
26337
- const logger$$ = getLogger('naylence.fame.node.node');
26379
+ const logger$10 = getLogger('naylence.fame.node.node');
26338
26380
  function isSnakeCase(name) {
26339
26381
  return name.includes('_');
26340
26382
  }
@@ -26461,6 +26503,8 @@
26461
26503
  this._acceptedLogicals = new Set(acceptedLogicalsOption);
26462
26504
  const deliveryPolicyOption = resolveOption(options, 'deliveryPolicy', 'delivery_policy');
26463
26505
  this._deliveryPolicy = deliveryPolicyOption ?? null;
26506
+ const connectionRetryPolicyOption = resolveOption(options, 'connectionRetryPolicy', 'connection_retry_policy');
26507
+ this._connectionRetryPolicy = connectionRetryPolicyOption ?? null;
26464
26508
  const admissionClientOption = resolveOption(options, 'admissionClient', 'admission_client');
26465
26509
  this._admissionClient = admissionClientOption ?? null;
26466
26510
  const attachClientOption = resolveOption(options, 'attachClient', 'attach_client');
@@ -26590,6 +26634,7 @@
26590
26634
  onAttach: (info, connector) => this.handleAttach(info, connector),
26591
26635
  onEpochChange: (epoch) => this.handleEpochChange(epoch),
26592
26636
  admissionClient: this._admissionClient,
26637
+ retryPolicy: this._connectionRetryPolicy,
26593
26638
  });
26594
26639
  this._sessionManager = manager;
26595
26640
  await manager.start();
@@ -26601,7 +26646,7 @@
26601
26646
  confirmIdentity(systemId, source) {
26602
26647
  if (this._confirmedId) {
26603
26648
  if (this._confirmedId !== systemId) {
26604
- logger$$.error('node_identity_mismatch', {
26649
+ logger$10.error('node_identity_mismatch', {
26605
26650
  current_id: this._confirmedId,
26606
26651
  new_id: systemId,
26607
26652
  source,
@@ -26613,14 +26658,14 @@
26613
26658
  const isReassignment = this._provisionalId !== systemId;
26614
26659
  this._confirmedId = systemId;
26615
26660
  if (isReassignment) {
26616
- logger$$.debug('node_identity_reassigned', {
26661
+ logger$10.debug('node_identity_reassigned', {
26617
26662
  system_id: systemId,
26618
26663
  previous_id: this._provisionalId,
26619
26664
  source,
26620
26665
  });
26621
26666
  }
26622
26667
  else {
26623
- logger$$.debug('node_identity_confirmed', {
26668
+ logger$10.debug('node_identity_confirmed', {
26624
26669
  system_id: systemId,
26625
26670
  source,
26626
26671
  });
@@ -26688,7 +26733,7 @@
26688
26733
  return;
26689
26734
  }
26690
26735
  if (frameType === 'NodeHeartbeat') {
26691
- logger$$.debug('received_heartbeat_frame', {
26736
+ logger$10.debug('received_heartbeat_frame', {
26692
26737
  envelopeId: envelope.id,
26693
26738
  corrId: envelope.corrId ?? null,
26694
26739
  });
@@ -26700,7 +26745,7 @@
26700
26745
  await this.handleDeliveryAck(envelope, context);
26701
26746
  return;
26702
26747
  }
26703
- logger$$.debug('unhandled_system_frame', {
26748
+ logger$10.debug('unhandled_system_frame', {
26704
26749
  envelopeId: envelope.id,
26705
26750
  frameType,
26706
26751
  });
@@ -26712,13 +26757,13 @@
26712
26757
  }
26713
26758
  await this._deliveryTracker.onEnvelopeDelivered(SYSTEM_INBOX$1, envelope, context);
26714
26759
  if (frame.ok !== false) {
26715
- logger$$.debug('delivery_ack_received', {
26760
+ logger$10.debug('delivery_ack_received', {
26716
26761
  envelopeId: envelope.id,
26717
26762
  corrId: envelope.corrId ?? null,
26718
26763
  });
26719
26764
  return;
26720
26765
  }
26721
- logger$$.warning('delivery_nack_received', {
26766
+ logger$10.warning('delivery_nack_received', {
26722
26767
  envelopeId: envelope.id,
26723
26768
  corrId: envelope.corrId ?? null,
26724
26769
  code: frame.code ?? null,
@@ -26728,7 +26773,7 @@
26728
26773
  await this.onDeliveryNack(frame, envelope, context);
26729
26774
  }
26730
26775
  async onDeliveryNack(frame, envelope, _context) {
26731
- logger$$.debug('delivery_nack_processed', {
26776
+ logger$10.debug('delivery_nack_processed', {
26732
26777
  envelopeId: envelope.id,
26733
26778
  code: frame.code ?? null,
26734
26779
  reason: frame.reason ?? null,
@@ -26843,7 +26888,7 @@
26843
26888
  await this._bindingManager.restore();
26844
26889
  await this._envelopeListenerManager.start();
26845
26890
  this._isStarted = true;
26846
- logger$$.debug('node_started', {
26891
+ logger$10.debug('node_started', {
26847
26892
  node_id: this.id,
26848
26893
  sid: this.sid,
26849
26894
  path: this.physicalPath,
@@ -26875,7 +26920,7 @@
26875
26920
  await this._serviceManager.stop();
26876
26921
  await this.dispatchEvent('onNodeStopped', this);
26877
26922
  this._isStarted = false;
26878
- logger$$.debug('node_stopped', {
26923
+ logger$10.debug('node_stopped', {
26879
26924
  node_id: this.id,
26880
26925
  });
26881
26926
  }
@@ -27065,20 +27110,20 @@
27065
27110
  await this.forwardUpstream(processedEnvelope, context);
27066
27111
  }
27067
27112
  else {
27068
- logger$$.error('attempted_upstream_loop', {
27113
+ logger$10.error('attempted_upstream_loop', {
27069
27114
  envelopeId: processedEnvelope.id,
27070
27115
  });
27071
27116
  }
27072
27117
  return;
27073
27118
  }
27074
27119
  if (!processedEnvelope.to) {
27075
- logger$$.error('dropping_envelope_without_destination', {
27120
+ logger$10.error('dropping_envelope_without_destination', {
27076
27121
  envelopeId: processedEnvelope.id,
27077
27122
  capabilities: processedEnvelope.capabilities ?? [],
27078
27123
  });
27079
27124
  return;
27080
27125
  }
27081
- logger$$.warning('no_local_handler_for_address', {
27126
+ logger$10.warning('no_local_handler_for_address', {
27082
27127
  address: processedEnvelope.to.toString?.() ?? String(processedEnvelope.to),
27083
27128
  originType: context?.originType ?? null,
27084
27129
  });
@@ -27202,7 +27247,7 @@
27202
27247
  }
27203
27248
  }
27204
27249
  catch (error) {
27205
- logger$$.warning('callback_grant_collection_failed', {
27250
+ logger$10.warning('callback_grant_collection_failed', {
27206
27251
  error: error instanceof Error ? error.message : String(error),
27207
27252
  });
27208
27253
  }
@@ -27265,7 +27310,7 @@
27265
27310
  await store.set('self', record);
27266
27311
  }
27267
27312
  catch (error) {
27268
- logger$$.warning('node_meta_persist_failed', {
27313
+ logger$10.warning('node_meta_persist_failed', {
27269
27314
  error: error instanceof Error ? error.message : String(error),
27270
27315
  });
27271
27316
  }
@@ -27294,6 +27339,7 @@
27294
27339
  telemetry: unknown().optional().nullable(),
27295
27340
  requestedCapabilities: array(string$1()).optional(),
27296
27341
  identityPolicy: unknown().optional().nullable(),
27342
+ connectionRetryPolicy: unknown().optional().nullable(),
27297
27343
  })
27298
27344
  .passthrough();
27299
27345
  function normalizeFameNodeConfig(input) {
@@ -27335,6 +27381,9 @@
27335
27381
  identityPolicy: parsed.identityPolicy === undefined
27336
27382
  ? null
27337
27383
  : parsed.identityPolicy,
27384
+ connectionRetryPolicy: parsed.connectionRetryPolicy === undefined
27385
+ ? null
27386
+ : parsed.connectionRetryPolicy,
27338
27387
  };
27339
27388
  if (parsed.requestedCapabilities) {
27340
27389
  normalized.requestedCapabilities = coerceStringArray$1(parsed.requestedCapabilities);
@@ -27379,6 +27428,24 @@
27379
27428
  }
27380
27429
  }
27381
27430
 
27431
+ const CONNECTION_RETRY_POLICY_FACTORY_BASE_TYPE = 'ConnectionRetryPolicyFactory';
27432
+ class ConnectionRetryPolicyFactory extends AbstractResourceFactory {
27433
+ static async createConnectionRetryPolicy(config, options = {}) {
27434
+ if (config) {
27435
+ const policy = await createResource$1(CONNECTION_RETRY_POLICY_FACTORY_BASE_TYPE, config, options);
27436
+ if (!policy) {
27437
+ throw new Error('Failed to create connection retry policy from configuration');
27438
+ }
27439
+ return policy;
27440
+ }
27441
+ const policy = await createDefaultResource(CONNECTION_RETRY_POLICY_FACTORY_BASE_TYPE, null, options);
27442
+ if (!policy) {
27443
+ throw new Error('Failed to create default connection retry policy');
27444
+ }
27445
+ return policy;
27446
+ }
27447
+ }
27448
+
27382
27449
  const TOKEN_PROVIDER_FACTORY_BASE_TYPE = 'TokenProviderFactory';
27383
27450
  class TokenProviderFactory extends AbstractResourceFactory {
27384
27451
  static async createTokenProvider(config, options = {}) {
@@ -27416,7 +27483,7 @@
27416
27483
  'function');
27417
27484
  }
27418
27485
 
27419
- const logger$_ = getLogger('naylence.fame.node.default_node_identity_policy');
27486
+ const logger$$ = getLogger('naylence.fame.node.default_node_identity_policy');
27420
27487
  class DefaultNodeIdentityPolicy {
27421
27488
  async resolveInitialNodeId(context) {
27422
27489
  if (context.configuredId) {
@@ -27446,7 +27513,7 @@
27446
27513
  if (isIdentityExposingTokenProvider(provider)) {
27447
27514
  const identity = await provider.getIdentity();
27448
27515
  if (identity && identity.subject) {
27449
- logger$_.debug('identity_extracted_from_grant', {
27516
+ logger$$.debug('identity_extracted_from_grant', {
27450
27517
  identity_id: identity.subject,
27451
27518
  grant_type: grant.type,
27452
27519
  });
@@ -27455,7 +27522,7 @@
27455
27522
  }
27456
27523
  }
27457
27524
  catch (error) {
27458
- logger$_.warning('identity_extraction_failed', {
27525
+ logger$$.warning('identity_extraction_failed', {
27459
27526
  error: error instanceof Error ? error.message : String(error),
27460
27527
  grant_type: grant.type,
27461
27528
  });
@@ -27539,7 +27606,7 @@
27539
27606
  }
27540
27607
  }
27541
27608
 
27542
- const logger$Z = getLogger('naylence.fame.node.admission.default_node_attach_client');
27609
+ const logger$_ = getLogger('naylence.fame.node.admission.default_node_attach_client');
27543
27610
  const HANDSHAKE_POLL_INTERVAL_MS = 20;
27544
27611
  class DefaultNodeAttachClient {
27545
27612
  constructor(options = {}) {
@@ -27563,7 +27630,7 @@
27563
27630
  }
27564
27631
  else {
27565
27632
  // Silently ignore frames from other agents during concurrent handshakes
27566
- logger$Z.debug('handshake_ignoring_frame_from_different_system', {
27633
+ logger$_.debug('handshake_ignoring_frame_from_different_system', {
27567
27634
  frame_type: envelope.frame.type,
27568
27635
  frame_system_id: frameSystemId,
27569
27636
  expected_system_id: this.expectedSystemId,
@@ -27606,7 +27673,7 @@
27606
27673
  }
27607
27674
  }
27608
27675
  catch (error) {
27609
- logger$Z.debug('stickiness_offer_skipped', {
27676
+ logger$_.debug('stickiness_offer_skipped', {
27610
27677
  error: error instanceof Error ? error.message : String(error),
27611
27678
  });
27612
27679
  }
@@ -27627,7 +27694,7 @@
27627
27694
  if (!processedEnvelope) {
27628
27695
  throw new Error('Envelope was blocked by onForwardUpstream event');
27629
27696
  }
27630
- logger$Z.debug('sending_node_attach_envelope', {
27697
+ logger$_.debug('sending_node_attach_envelope', {
27631
27698
  envp_id: processedEnvelope.id ?? envelope.id ?? null,
27632
27699
  frame_type: processedEnvelope.frame?.type ?? 'unknown',
27633
27700
  trace_id: processedEnvelope.traceId ?? envelope.traceId ?? null,
@@ -27663,7 +27730,7 @@
27663
27730
  try {
27664
27731
  const keyInfos = await this.attachmentKeyValidator.validateKeys(parentKeys);
27665
27732
  if (Array.isArray(keyInfos) && keyInfos.length > 0) {
27666
- logger$Z.debug('parent_certificate_validation_passed', {
27733
+ logger$_.debug('parent_certificate_validation_passed', {
27667
27734
  parent_id: parentId,
27668
27735
  correlation_id: corrId,
27669
27736
  validated_keys: keyInfos.length,
@@ -27672,7 +27739,7 @@
27672
27739
  }
27673
27740
  catch (error) {
27674
27741
  if (error instanceof KeyValidationError) {
27675
- logger$Z.error('parent_certificate_validation_failed', {
27742
+ logger$_.error('parent_certificate_validation_failed', {
27676
27743
  parent_id: parentId,
27677
27744
  correlation_id: corrId,
27678
27745
  error_code: error.code,
@@ -27686,12 +27753,12 @@
27686
27753
  }
27687
27754
  }
27688
27755
  else {
27689
- logger$Z.debug('parent_certificate_validation_skipped', {
27756
+ logger$_.debug('parent_certificate_validation_skipped', {
27690
27757
  parent_id: parentId,
27691
27758
  reason: 'no_validator',
27692
27759
  });
27693
27760
  }
27694
- logger$Z.debug('processing_node_attach_ack', {
27761
+ logger$_.debug('processing_node_attach_ack', {
27695
27762
  parent_id: ackFrame.targetSystemId,
27696
27763
  });
27697
27764
  this.inHandshake = false;
@@ -27722,7 +27789,7 @@
27722
27789
  }
27723
27790
  }
27724
27791
  catch (error) {
27725
- logger$Z.debug('stickiness_accept_skipped', {
27792
+ logger$_.debug('stickiness_accept_skipped', {
27726
27793
  error: error instanceof Error ? error.message : String(error),
27727
27794
  });
27728
27795
  }
@@ -27776,7 +27843,7 @@
27776
27843
  // NodeAttach frames during handshake are expected in multi-agent scenarios
27777
27844
  // where multiple agents attach concurrently to the same channel
27778
27845
  if (envelope.frame.type === 'NodeAttach') {
27779
- logger$Z.debug('handshake_ignoring_concurrent_attach', {
27846
+ logger$_.debug('handshake_ignoring_concurrent_attach', {
27780
27847
  frame_type: envelope.frame.type,
27781
27848
  frame_system_id: envelope.frame?.systemId ??
27782
27849
  'unknown',
@@ -27784,7 +27851,7 @@
27784
27851
  }
27785
27852
  else {
27786
27853
  // Other unexpected frames are still logged as errors
27787
- logger$Z.error('unexpected_frame_during_handshake', {
27854
+ logger$_.error('unexpected_frame_during_handshake', {
27788
27855
  frame_type: envelope.frame.type,
27789
27856
  });
27790
27857
  }
@@ -27919,7 +27986,7 @@
27919
27986
  // void import('./trace-emitter-profile-factory.js');
27920
27987
 
27921
27988
  const BINDING_STORE_NAMESPACE = '__binding_store';
27922
- const logger$Y = getLogger('naylence.fame.node.factory_commons');
27989
+ const logger$Z = getLogger('naylence.fame.node.factory_commons');
27923
27990
  function isPlainRecord$2(value) {
27924
27991
  return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
27925
27992
  }
@@ -28026,6 +28093,7 @@
28026
28093
  const telemetryConfig = pickOption$1(config.telemetry ?? null, aliasRecord, 'trace_emitter', 'telemetry_config');
28027
28094
  const securityConfig = pickOption$1(config.security ?? null, aliasRecord, 'security_manager', 'security_profile');
28028
28095
  const identityPolicyConfig = pickOption$1(config.identityPolicy ?? null, aliasRecord, 'identity_policy', 'node_identity_policy');
28096
+ const connectionRetryPolicyConfig = pickOption$1(config.connectionRetryPolicy ?? null, aliasRecord, 'connection_retry_policy', 'retry_policy');
28029
28097
  const publicUrl = pickString$2(config.publicUrl ?? null, aliasRecord, 'public_url') ?? null;
28030
28098
  const directParentUrl = pickString$2(config.directParentUrl ?? null, aliasRecord, 'direct_parent_url') ?? null;
28031
28099
  const hasParentFlag = config.hasParent || Boolean(aliasRecord.has_parent ?? false);
@@ -28035,6 +28103,7 @@
28035
28103
  const nodeMetaStore = await storageProvider.getKeyValueStore(NodeMetaRecord, NODE_META_NAMESPACE);
28036
28104
  const nodeMeta = await nodeMetaStore.get('self');
28037
28105
  const identityPolicy = await resolveNodeIdentityPolicy(identityPolicyConfig ?? null, expressionOptions);
28106
+ const connectionRetryPolicy = await resolveConnectionRetryPolicy(connectionRetryPolicyConfig ?? null, expressionOptions);
28038
28107
  const admissionClient = await resolveAdmissionClient(admissionConfig ?? null, expressionOptions, identityPolicy ?? undefined);
28039
28108
  const hasParent = determineHasParent(hasParentFlag, directParentUrl, admissionClient);
28040
28109
  const replicaStickinessManager = await resolveReplicaStickinessManager(hasParent, requestedLogicals, expressionOptions);
@@ -28103,6 +28172,7 @@
28103
28172
  transportListeners,
28104
28173
  traceEmitter,
28105
28174
  identityPolicy: identityPolicy ?? undefined,
28175
+ connectionRetryPolicy: connectionRetryPolicy ?? undefined,
28106
28176
  };
28107
28177
  }
28108
28178
  async function resolveNodeIdentityPolicy(config, options) {
@@ -28110,7 +28180,18 @@
28110
28180
  return await NodeIdentityPolicyFactory.createNodeIdentityPolicy(config ?? undefined, cloneCreateOptions(options));
28111
28181
  }
28112
28182
  catch (error) {
28113
- logger$Y.warning('node_identity_policy_creation_failed', {
28183
+ logger$Z.warning('node_identity_policy_creation_failed', {
28184
+ error: error instanceof Error ? error.message : String(error),
28185
+ });
28186
+ return null;
28187
+ }
28188
+ }
28189
+ async function resolveConnectionRetryPolicy(config, options) {
28190
+ try {
28191
+ return await ConnectionRetryPolicyFactory.createConnectionRetryPolicy(config ?? undefined, cloneCreateOptions(options));
28192
+ }
28193
+ catch (error) {
28194
+ logger$Z.warning('connection_retry_policy_creation_failed', {
28114
28195
  error: error instanceof Error ? error.message : String(error),
28115
28196
  });
28116
28197
  return null;
@@ -28122,7 +28203,7 @@
28122
28203
  return await StorageProviderFactory.createStorageProvider(config, cloneCreateOptions(options));
28123
28204
  }
28124
28205
  catch (error) {
28125
- logger$Y.warning('storage_provider_creation_failed', {
28206
+ logger$Z.warning('storage_provider_creation_failed', {
28126
28207
  error: error instanceof Error ? error.message : String(error),
28127
28208
  });
28128
28209
  }
@@ -28144,7 +28225,7 @@
28144
28225
  return await AdmissionClientFactory.createAdmissionClient((config ?? null), createOptions);
28145
28226
  }
28146
28227
  catch (error) {
28147
- logger$Y.warning('admission_client_creation_failed', {
28228
+ logger$Z.warning('admission_client_creation_failed', {
28148
28229
  error: error instanceof Error ? error.message : String(error),
28149
28230
  });
28150
28231
  return null;
@@ -28171,7 +28252,7 @@
28171
28252
  return await ReplicaStickinessManagerFactory.createReplicaStickinessManager(undefined, cloneCreateOptions(options));
28172
28253
  }
28173
28254
  catch (error) {
28174
- logger$Y.debug('replica_stickiness_manager_unavailable', { error });
28255
+ logger$Z.debug('replica_stickiness_manager_unavailable', { error });
28175
28256
  return null;
28176
28257
  }
28177
28258
  }
@@ -28180,7 +28261,7 @@
28180
28261
  return await AttachmentKeyValidatorFactory.createAttachmentKeyValidator(config ?? undefined, cloneCreateOptions(options));
28181
28262
  }
28182
28263
  catch (error) {
28183
- logger$Y.warning('attachment_key_validator_creation_failed', {
28264
+ logger$Z.warning('attachment_key_validator_creation_failed', {
28184
28265
  error: error instanceof Error ? error.message : String(error),
28185
28266
  });
28186
28267
  return null;
@@ -28198,7 +28279,7 @@
28198
28279
  return await DeliveryPolicyFactory.createDeliveryPolicy(config ?? undefined, cloneCreateOptions(options));
28199
28280
  }
28200
28281
  catch (error) {
28201
- logger$Y.warning('delivery_policy_creation_failed', {
28282
+ logger$Z.warning('delivery_policy_creation_failed', {
28202
28283
  error: error instanceof Error ? error.message : String(error),
28203
28284
  });
28204
28285
  return null;
@@ -28212,7 +28293,7 @@
28212
28293
  return await TransportListenerFactory.createTransportListeners(configs, eventListeners, cloneCreateOptions(options));
28213
28294
  }
28214
28295
  catch (error) {
28215
- logger$Y.warning('transport_listener_creation_failed', {
28296
+ logger$Z.warning('transport_listener_creation_failed', {
28216
28297
  error: error instanceof Error ? error.message : String(error),
28217
28298
  });
28218
28299
  return [];
@@ -28223,7 +28304,7 @@
28223
28304
  return await TraceEmitterFactory.createTraceEmitter(config ?? undefined, cloneCreateOptions(options));
28224
28305
  }
28225
28306
  catch (error) {
28226
- logger$Y.warning('trace_emitter_creation_failed', {
28307
+ logger$Z.warning('trace_emitter_creation_failed', {
28227
28308
  error: error instanceof Error ? error.message : String(error),
28228
28309
  });
28229
28310
  return null;
@@ -28279,7 +28360,7 @@
28279
28360
  return manager ?? null;
28280
28361
  }
28281
28362
  catch (error) {
28282
- logger$Y.warning('security_manager_creation_failed', {
28363
+ logger$Z.warning('security_manager_creation_failed', {
28283
28364
  error: error instanceof Error ? error.message : String(error),
28284
28365
  });
28285
28366
  return null;
@@ -28308,7 +28389,7 @@
28308
28389
  // This happens with overlay security profiles that need envelope signing
28309
28390
  if (requiresCryptoProvider(config)) {
28310
28391
  try {
28311
- logger$Y.debug('auto_creating_crypto_provider', {
28392
+ logger$Z.debug('auto_creating_crypto_provider', {
28312
28393
  reason: 'overlay_security_requires_signing',
28313
28394
  });
28314
28395
  // Dynamically import to avoid circular dependencies
@@ -28328,7 +28409,7 @@
28328
28409
  });
28329
28410
  }
28330
28411
  catch (error) {
28331
- logger$Y.error('failed_to_auto_create_crypto_provider', {
28412
+ logger$Z.error('failed_to_auto_create_crypto_provider', {
28332
28413
  error: error instanceof Error ? error.message : String(error),
28333
28414
  });
28334
28415
  throw error;
@@ -28871,7 +28952,7 @@
28871
28952
  // registerFactory(NODE_LIKE_FACTORY_BASE_TYPE, type, factory);
28872
28953
  // }
28873
28954
 
28874
- const FACTORY_META$17 = {
28955
+ const FACTORY_META$18 = {
28875
28956
  base: NODE_LIKE_FACTORY_BASE_TYPE,
28876
28957
  key: 'Node',
28877
28958
  };
@@ -28905,6 +28986,7 @@
28905
28986
  nodeMetaStore: components.nodeMetaStore,
28906
28987
  transportListeners: components.transportListeners,
28907
28988
  defaultServiceConfigs: serviceConfigs,
28989
+ connectionRetryPolicy: components.connectionRetryPolicy,
28908
28990
  });
28909
28991
  return node;
28910
28992
  }
@@ -28912,7 +28994,7 @@
28912
28994
 
28913
28995
  var nodeFactory = /*#__PURE__*/Object.freeze({
28914
28996
  __proto__: null,
28915
- FACTORY_META: FACTORY_META$17,
28997
+ FACTORY_META: FACTORY_META$18,
28916
28998
  NodeFactory: NodeFactory,
28917
28999
  default: NodeFactory
28918
29000
  });
@@ -29446,7 +29528,7 @@
29446
29528
  };
29447
29529
  }
29448
29530
 
29449
- const logger$X = getLogger('naylence.fame.node.envelope_security_handler');
29531
+ const logger$Y = getLogger('naylence.fame.node.envelope_security_handler');
29450
29532
  const ENCRYPTION_OPTION_ALIAS_PAIRS = [
29451
29533
  ['recipKid', 'recip_kid'],
29452
29534
  ['recipientKeyId', 'recipient_key_id'],
@@ -29495,7 +29577,7 @@
29495
29577
  const shouldSign = this.securityPolicy
29496
29578
  ? await this.securityPolicy.shouldSignEnvelope(envelope, context, this.node)
29497
29579
  : false;
29498
- logger$X.debug('checking_signing', {
29580
+ logger$Y.debug('checking_signing', {
29499
29581
  has_signer: Boolean(this.envelopeSigner),
29500
29582
  should_sign: shouldSign,
29501
29583
  envp_id: envelope.id,
@@ -29517,7 +29599,7 @@
29517
29599
  const shouldEncrypt = this.securityPolicy
29518
29600
  ? await this.securityPolicy.shouldEncryptEnvelope(envelope, context, this.node)
29519
29601
  : false;
29520
- logger$X.debug('checking_encryption', {
29602
+ logger$Y.debug('checking_encryption', {
29521
29603
  has_encryption_manager: Boolean(this.encryptionManager),
29522
29604
  should_encrypt: shouldEncrypt,
29523
29605
  envp_id: envelope.id,
@@ -29525,7 +29607,7 @@
29525
29607
  });
29526
29608
  if (this.encryptionManager && this.securityPolicy) {
29527
29609
  if (envelope.sec?.enc) {
29528
- logger$X.debug('skipping_encryption_already_encrypted', {
29610
+ logger$Y.debug('skipping_encryption_already_encrypted', {
29529
29611
  envp_id: envelope.id,
29530
29612
  destination: envelope.to ? String(envelope.to) : undefined,
29531
29613
  });
@@ -29538,7 +29620,7 @@
29538
29620
  CryptoLevel.PLAINTEXT;
29539
29621
  desiredCryptoLevel =
29540
29622
  await this.securityPolicy.decideResponseCryptoLevel(requestCryptoLevel, envelope, context);
29541
- logger$X.debug('response_crypto_level_decided', {
29623
+ logger$Y.debug('response_crypto_level_decided', {
29542
29624
  envp_id: envelope.id,
29543
29625
  crypto_level: desiredCryptoLevel,
29544
29626
  destination: envelope.to ? String(envelope.to) : undefined,
@@ -29549,7 +29631,7 @@
29549
29631
  else {
29550
29632
  desiredCryptoLevel =
29551
29633
  await this.securityPolicy.decideOutboundCryptoLevel(envelope, context, this.node);
29552
- logger$X.debug('outbound_crypto_level_decided', {
29634
+ logger$Y.debug('outbound_crypto_level_decided', {
29553
29635
  envp_id: envelope.id,
29554
29636
  frame_type: envelope.frame.type,
29555
29637
  crypto_level: desiredCryptoLevel,
@@ -29557,11 +29639,11 @@
29557
29639
  });
29558
29640
  }
29559
29641
  if (desiredCryptoLevel === CryptoLevel.SEALED) {
29560
- logger$X.debug('applying_sealed_encryption', { envp_id: envelope.id });
29642
+ logger$Y.debug('applying_sealed_encryption', { envp_id: envelope.id });
29561
29643
  return await this.handleSealedEncryption(envelope, context);
29562
29644
  }
29563
29645
  if (desiredCryptoLevel === CryptoLevel.CHANNEL) {
29564
- logger$X.debug('applying_channel_encryption', { envp_id: envelope.id });
29646
+ logger$Y.debug('applying_channel_encryption', { envp_id: envelope.id });
29565
29647
  return await this.handleChannelEncryption(envelope, context);
29566
29648
  }
29567
29649
  }
@@ -29612,7 +29694,7 @@
29612
29694
  frameType === 'KeyAnnounce' ||
29613
29695
  frameType === 'SecureOpen' ||
29614
29696
  frameType === 'SecureAccept') {
29615
- logger$X.error('critical_frame_unsigned_rejected', {
29697
+ logger$Y.error('critical_frame_unsigned_rejected', {
29616
29698
  envp_id: envelope.id,
29617
29699
  frame_type: frameType,
29618
29700
  reason: 'critical_frames_must_be_signed',
@@ -29620,7 +29702,7 @@
29620
29702
  return [envelope, false];
29621
29703
  }
29622
29704
  const action = this.securityPolicy.getUnsignedViolationAction(envelope, context);
29623
- logger$X.warning('unsigned_envelope_violation', {
29705
+ logger$Y.warning('unsigned_envelope_violation', {
29624
29706
  envp_id: envelope.id,
29625
29707
  frame_type: frameType,
29626
29708
  action,
@@ -29632,26 +29714,26 @@
29632
29714
  return [envelope, true];
29633
29715
  }
29634
29716
  async handleChannelHandshakeComplete(channelId, destination) {
29635
- logger$X.debug('channel_handshake_completed', {
29717
+ logger$Y.debug('channel_handshake_completed', {
29636
29718
  channel_id: channelId,
29637
29719
  destination,
29638
29720
  });
29639
29721
  if (this.encryptionManager?.notifyChannelEstablished) {
29640
29722
  await this.encryptionManager.notifyChannelEstablished(channelId);
29641
- logger$X.debug('notified_encryption_manager_channel_ready', {
29723
+ logger$Y.debug('notified_encryption_manager_channel_ready', {
29642
29724
  channel_id: channelId,
29643
29725
  });
29644
29726
  }
29645
29727
  }
29646
29728
  async handleChannelHandshakeFailed(channelId, destination, reason = 'handshake_failed') {
29647
- logger$X.debug('channel_handshake_failed', {
29729
+ logger$Y.debug('channel_handshake_failed', {
29648
29730
  channel_id: channelId,
29649
29731
  destination,
29650
29732
  reason,
29651
29733
  });
29652
29734
  if (this.encryptionManager?.notifyChannelFailed) {
29653
29735
  await this.encryptionManager.notifyChannelFailed(channelId, reason);
29654
- logger$X.debug('notified_encryption_manager_channel_failed', {
29736
+ logger$Y.debug('notified_encryption_manager_channel_failed', {
29655
29737
  channel_id: channelId,
29656
29738
  reason,
29657
29739
  });
@@ -29698,7 +29780,7 @@
29698
29780
  checkPayload: false,
29699
29781
  });
29700
29782
  if (verified) {
29701
- logger$X.debug('envelope_verified', {
29783
+ logger$Y.debug('envelope_verified', {
29702
29784
  envp_id: envelope.id,
29703
29785
  sid: envelope.sid,
29704
29786
  kid,
@@ -29709,7 +29791,7 @@
29709
29791
  }
29710
29792
  this.keyManagementHandler.queuePendingSignedEnvelope(kid, envelope, context);
29711
29793
  await this.keyManagementHandler.maybeRequestSigningKey(kid, context.originType, fromSystemId);
29712
- logger$X.debug('queued_envelope_missing_signing_key', {
29794
+ logger$Y.debug('queued_envelope_missing_signing_key', {
29713
29795
  kid,
29714
29796
  envp_id: envelope.id,
29715
29797
  });
@@ -29717,7 +29799,7 @@
29717
29799
  }
29718
29800
  async handleSealedEncryption(envelope, context) {
29719
29801
  if (!envelope.to) {
29720
- logger$X.warning('sealed_encryption_requested_but_no_destination', {
29802
+ logger$Y.warning('sealed_encryption_requested_but_no_destination', {
29721
29803
  envp_id: envelope.id,
29722
29804
  });
29723
29805
  return true;
@@ -29729,20 +29811,20 @@
29729
29811
  : undefined;
29730
29812
  if (options) {
29731
29813
  if (options.encryptionType === 'channel') {
29732
- logger$X.warning('policy_returned_channel_for_sealed_request', {
29814
+ logger$Y.warning('policy_returned_channel_for_sealed_request', {
29733
29815
  envp_id: envelope.id,
29734
29816
  });
29735
29817
  return await this.handleToBeEncryptedEnvelopeWithOptions(envelope, context, normalizeEncryptionOptions({
29736
29818
  requestAddress: envelope.to,
29737
29819
  }));
29738
29820
  }
29739
- logger$X.debug('using_sealed_encryption_options', {
29821
+ logger$Y.debug('using_sealed_encryption_options', {
29740
29822
  envp_id: envelope.id,
29741
29823
  options,
29742
29824
  });
29743
29825
  return await this.handleToBeEncryptedEnvelopeWithOptions(envelope, context, options);
29744
29826
  }
29745
- logger$X.debug('no_encryption_options_requesting_key', {
29827
+ logger$Y.debug('no_encryption_options_requesting_key', {
29746
29828
  envp_id: envelope.id,
29747
29829
  });
29748
29830
  return await this.handleToBeEncryptedEnvelopeWithOptions(envelope, context, normalizeEncryptionOptions({
@@ -29750,7 +29832,7 @@
29750
29832
  }));
29751
29833
  }
29752
29834
  catch (error) {
29753
- logger$X.debug('sealed_key_lookup_failed_requesting', {
29835
+ logger$Y.debug('sealed_key_lookup_failed_requesting', {
29754
29836
  envp_id: envelope.id,
29755
29837
  error: error instanceof Error ? error.message : String(error),
29756
29838
  });
@@ -29761,7 +29843,7 @@
29761
29843
  }
29762
29844
  async handleChannelEncryption(envelope, context) {
29763
29845
  if (!envelope.to) {
29764
- logger$X.warning('channel_encryption_requested_but_no_destination', {
29846
+ logger$Y.warning('channel_encryption_requested_but_no_destination', {
29765
29847
  envp_id: envelope.id,
29766
29848
  });
29767
29849
  return true;
@@ -29776,13 +29858,13 @@
29776
29858
  return true;
29777
29859
  }
29778
29860
  if (context.originType !== DeliveryOriginType.LOCAL) {
29779
- logger$X.warning('envelope_encryption_rejected_non_local', {
29861
+ logger$Y.warning('envelope_encryption_rejected_non_local', {
29780
29862
  origin: context.originType,
29781
29863
  });
29782
29864
  return true;
29783
29865
  }
29784
29866
  if (!isDataFrame$4(envelope.frame)) {
29785
- logger$X.trace('skipping_encryption_non_dataframe', {
29867
+ logger$Y.trace('skipping_encryption_non_dataframe', {
29786
29868
  envp_id: envelope.id,
29787
29869
  frame_type: envelope.frame.type,
29788
29870
  });
@@ -29793,7 +29875,7 @@
29793
29875
  ? normalizeEncryptionOptions(rawOptions)
29794
29876
  : undefined;
29795
29877
  if (!options) {
29796
- logger$X.warning('no_encryption_options_provided', {
29878
+ logger$Y.warning('no_encryption_options_provided', {
29797
29879
  envp_id: envelope.id,
29798
29880
  });
29799
29881
  return true;
@@ -29805,13 +29887,13 @@
29805
29887
  return true;
29806
29888
  }
29807
29889
  if (context.originType !== DeliveryOriginType.LOCAL) {
29808
- logger$X.warning('envelope_encryption_rejected_non_local', {
29890
+ logger$Y.warning('envelope_encryption_rejected_non_local', {
29809
29891
  origin: context.originType,
29810
29892
  });
29811
29893
  return true;
29812
29894
  }
29813
29895
  if (!isDataFrame$4(envelope.frame)) {
29814
- logger$X.trace('skipping_encryption_non_dataframe', {
29896
+ logger$Y.trace('skipping_encryption_non_dataframe', {
29815
29897
  envp_id: envelope.id,
29816
29898
  frame_type: envelope.frame.type,
29817
29899
  });
@@ -29828,7 +29910,7 @@
29828
29910
  // Skip encryption if envelope is already encrypted
29829
29911
  // This prevents re-queuing when replayed envelopes go through security again
29830
29912
  if (envelope.sec?.enc) {
29831
- logger$X.debug('skipping_encryption_already_encrypted', {
29913
+ logger$Y.debug('skipping_encryption_already_encrypted', {
29832
29914
  envp_id: envelope.id,
29833
29915
  destination: envelope.to ? String(envelope.to) : undefined,
29834
29916
  });
@@ -29837,14 +29919,14 @@
29837
29919
  try {
29838
29920
  const result = await this.encryptionManager.encryptEnvelope(envelope, normalizedOptions);
29839
29921
  if (result.status === EncryptionStatus.QUEUED) {
29840
- logger$X.debug('envelope_queued_for_encryption', {
29922
+ logger$Y.debug('envelope_queued_for_encryption', {
29841
29923
  envp_id: envelope.id,
29842
29924
  });
29843
29925
  await this.handleEncryptionQueueing(envelope, context, normalizedOptions);
29844
29926
  return false;
29845
29927
  }
29846
29928
  if (result.status === EncryptionStatus.OK) {
29847
- logger$X.debug('envelope_encrypted', { envp_id: envelope.id });
29929
+ logger$Y.debug('envelope_encrypted', { envp_id: envelope.id });
29848
29930
  if (result.envelope) {
29849
29931
  envelope.frame = result.envelope.frame;
29850
29932
  envelope.sec = result.envelope.sec;
@@ -29852,17 +29934,17 @@
29852
29934
  return true;
29853
29935
  }
29854
29936
  if (result.status === EncryptionStatus.SKIPPED) {
29855
- logger$X.debug('envelope_encryption_skipped', { envp_id: envelope.id });
29937
+ logger$Y.debug('envelope_encryption_skipped', { envp_id: envelope.id });
29856
29938
  return true;
29857
29939
  }
29858
- logger$X.warning('unknown_encryption_status', {
29940
+ logger$Y.warning('unknown_encryption_status', {
29859
29941
  envp_id: envelope.id,
29860
29942
  status: result.status,
29861
29943
  });
29862
29944
  return true;
29863
29945
  }
29864
29946
  catch (error) {
29865
- logger$X.error('encryption_failed', {
29947
+ logger$Y.error('encryption_failed', {
29866
29948
  envp_id: envelope.id,
29867
29949
  error: error instanceof Error ? error.message : String(error),
29868
29950
  });
@@ -29901,7 +29983,7 @@
29901
29983
  return;
29902
29984
  }
29903
29985
  if (normalizedOptions.encryptionType === 'channel') {
29904
- logger$X.debug('channel_encryption_queueing_handled_internally', {
29986
+ logger$Y.debug('channel_encryption_queueing_handled_internally', {
29905
29987
  envp_id: envelope.id,
29906
29988
  destination: normalizedOptions.destination
29907
29989
  ? String(normalizedOptions.destination)
@@ -29909,13 +29991,13 @@
29909
29991
  });
29910
29992
  return;
29911
29993
  }
29912
- logger$X.warning('unknown_encryption_queueing_options', {
29994
+ logger$Y.warning('unknown_encryption_queueing_options', {
29913
29995
  envp_id: envelope.id,
29914
29996
  options: normalizedOptions,
29915
29997
  });
29916
29998
  }
29917
29999
  async handleFailedChannelEnvelopeCleanup(destination, reason) {
29918
- logger$X.debug('channel_handshake_failure_cleanup_attempted', {
30000
+ logger$Y.debug('channel_handshake_failure_cleanup_attempted', {
29919
30001
  destination,
29920
30002
  reason,
29921
30003
  note: 'envelope_cleanup_handled_by_encryption_manager',
@@ -29926,7 +30008,7 @@
29926
30008
  }
29927
30009
  }
29928
30010
 
29929
- const logger$W = getLogger('naylence.fame.node.secure_channel_frame_handler');
30011
+ const logger$X = getLogger('naylence.fame.node.secure_channel_frame_handler');
29930
30012
  function isPlainRecord$1(value) {
29931
30013
  if (typeof value !== 'object' || value === null) {
29932
30014
  return false;
@@ -30016,7 +30098,7 @@
30016
30098
  assertSecureChannelManager(this.secureChannelManager);
30017
30099
  const frame = envelope.frame;
30018
30100
  assertFrameType(frame, 'SecureOpen');
30019
- logger$W.debug('received_secure_open', {
30101
+ logger$X.debug('received_secure_open', {
30020
30102
  cid: frame.cid,
30021
30103
  algorithm: frame.alg,
30022
30104
  });
@@ -30039,13 +30121,13 @@
30039
30121
  stickySid: envelope.sid ?? undefined,
30040
30122
  expectedResponseType: FameResponseType.NONE,
30041
30123
  };
30042
- logger$W.debug('stickiness_requested_for_channel_encryption', {
30124
+ logger$X.debug('stickiness_requested_for_channel_encryption', {
30043
30125
  cid: frame.cid,
30044
30126
  reason: 'secure_channel_established',
30045
30127
  });
30046
30128
  }
30047
30129
  await this.sendCallback(responseEnvelope, responseContext);
30048
- logger$W.debug('sent_secure_accept', { cid: frame.cid, ok: acceptFrame.ok });
30130
+ logger$X.debug('sent_secure_accept', { cid: frame.cid, ok: acceptFrame.ok });
30049
30131
  if (acceptFrame.ok && this.envelopeSecurityHandler) {
30050
30132
  const destination = extractDestinationFromChannelId(frame.cid);
30051
30133
  if (destination) {
@@ -30057,13 +30139,13 @@
30057
30139
  assertSecureChannelManager(this.secureChannelManager);
30058
30140
  const frame = envelope.frame;
30059
30141
  assertFrameType(frame, 'SecureAccept');
30060
- logger$W.debug('received_secure_accept', { cid: frame.cid, ok: frame.ok });
30142
+ logger$X.debug('received_secure_accept', { cid: frame.cid, ok: frame.ok });
30061
30143
  const success = await this.secureChannelManager.handleAcceptFrame(frame);
30062
30144
  if (!success) {
30063
- logger$W.warning('failed_to_complete_channel', { cid: frame.cid });
30145
+ logger$X.warning('failed_to_complete_channel', { cid: frame.cid });
30064
30146
  }
30065
30147
  else {
30066
- logger$W.debug('channel_established', { cid: frame.cid });
30148
+ logger$X.debug('channel_established', { cid: frame.cid });
30067
30149
  if (this.envelopeSecurityHandler) {
30068
30150
  const destination = extractDestinationFromChannelId(frame.cid);
30069
30151
  if (destination) {
@@ -30075,7 +30157,7 @@
30075
30157
  const destination = extractDestinationFromChannelId(frame.cid);
30076
30158
  if (destination) {
30077
30159
  await this.envelopeSecurityHandler.handleChannelHandshakeFailed(frame.cid, destination, 'negative_secure_accept');
30078
- logger$W.debug('notified_handshake_failure', {
30160
+ logger$X.debug('notified_handshake_failure', {
30079
30161
  cid: frame.cid,
30080
30162
  destination,
30081
30163
  });
@@ -30086,7 +30168,7 @@
30086
30168
  assertSecureChannelManager(this.secureChannelManager);
30087
30169
  const frame = envelope.frame;
30088
30170
  assertFrameType(frame, 'SecureClose');
30089
- logger$W.debug('received_secure_close', {
30171
+ logger$X.debug('received_secure_close', {
30090
30172
  cid: frame.cid,
30091
30173
  reason: frame.reason,
30092
30174
  });
@@ -30110,7 +30192,7 @@
30110
30192
  }).optional(),
30111
30193
  });
30112
30194
 
30113
- const FACTORY_META$16 = {
30195
+ const FACTORY_META$17 = {
30114
30196
  base: NODE_IDENTITY_POLICY_FACTORY_BASE_TYPE,
30115
30197
  key: 'DefaultNodeIdentityPolicy',
30116
30198
  };
@@ -30128,11 +30210,11 @@
30128
30210
  var defaultNodeIdentityPolicyFactory = /*#__PURE__*/Object.freeze({
30129
30211
  __proto__: null,
30130
30212
  DefaultNodeIdentityPolicyFactory: DefaultNodeIdentityPolicyFactory,
30131
- FACTORY_META: FACTORY_META$16,
30213
+ FACTORY_META: FACTORY_META$17,
30132
30214
  default: DefaultNodeIdentityPolicyFactory
30133
30215
  });
30134
30216
 
30135
- const logger$V = getLogger('naylence.fame.node.token_subject_node_identity_policy');
30217
+ const logger$W = getLogger('naylence.fame.node.token_subject_node_identity_policy');
30136
30218
  class TokenSubjectNodeIdentityPolicy {
30137
30219
  async resolveInitialNodeId(context) {
30138
30220
  if (context.configuredId) {
@@ -30144,7 +30226,7 @@
30144
30226
  return generateIdAsync();
30145
30227
  }
30146
30228
  async resolveAdmissionNodeId(context) {
30147
- logger$V.debug('resolve_admission_node_id_start', {
30229
+ logger$W.debug('resolve_admission_node_id_start', {
30148
30230
  grantsCount: context.grants?.length ?? 0,
30149
30231
  currentNodeId: context.currentNodeId,
30150
30232
  });
@@ -30153,31 +30235,31 @@
30153
30235
  try {
30154
30236
  const auth = grant.auth;
30155
30237
  if (!auth) {
30156
- logger$V.debug('skipping_grant_no_auth', { grantType: grant.type });
30238
+ logger$W.debug('skipping_grant_no_auth', { grantType: grant.type });
30157
30239
  continue;
30158
30240
  }
30159
30241
  const tokenProviderConfig = (auth.tokenProvider ??
30160
30242
  auth.token_provider);
30161
30243
  if (!tokenProviderConfig ||
30162
30244
  typeof tokenProviderConfig.type !== 'string') {
30163
- logger$V.debug('skipping_grant_invalid_token_provider_config', {
30245
+ logger$W.debug('skipping_grant_invalid_token_provider_config', {
30164
30246
  grantType: grant.type,
30165
30247
  config: tokenProviderConfig,
30166
30248
  });
30167
30249
  continue;
30168
30250
  }
30169
- logger$V.debug('creating_token_provider', {
30251
+ logger$W.debug('creating_token_provider', {
30170
30252
  type: tokenProviderConfig.type,
30171
30253
  });
30172
30254
  const provider = await TokenProviderFactory.createTokenProvider(tokenProviderConfig);
30173
30255
  const isExposing = isIdentityExposingTokenProvider(provider);
30174
- logger$V.debug('token_provider_created', {
30256
+ logger$W.debug('token_provider_created', {
30175
30257
  type: tokenProviderConfig.type,
30176
30258
  isIdentityExposing: isExposing,
30177
30259
  });
30178
30260
  if (isExposing) {
30179
30261
  const identity = await provider.getIdentity();
30180
- logger$V.debug('retrieved_identity', { identity });
30262
+ logger$W.debug('retrieved_identity', { identity });
30181
30263
  if (identity && identity.subject) {
30182
30264
  const hashedSubject = await generateIdAsync({
30183
30265
  mode: 'fingerprint',
@@ -30185,7 +30267,7 @@
30185
30267
  length: 8,
30186
30268
  });
30187
30269
  const newNodeId = `${hashedSubject}-${context.currentNodeId}`;
30188
- logger$V.info('resolved_identity_from_token', {
30270
+ logger$W.info('resolved_identity_from_token', {
30189
30271
  subject: identity.subject,
30190
30272
  hashedSubject,
30191
30273
  newNodeId,
@@ -30193,17 +30275,17 @@
30193
30275
  return newNodeId;
30194
30276
  }
30195
30277
  else {
30196
- logger$V.debug('identity_missing_subject', { identity });
30278
+ logger$W.debug('identity_missing_subject', { identity });
30197
30279
  }
30198
30280
  }
30199
30281
  }
30200
30282
  catch (err) {
30201
- logger$V.warning('failed_to_extract_identity_from_grant', { error: err });
30283
+ logger$W.warning('failed_to_extract_identity_from_grant', { error: err });
30202
30284
  }
30203
30285
  }
30204
30286
  }
30205
30287
  else {
30206
- logger$V.debug('no_grants_available');
30288
+ logger$W.debug('no_grants_available');
30207
30289
  }
30208
30290
  return context.currentNodeId;
30209
30291
  }
@@ -30214,7 +30296,7 @@
30214
30296
  TokenSubjectNodeIdentityPolicy: TokenSubjectNodeIdentityPolicy
30215
30297
  });
30216
30298
 
30217
- const FACTORY_META$15 = {
30299
+ const FACTORY_META$16 = {
30218
30300
  base: NODE_IDENTITY_POLICY_FACTORY_BASE_TYPE,
30219
30301
  key: 'TokenSubjectNodeIdentityPolicy',
30220
30302
  };
@@ -30233,12 +30315,12 @@
30233
30315
 
30234
30316
  var tokenSubjectNodeIdentityPolicyFactory = /*#__PURE__*/Object.freeze({
30235
30317
  __proto__: null,
30236
- FACTORY_META: FACTORY_META$15,
30318
+ FACTORY_META: FACTORY_META$16,
30237
30319
  TokenSubjectNodeIdentityPolicyFactory: TokenSubjectNodeIdentityPolicyFactory,
30238
30320
  default: TokenSubjectNodeIdentityPolicyFactory
30239
30321
  });
30240
30322
 
30241
- const logger$U = getLogger('naylence.fame.node.node_identity_policy_profile_factory');
30323
+ const logger$V = getLogger('naylence.fame.node.node_identity_policy_profile_factory');
30242
30324
  const PROFILE_NAME_DEFAULT = 'default';
30243
30325
  const PROFILE_NAME_TOKEN_SUBJECT = 'token-subject';
30244
30326
  const PROFILE_NAME_TOKEN_SUBJECT_ALIAS = 'token_subject';
@@ -30253,7 +30335,7 @@
30253
30335
  [PROFILE_NAME_TOKEN_SUBJECT]: TOKEN_SUBJECT_PROFILE,
30254
30336
  [PROFILE_NAME_TOKEN_SUBJECT_ALIAS]: TOKEN_SUBJECT_PROFILE,
30255
30337
  };
30256
- const FACTORY_META$14 = {
30338
+ const FACTORY_META$15 = {
30257
30339
  base: NODE_IDENTITY_POLICY_FACTORY_BASE_TYPE,
30258
30340
  key: 'NodeIdentityPolicyProfile',
30259
30341
  };
@@ -30265,7 +30347,7 @@
30265
30347
  async create(config) {
30266
30348
  const normalized = normalizeConfig$t(config);
30267
30349
  const profileConfig = resolveProfileConfig$4(normalized.profile);
30268
- logger$U.debug('enabling_node_identity_policy_profile', {
30350
+ logger$V.debug('enabling_node_identity_policy_profile', {
30269
30351
  profile: normalized.profile,
30270
30352
  });
30271
30353
  return NodeIdentityPolicyFactory.createNodeIdentityPolicy(profileConfig);
@@ -30301,11 +30383,95 @@
30301
30383
 
30302
30384
  var nodeIdentityPolicyProfileFactory = /*#__PURE__*/Object.freeze({
30303
30385
  __proto__: null,
30304
- FACTORY_META: FACTORY_META$14,
30386
+ FACTORY_META: FACTORY_META$15,
30305
30387
  NodeIdentityPolicyProfileFactory: NodeIdentityPolicyProfileFactory,
30306
30388
  default: NodeIdentityPolicyProfileFactory
30307
30389
  });
30308
30390
 
30391
+ /**
30392
+ * Environment variable for overriding max initial attempts.
30393
+ */
30394
+ const ENV_VAR_SESSION_MAX_INITIAL_ATTEMPTS = 'FAME_SESSION_MAX_INITIAL_ATTEMPTS';
30395
+ /**
30396
+ * Default implementation of connection retry policy.
30397
+ *
30398
+ * Before first successful attach:
30399
+ * - Respects maxInitialAttempts configuration
30400
+ * - Uses exponential backoff with jitter
30401
+ *
30402
+ * After first successful attach:
30403
+ * - Always retries (unlimited) to maintain connection
30404
+ * - Resets backoff if connection was stable for >10 seconds
30405
+ */
30406
+ class DefaultConnectionRetryPolicy {
30407
+ constructor(options = {}) {
30408
+ // Check for environment variable override
30409
+ const envValue = typeof process !== 'undefined'
30410
+ ? process.env?.[ENV_VAR_SESSION_MAX_INITIAL_ATTEMPTS]
30411
+ : undefined;
30412
+ if (envValue !== undefined && envValue !== '') {
30413
+ const parsed = parseInt(envValue, 10);
30414
+ this.maxInitialAttempts = isNaN(parsed) ? (options.maxInitialAttempts ?? 1) : parsed;
30415
+ }
30416
+ else {
30417
+ this.maxInitialAttempts = options.maxInitialAttempts ?? 1;
30418
+ }
30419
+ }
30420
+ shouldRetry(context) {
30421
+ // After first successful attach, always retry to maintain connection
30422
+ if (context.hadSuccessfulAttach) {
30423
+ return true;
30424
+ }
30425
+ // maxInitialAttempts = 0 means unlimited retries
30426
+ if (this.maxInitialAttempts === 0) {
30427
+ return true;
30428
+ }
30429
+ // Fail if we've exceeded the configured max attempts
30430
+ return context.attemptNumber < this.maxInitialAttempts;
30431
+ }
30432
+ calculateRetryDelay(_context, baseDelay) {
30433
+ // Add jitter to prevent thundering herd
30434
+ const jitter = Math.random() * baseDelay;
30435
+ return baseDelay + jitter;
30436
+ }
30437
+ }
30438
+
30439
+ const logger$U = getLogger('naylence.fame.node.default-connection-retry-policy-factory');
30440
+ const FACTORY_META$14 = {
30441
+ base: CONNECTION_RETRY_POLICY_FACTORY_BASE_TYPE,
30442
+ key: 'DefaultConnectionRetryPolicy',
30443
+ };
30444
+ class DefaultConnectionRetryPolicyFactory extends ConnectionRetryPolicyFactory {
30445
+ constructor() {
30446
+ super(...arguments);
30447
+ this.type = 'DefaultConnectionRetryPolicy';
30448
+ this.isDefault = true;
30449
+ }
30450
+ async create(config) {
30451
+ const options = {};
30452
+ if (config) {
30453
+ const rawMax = config.maxInitialAttempts ??
30454
+ config.max_initial_attempts;
30455
+ if (rawMax !== undefined && rawMax !== null) {
30456
+ options.maxInitialAttempts =
30457
+ typeof rawMax === 'string' ? parseInt(rawMax, 10) : Number(rawMax);
30458
+ }
30459
+ }
30460
+ const policy = new DefaultConnectionRetryPolicy(options);
30461
+ logger$U.debug('connection_retry_policy_created', {
30462
+ maxInitialAttempts: policy.maxInitialAttempts,
30463
+ });
30464
+ return policy;
30465
+ }
30466
+ }
30467
+
30468
+ var defaultConnectionRetryPolicyFactory = /*#__PURE__*/Object.freeze({
30469
+ __proto__: null,
30470
+ DefaultConnectionRetryPolicyFactory: DefaultConnectionRetryPolicyFactory,
30471
+ FACTORY_META: FACTORY_META$14,
30472
+ default: DefaultConnectionRetryPolicyFactory
30473
+ });
30474
+
30309
30475
  const LOAD_BALANCER_STICKINESS_MANAGER_FACTORY_BASE_TYPE = 'LoadBalancerStickinessManagerFactory';
30310
30476
  class LoadBalancerStickinessManagerFactory extends AbstractResourceFactory {
30311
30477
  static async createLoadBalancerStickinessManager(config, options = {}) {
@@ -33377,6 +33543,7 @@
33377
33543
  this.maxAttachTtlSec = opts.maxAttachTtlSec ?? null;
33378
33544
  this.requestedLogicals = opts.requestedLogicals ?? [];
33379
33545
  this.attachClient = opts.attachClient ?? null;
33546
+ this.connectionRetryPolicy = opts.connectionRetryPolicy ?? null;
33380
33547
  this.nodeAttachFrameHandler = new NodeAttachFrameHandler({
33381
33548
  routingNode: this,
33382
33549
  routeManager: this.routeManager,
@@ -33926,6 +34093,7 @@
33926
34093
  onAttach: (info, connector) => this.onNodeAttachToPeer(info, connector),
33927
34094
  onEpochChange: (epoch) => this.onEpochChange(epoch),
33928
34095
  onWelcome: async () => undefined,
34096
+ retryPolicy: this.connectionRetryPolicy,
33929
34097
  });
33930
34098
  await sessionManager.start();
33931
34099
  const systemId = sessionManager.systemId;
@@ -55055,12 +55223,12 @@
55055
55223
  });
55056
55224
 
55057
55225
  // This file is auto-generated during build - do not edit manually
55058
- // Generated from package.json version: 0.3.12
55226
+ // Generated from package.json version: 0.3.13
55059
55227
  /**
55060
55228
  * The package version, injected at build time.
55061
55229
  * @internal
55062
55230
  */
55063
- const VERSION$1 = '0.3.12';
55231
+ const VERSION$1 = '0.3.13';
55064
55232
 
55065
55233
  let initialized = false;
55066
55234
  const agentSdkPlugin = {
@@ -55434,6 +55602,20 @@
55434
55602
  return registeredAgentProxyCtor;
55435
55603
  }
55436
55604
 
55605
+ /**
55606
+ * Agent module providing the abstract {@link Agent} class.
55607
+ *
55608
+ * An Agent is a self-contained unit of work that can receive tasks, process them,
55609
+ * and return results. Agents communicate over the Fame fabric using a standard
55610
+ * task-based protocol.
55611
+ *
55612
+ * @remarks
55613
+ * For concrete implementations:
55614
+ * - Use {@link BaseAgent} when you need full control over task handling and state.
55615
+ * - Use {@link BackgroundTaskAgent} for long-running or async background work.
55616
+ *
55617
+ * @module
55618
+ */
55437
55619
  const logger$2 = getLogger('naylence.agent.agent');
55438
55620
  let registeredBaseAgentCtor = null;
55439
55621
  function requireBaseAgentCtor() {
@@ -55446,7 +55628,9 @@
55446
55628
  function registerBaseAgentConstructor(ctor) {
55447
55629
  registeredBaseAgentCtor = ctor;
55448
55630
  }
55631
+ /** @internal */
55449
55632
  const isNodeRuntime = () => typeof process !== 'undefined' && process.release?.name === 'node';
55633
+ /** @internal */
55450
55634
  const LOG_LEVEL_KEYWORDS = {
55451
55635
  critical: LogLevel.CRITICAL,
55452
55636
  error: LogLevel.ERROR,
@@ -55456,6 +55640,7 @@
55456
55640
  debug: LogLevel.DEBUG,
55457
55641
  trace: LogLevel.TRACE,
55458
55642
  };
55643
+ /** @internal */
55459
55644
  function normalizeLogLevel(level) {
55460
55645
  if (typeof level === 'number') {
55461
55646
  if (Object.values(LogLevel).includes(level)) {
@@ -55473,6 +55658,7 @@
55473
55658
  }
55474
55659
  return level;
55475
55660
  }
55661
+ /** @internal */
55476
55662
  class Deferred {
55477
55663
  constructor() {
55478
55664
  this.settled = false;
@@ -55494,6 +55680,7 @@
55494
55680
  this.internalReject(reason);
55495
55681
  }
55496
55682
  }
55683
+ /** @internal */
55497
55684
  async function setupSignalHandlers(stop) {
55498
55685
  if (!isNodeRuntime()) {
55499
55686
  return () => { };
@@ -55518,6 +55705,7 @@
55518
55705
  }
55519
55706
  };
55520
55707
  }
55708
+ /** @internal */
55521
55709
  async function acquireFabric(options) {
55522
55710
  const manageContext = fabricStack.length === 0;
55523
55711
  const fabric = await FameFabric.getOrCreate(options ?? {});
@@ -55539,19 +55727,68 @@
55539
55727
  },
55540
55728
  };
55541
55729
  }
55730
+ /** @internal */
55542
55731
  function toFameAddress$1(value) {
55543
55732
  return value instanceof FameAddress ? value : new FameAddress(String(value));
55544
55733
  }
55734
+ /** @internal */
55545
55735
  function invokeProxyRunTask(proxy, payload, taskId) {
55546
55736
  if (typeof proxy.runTask === 'function') {
55547
55737
  return proxy.runTask(payload, taskId);
55548
55738
  }
55549
55739
  throw new Error('AgentProxy must implement runTask');
55550
55740
  }
55741
+ /**
55742
+ * Abstract base class for all agents.
55743
+ *
55744
+ * Agents are addressable services that handle tasks over the Fame fabric.
55745
+ * This class defines the core protocol methods every agent must implement.
55746
+ *
55747
+ * @remarks
55748
+ * Do not extend Agent directly. Instead:
55749
+ * - Extend {@link BaseAgent} for standard request-response agents.
55750
+ * - Extend {@link BackgroundTaskAgent} for long-running background work.
55751
+ *
55752
+ * Use {@link Agent.remote} or {@link Agent.remoteByAddress} to create proxies
55753
+ * for communicating with remote agents.
55754
+ *
55755
+ * @example
55756
+ * ```typescript
55757
+ * import { BaseAgent, Payload } from '@naylence/agent-sdk';
55758
+ *
55759
+ * class EchoAgent extends BaseAgent {
55760
+ * async runTask(payload: Payload): Promise<Payload> {
55761
+ * return payload;
55762
+ * }
55763
+ * }
55764
+ *
55765
+ * const agent = new EchoAgent('echo');
55766
+ * await agent.serve('fame://echo');
55767
+ * ```
55768
+ */
55551
55769
  class Agent extends RpcMixin {
55770
+ /**
55771
+ * Capabilities advertised by this agent for discovery.
55772
+ */
55552
55773
  get capabilities() {
55553
55774
  return undefined;
55554
55775
  }
55776
+ /**
55777
+ * Creates a proxy for communicating with a remote agent.
55778
+ *
55779
+ * @remarks
55780
+ * Provide exactly one of `address` or `capabilities` in the options.
55781
+ *
55782
+ * @example
55783
+ * ```typescript
55784
+ * const proxy = Agent.remote<EchoAgent>({ address: 'fame://echo' });
55785
+ * const result = await proxy.runTask('hello');
55786
+ * ```
55787
+ *
55788
+ * @param options - Remote agent options.
55789
+ * @returns A proxy for the remote agent.
55790
+ * @throws Error if both or neither of address/capabilities are provided.
55791
+ */
55555
55792
  static remote(options) {
55556
55793
  const { address, capabilities, fabric } = options;
55557
55794
  const selected = Number(address != null) + Number(capabilities != null);
@@ -55568,6 +55805,13 @@
55568
55805
  fabric: resolvedFabric,
55569
55806
  });
55570
55807
  }
55808
+ /**
55809
+ * Creates a proxy for a remote agent by its address.
55810
+ *
55811
+ * @param address - The target agent's address.
55812
+ * @param options - Optional fabric configuration.
55813
+ * @returns A proxy for the remote agent.
55814
+ */
55571
55815
  static remoteByAddress(address, options = {}) {
55572
55816
  const remoteOptions = { address };
55573
55817
  if (options.fabric !== undefined) {
@@ -55575,6 +55819,13 @@
55575
55819
  }
55576
55820
  return this.remote(remoteOptions);
55577
55821
  }
55822
+ /**
55823
+ * Creates a proxy for a remote agent by required capabilities.
55824
+ *
55825
+ * @param capabilities - Required capabilities for discovery.
55826
+ * @param options - Optional fabric configuration.
55827
+ * @returns A proxy for a matching remote agent.
55828
+ */
55578
55829
  static remoteByCapabilities(capabilities, options = {}) {
55579
55830
  const remoteOptions = { capabilities };
55580
55831
  if (options.fabric !== undefined) {
@@ -55582,6 +55833,15 @@
55582
55833
  }
55583
55834
  return this.remote(remoteOptions);
55584
55835
  }
55836
+ /**
55837
+ * Creates an agent from a simple handler function.
55838
+ *
55839
+ * @remarks
55840
+ * Useful for quick prototyping without defining a full agent class.
55841
+ *
55842
+ * @param handler - Function that processes task payloads.
55843
+ * @returns A new agent instance wrapping the handler.
55844
+ */
55585
55845
  static async fromHandler(handler) {
55586
55846
  if (!registeredBaseAgentCtor) {
55587
55847
  await Promise.resolve().then(function () { return baseAgent; });
@@ -55598,10 +55858,25 @@
55598
55858
  }
55599
55859
  return new HandlerAgent();
55600
55860
  }
55861
+ /**
55862
+ * Sends the same payload to multiple agents.
55863
+ *
55864
+ * @param addresses - List of agent addresses.
55865
+ * @param payload - Payload to send to all agents.
55866
+ * @param options - Execution options.
55867
+ * @returns Array of [address, result|error] tuples.
55868
+ */
55601
55869
  static async broadcast(addresses, payload = null, options = {}) {
55602
55870
  const targets = addresses.map((address) => [address, payload]);
55603
55871
  return this.runMany(targets, options);
55604
55872
  }
55873
+ /**
55874
+ * Runs tasks on multiple agents with individual payloads.
55875
+ *
55876
+ * @param targets - Iterable of [address, payload] pairs.
55877
+ * @param options - Execution options.
55878
+ * @returns Array of [address, result|error] tuples.
55879
+ */
55605
55880
  static async runMany(targets, options = {}) {
55606
55881
  const { fabric, gatherExceptions = true } = options;
55607
55882
  const resolvedFabric = fabric ?? FameFabric.current();
@@ -55637,6 +55912,16 @@
55637
55912
  return [addressKey, result.reason];
55638
55913
  });
55639
55914
  }
55915
+ /**
55916
+ * Starts serving this agent at the given address.
55917
+ *
55918
+ * @remarks
55919
+ * In Node.js, the agent listens for SIGINT/SIGTERM to shut down gracefully.
55920
+ * The method returns when the agent stops serving.
55921
+ *
55922
+ * @param address - The address to serve at (e.g., 'fame://my-agent').
55923
+ * @param options - Serve options including log level and fabric config.
55924
+ */
55640
55925
  async aserve(address, options = {}) {
55641
55926
  // Extract logLevel, pass everything else to fabric
55642
55927
  const { logLevel = null, ...fabricOptions } = options;
@@ -55665,6 +55950,12 @@
55665
55950
  await release();
55666
55951
  }
55667
55952
  }
55953
+ /**
55954
+ * Alias for {@link Agent.aserve}.
55955
+ *
55956
+ * @param address - The address to serve at.
55957
+ * @param options - Serve options.
55958
+ */
55668
55959
  serve(address, options = {}) {
55669
55960
  return this.aserve(address, options);
55670
55961
  }
@@ -56098,6 +56389,7 @@
56098
56389
 
56099
56390
  var _BaseAgent_instances, _BaseAgent_createTaskFromPayloadResponse;
56100
56391
  const logger$1 = getLogger('naylence.agent.base_agent');
56392
+ /** @internal */
56101
56393
  class StateContext {
56102
56394
  constructor(acquireLock, loadState, saveState) {
56103
56395
  this.acquireLock = acquireLock;
@@ -56329,17 +56621,20 @@
56329
56621
  * ```
56330
56622
  */
56331
56623
  BaseAgentState.schema = object({});
56624
+ /** @internal */
56332
56625
  function camelToSnakeCase(name) {
56333
56626
  return name
56334
56627
  .replace(/([a-z0-9])([A-Z])/g, '$1_$2')
56335
56628
  .replace(/([A-Z])([A-Z][a-z])/g, '$1_$2')
56336
56629
  .toLowerCase();
56337
56630
  }
56631
+ /** @internal */
56338
56632
  function sanitizeNamespace(ns) {
56339
56633
  const replaced = ns.replace(/[^A-Za-z0-9._-]+/g, '_').replace(/^[._-]+|[._-]+$/g, '');
56340
56634
  const safe = replaced.length > 0 ? replaced : 'ns';
56341
56635
  return safe.slice(0, 120);
56342
56636
  }
56637
+ /** @internal */
56343
56638
  async function delay$1(ms) {
56344
56639
  await new Promise((resolve) => {
56345
56640
  const timeout = globalThis.setTimeout;
@@ -56349,19 +56644,71 @@
56349
56644
  timeout(resolve, ms);
56350
56645
  });
56351
56646
  }
56647
+ /** @internal */
56352
56648
  function resolveRpcParams(params) {
56353
56649
  if (params && typeof params === 'object') {
56354
56650
  return params;
56355
56651
  }
56356
56652
  return {};
56357
56653
  }
56654
+ /** @internal */
56358
56655
  function resolveReplyTarget(explicit, params) {
56359
56656
  const fromParams = params['reply_to'] ??
56360
56657
  params['replyTo'];
56361
56658
  const resolved = explicit ?? fromParams ?? null;
56362
56659
  return resolved === undefined ? null : resolved;
56363
56660
  }
56661
+ /**
56662
+ * Standard implementation of the {@link Agent} protocol.
56663
+ *
56664
+ * Provides built-in state management, message handling, and task lifecycle support.
56665
+ * Extend this class and override {@link BaseAgent.runTask} to implement your agent logic.
56666
+ *
56667
+ * @remarks
56668
+ * BaseAgent handles:
56669
+ * - JSON-RPC message routing
56670
+ * - State persistence with optional Zod validation
56671
+ * - Task creation from runTask results
56672
+ * - Graceful shutdown via SIGINT/SIGTERM
56673
+ *
56674
+ * For background/async task execution, use {@link BackgroundTaskAgent} instead.
56675
+ *
56676
+ * @example
56677
+ * ```typescript
56678
+ * import { BaseAgent, Payload, BaseAgentState } from '@naylence/agent-sdk';
56679
+ * import { z } from 'zod';
56680
+ *
56681
+ * const CounterSchema = z.object({ count: z.number() });
56682
+ *
56683
+ * class CounterState extends BaseAgentState {
56684
+ * static readonly schema = CounterSchema;
56685
+ * count = 0;
56686
+ * }
56687
+ *
56688
+ * class CounterAgent extends BaseAgent<CounterState> {
56689
+ * static STATE_MODEL = CounterState;
56690
+ *
56691
+ * async runTask(payload: Payload): Promise<number> {
56692
+ * return await this.withState(async (state) => {
56693
+ * state.count += 1;
56694
+ * return state.count;
56695
+ * });
56696
+ * }
56697
+ * }
56698
+ *
56699
+ * const agent = new CounterAgent('counter');
56700
+ * await agent.serve('fame://counter');
56701
+ * ```
56702
+ *
56703
+ * @typeParam StateT - The state model type, defaults to {@link BaseAgentState}.
56704
+ */
56364
56705
  class BaseAgent extends Agent {
56706
+ /**
56707
+ * Creates a new BaseAgent.
56708
+ *
56709
+ * @param name - Agent name. Defaults to snake_case of the class name.
56710
+ * @param options - Configuration options for state and storage.
56711
+ */
56365
56712
  constructor(name = null, options = {}) {
56366
56713
  super();
56367
56714
  _BaseAgent_instances.add(this);
@@ -56382,9 +56729,14 @@
56382
56729
  this._stateKey = options.stateKey ?? 'state';
56383
56730
  this._stateFactory = options.stateFactory ?? null;
56384
56731
  }
56732
+ /**
56733
+ * Capabilities advertised by this agent.
56734
+ * Includes the standard agent capability by default.
56735
+ */
56385
56736
  get capabilities() {
56386
56737
  return [...this._capabilities];
56387
56738
  }
56739
+ /** The agent's name. */
56388
56740
  get name() {
56389
56741
  return this._name;
56390
56742
  }
@@ -56393,12 +56745,18 @@
56393
56745
  address: this._address?.toString() ?? null,
56394
56746
  };
56395
56747
  }
56748
+ /** The address this agent is registered at. */
56396
56749
  get address() {
56397
56750
  return this._address;
56398
56751
  }
56752
+ /** @internal */
56399
56753
  set address(value) {
56400
56754
  this._address = value;
56401
56755
  }
56756
+ /**
56757
+ * Storage provider for state persistence.
56758
+ * @throws Error if no storage provider is available.
56759
+ */
56402
56760
  get storageProvider() {
56403
56761
  if (!this._storageProvider) {
56404
56762
  if (this._node) {
@@ -56423,6 +56781,7 @@
56423
56781
  // Look up the fabric from the registry (set by InProcessFameFabric.start())
56424
56782
  this._fabric = getFabricForNode(node) ?? null;
56425
56783
  }
56784
+ /** @internal */
56426
56785
  async acquireStateLock() {
56427
56786
  let acquiredResolve;
56428
56787
  const acquired = new Promise((resolve) => {
@@ -56449,12 +56808,14 @@
56449
56808
  });
56450
56809
  };
56451
56810
  }
56811
+ /** @internal */
56452
56812
  ensureStateModel() {
56453
56813
  if (this._stateModel) {
56454
56814
  return this._stateModel;
56455
56815
  }
56456
56816
  throw new Error("No state model configured. Provide via Generic, STATE_MODEL, constructor 'stateModel', or 'stateFactory'.");
56457
56817
  }
56818
+ /** @internal */
56458
56819
  async ensureStateStore(modelType) {
56459
56820
  if (this._stateStore) {
56460
56821
  return;
@@ -56467,12 +56828,14 @@
56467
56828
  const namespace = sanitizeNamespace(namespaceRaw);
56468
56829
  this._stateStore = await provider.getKeyValueStore(modelType, namespace);
56469
56830
  }
56831
+ /** @internal */
56470
56832
  defaultStateNamespace() {
56471
56833
  if (!this._name) {
56472
56834
  throw new Error("Cannot derive default state namespace without agent name. Set 'name' or provide 'stateNamespace'.");
56473
56835
  }
56474
56836
  return `__agent_${this._name}`;
56475
56837
  }
56838
+ /** @internal */
56476
56839
  async loadStateInternal() {
56477
56840
  if (this._stateCache) {
56478
56841
  return this._stateCache;
@@ -56502,6 +56865,7 @@
56502
56865
  this._stateCache = state;
56503
56866
  return state;
56504
56867
  }
56868
+ /** @internal */
56505
56869
  async saveStateInternal(state) {
56506
56870
  const modelType = this.ensureStateModel();
56507
56871
  await this.ensureStateStore(modelType);
@@ -56513,15 +56877,45 @@
56513
56877
  await this._stateStore.set(this._stateKey, state);
56514
56878
  this._stateCache = state;
56515
56879
  }
56880
+ /**
56881
+ * State context for lock-protected state access.
56882
+ *
56883
+ * @remarks
56884
+ * Prefer using {@link BaseAgent.withState} for simpler access patterns.
56885
+ *
56886
+ * @throws Error if no state model is configured.
56887
+ */
56516
56888
  get state() {
56517
56889
  if (!this._stateModel && !this._stateFactory) {
56518
56890
  throw new Error('No state model configured');
56519
56891
  }
56520
56892
  return new StateContext(() => this.acquireStateLock(), () => this.loadStateInternal(), (state) => this.saveStateInternal(state));
56521
56893
  }
56894
+ /**
56895
+ * Executes a callback with exclusive access to the agent's state.
56896
+ *
56897
+ * State changes are automatically persisted after the callback completes.
56898
+ *
56899
+ * @param callback - Function receiving the current state.
56900
+ * @returns The callback's return value.
56901
+ *
56902
+ * @example
56903
+ * ```typescript
56904
+ * const count = await this.withState(async (state) => {
56905
+ * state.count += 1;
56906
+ * return state.count;
56907
+ * });
56908
+ * ```
56909
+ */
56522
56910
  async withState(callback) {
56523
56911
  return await this.state.use(callback);
56524
56912
  }
56913
+ /**
56914
+ * Retrieves a snapshot of the current state.
56915
+ *
56916
+ * @remarks
56917
+ * Returns a point-in-time copy. For modifications, use {@link BaseAgent.withState}.
56918
+ */
56525
56919
  async getState() {
56526
56920
  const release = await this.acquireStateLock();
56527
56921
  try {
@@ -56531,6 +56925,9 @@
56531
56925
  release();
56532
56926
  }
56533
56927
  }
56928
+ /**
56929
+ * Deletes all persisted state for this agent.
56930
+ */
56534
56931
  async clearState() {
56535
56932
  const release = await this.acquireStateLock();
56536
56933
  try {
@@ -56543,6 +56940,7 @@
56543
56940
  release();
56544
56941
  }
56545
56942
  }
56943
+ /** @internal */
56546
56944
  static isRpcRequest(payload) {
56547
56945
  if (!payload || typeof payload !== 'object') {
56548
56946
  return false;
@@ -56557,6 +56955,7 @@
56557
56955
  }
56558
56956
  return true;
56559
56957
  }
56958
+ /** @internal */
56560
56959
  async handleMessage(envelope, _context) {
56561
56960
  const frame = envelope.frame;
56562
56961
  if (frame.type === 'DeliveryAck') {
@@ -56579,10 +56978,20 @@
56579
56978
  }
56580
56979
  return await this.handleRpcMessage(decoded, envelope);
56581
56980
  }
56981
+ /**
56982
+ * Override to handle non-RPC messages.
56983
+ *
56984
+ * Called when the agent receives a message that is not a JSON-RPC request.
56985
+ * The default implementation logs a warning and returns null.
56986
+ *
56987
+ * @param message - The decoded message payload.
56988
+ * @returns Optional response to send back.
56989
+ */
56582
56990
  async onMessage(message) {
56583
56991
  logger$1.warning('unhandled_inbound_message', { message });
56584
56992
  return null;
56585
56993
  }
56994
+ /** @internal */
56586
56995
  async handleRpcMessage(rpcRequest, envelope) {
56587
56996
  if (rpcRequest.method === 'tasks/sendSubscribe') {
56588
56997
  this.startSubscriptionTask(rpcRequest, envelope.replyTo ?? null);
@@ -56619,6 +57028,7 @@
56619
57028
  }.bind(this);
56620
57029
  return generator();
56621
57030
  }
57031
+ /** @internal */
56622
57032
  startSubscriptionTask(rpcRequest, replyTo) {
56623
57033
  const id = rpcRequest.id != null ? String(rpcRequest.id) : null;
56624
57034
  if (!id) {
@@ -56643,6 +57053,7 @@
56643
57053
  });
56644
57054
  }
56645
57055
  }
57056
+ /** @internal */
56646
57057
  async streamSendSubscribe(rpcRequest, replyTo, signal) {
56647
57058
  try {
56648
57059
  const params = resolveRpcParams(rpcRequest.params);
@@ -56728,9 +57139,40 @@
56728
57139
  async getTaskStatus(_params) {
56729
57140
  throw new UnsupportedOperationException(`Agent ${this.constructor.name} does not support operation 'getTaskStatus'`);
56730
57141
  }
57142
+ /**
57143
+ * Override to implement task execution logic.
57144
+ *
57145
+ * This is the primary extension point for agent behavior. Return the task result
57146
+ * or throw an error to fail the task.
57147
+ *
57148
+ * @param _payload - The task payload.
57149
+ * @param _id - Optional task identifier.
57150
+ * @returns The task result.
57151
+ * @throws UnsupportedOperationException if not overridden.
57152
+ *
57153
+ * @example
57154
+ * ```typescript
57155
+ * async runTask(payload: Payload): Promise<string> {
57156
+ * const input = typeof payload === 'string' ? payload : '';
57157
+ * return `Hello, ${input}!`;
57158
+ * }
57159
+ * ```
57160
+ */
56731
57161
  async runTask(_payload, _id) {
56732
57162
  throw new UnsupportedOperationException(`Agent ${this.constructor.name} does not support operation 'runTask'`);
56733
57163
  }
57164
+ /**
57165
+ * Initiates a task and returns its status.
57166
+ *
57167
+ * @remarks
57168
+ * If you override {@link BaseAgent.runTask}, this method automatically
57169
+ * creates a Task from the result. Override this method for custom
57170
+ * task lifecycle management.
57171
+ *
57172
+ * @param params - Task parameters including message and metadata.
57173
+ * @returns The completed task with result.
57174
+ * @throws Error if neither startTask nor runTask is implemented.
57175
+ */
56734
57176
  async startTask(params) {
56735
57177
  const ctor = this.constructor;
56736
57178
  const parts = params.message?.parts ?? [];
@@ -56758,7 +57200,9 @@
56758
57200
  await super.aserve(address, options);
56759
57201
  }
56760
57202
  }
56761
- _BaseAgent_instances = new WeakSet(), _BaseAgent_createTaskFromPayloadResponse = async function _BaseAgent_createTaskFromPayloadResponse(params, payload, runner) {
57203
+ _BaseAgent_instances = new WeakSet(), _BaseAgent_createTaskFromPayloadResponse =
57204
+ /** @internal */
57205
+ async function _BaseAgent_createTaskFromPayloadResponse(params, payload, runner) {
56762
57206
  const responsePayload = await runner(payload, params.id ?? null);
56763
57207
  let sanitizedPayload = null;
56764
57208
  if (typeof responsePayload === 'string') {
@@ -56774,6 +57218,10 @@
56774
57218
  sessionId: params.sessionId ?? null,
56775
57219
  });
56776
57220
  };
57221
+ /**
57222
+ * Default state model class. Override in subclasses to set state type.
57223
+ * @internal
57224
+ */
56777
57225
  BaseAgent.STATE_MODEL = null;
56778
57226
  registerBaseAgentConstructor(BaseAgent);
56779
57227
 
@@ -56784,8 +57232,27 @@
56784
57232
  TERMINAL_TASK_STATES: TERMINAL_TASK_STATES
56785
57233
  });
56786
57234
 
57235
+ /**
57236
+ * Agent base for running background work (polling/cron-like).
57237
+ *
57238
+ * {@link BackgroundTaskAgent} extends {@link BaseAgent} with infrastructure for
57239
+ * long-running, asynchronous task execution. Tasks run in the background after
57240
+ * being started, with status updates streamed to subscribers.
57241
+ *
57242
+ * @remarks
57243
+ * Use BackgroundTaskAgent when:
57244
+ * - Task execution takes significant time (seconds to minutes)
57245
+ * - You need to report progress updates during execution
57246
+ * - Clients should not block waiting for completion
57247
+ *
57248
+ * For simple request-response patterns, use {@link BaseAgent} instead.
57249
+ *
57250
+ * @module
57251
+ */
56787
57252
  const logger = getLogger('naylence.agent.background_task_agent');
57253
+ /** @internal */
56788
57254
  const DEFAULT_EVENT_QUEUE_SIZE = 1000;
57255
+ /** @internal */
56789
57256
  const END_OF_STREAM_SENTINEL = Object.freeze({
56790
57257
  id: '__sentinel__',
56791
57258
  status: {
@@ -56796,13 +57263,16 @@
56796
57263
  final: false,
56797
57264
  metadata: null,
56798
57265
  });
57266
+ /** @internal */
56799
57267
  const TIMEOUT_SYMBOL = Symbol('background-task-queue-timeout');
57268
+ /** @internal */
56800
57269
  function monotonicSeconds() {
56801
57270
  if (typeof performance !== 'undefined' && typeof performance.now === 'function') {
56802
57271
  return performance.now() / 1000;
56803
57272
  }
56804
57273
  return Date.now() / 1000;
56805
57274
  }
57275
+ /** @internal */
56806
57276
  async function delay(ms) {
56807
57277
  await new Promise((resolve) => {
56808
57278
  const timeout = globalThis.setTimeout;
@@ -56812,6 +57282,7 @@
56812
57282
  timeout(resolve, ms);
56813
57283
  });
56814
57284
  }
57285
+ /** @internal */
56815
57286
  class AsyncEventQueue {
56816
57287
  constructor(maxSize) {
56817
57288
  this.maxSize = maxSize;
@@ -56854,6 +57325,7 @@
56854
57325
  }
56855
57326
  }
56856
57327
  }
57328
+ /** @internal */
56857
57329
  function createTaskFromStatus(id, status) {
56858
57330
  return {
56859
57331
  id,
@@ -56864,6 +57336,7 @@
56864
57336
  metadata: null,
56865
57337
  };
56866
57338
  }
57339
+ /** @internal */
56867
57340
  function errorToString(error) {
56868
57341
  if (error instanceof Error) {
56869
57342
  return error.message || error.toString();
@@ -56878,19 +57351,75 @@
56878
57351
  return String(error);
56879
57352
  }
56880
57353
  }
57354
+ /**
57355
+ * Base class for agents that execute long-running background tasks.
57356
+ *
57357
+ * Unlike {@link BaseAgent} which runs tasks synchronously in startTask,
57358
+ * BackgroundTaskAgent starts tasks in the background and streams status
57359
+ * updates to subscribers. This is ideal for work that takes significant time.
57360
+ *
57361
+ * @remarks
57362
+ * Lifecycle:
57363
+ * 1. Client calls startTask, which returns immediately with WORKING status
57364
+ * 2. runBackgroundTask executes asynchronously
57365
+ * 3. Status updates are queued and delivered to subscribers
57366
+ * 4. Task completes with COMPLETED, FAILED, or CANCELED status
57367
+ *
57368
+ * Completed tasks are cached briefly for late subscribers to retrieve final status.
57369
+ *
57370
+ * @example
57371
+ * ```typescript
57372
+ * import {
57373
+ * BackgroundTaskAgent,
57374
+ * TaskSendParams,
57375
+ * TaskState,
57376
+ * } from '@naylence/agent-sdk';
57377
+ *
57378
+ * class SlowAgent extends BackgroundTaskAgent {
57379
+ * protected async runBackgroundTask(params: TaskSendParams): Promise<string> {
57380
+ * // Report progress
57381
+ * await this.updateTaskState(params.id, TaskState.WORKING);
57382
+ *
57383
+ * // Do expensive work
57384
+ * await someSlowOperation();
57385
+ *
57386
+ * // Return value becomes the task result
57387
+ * return 'done';
57388
+ * }
57389
+ * }
57390
+ *
57391
+ * const agent = new SlowAgent('slow-worker', {
57392
+ * maxTaskLifetimeMs: 60_000, // 1 minute timeout
57393
+ * });
57394
+ * await agent.serve('fame://slow-worker');
57395
+ * ```
57396
+ *
57397
+ * @typeParam StateT - The state model type, defaults to {@link BaseAgentState}.
57398
+ */
56881
57399
  class BackgroundTaskAgent extends BaseAgent {
57400
+ /**
57401
+ * Creates a new BackgroundTaskAgent.
57402
+ *
57403
+ * @param name - Agent name. Defaults to snake_case of the class name.
57404
+ * @param options - Configuration options for task execution and caching.
57405
+ */
56882
57406
  constructor(name = null, options = {}) {
56883
57407
  const { maxQueueSize = DEFAULT_EVENT_QUEUE_SIZE, maxTaskLifetimeMs = null, completedCacheSize = 100, completedCacheTtlSec = 300, ...baseOptions } = options;
56884
57408
  super(name, baseOptions);
57409
+ /** @internal */
56885
57410
  this.taskStatuses = new Map();
57411
+ /** @internal */
56886
57412
  this.taskEventQueues = new Map();
57413
+ /** @internal */
56887
57414
  this.completed = new Map();
57415
+ /** @internal */
56888
57416
  this.statusLock = new AsyncLock();
56889
57417
  this.maxQueueSize = maxQueueSize;
56890
57418
  this.maxTaskLifetimeMs = maxTaskLifetimeMs;
56891
57419
  this.completedCacheSize = completedCacheSize;
56892
57420
  this.completedCacheTtlSec = completedCacheTtlSec;
56893
57421
  }
57422
+ /** @internal */
56894
57423
  isTerminalTaskState(taskId) {
56895
57424
  const status = this.taskStatuses.get(taskId);
56896
57425
  if (status && TERMINAL_TASK_STATES.has(status.state)) {
@@ -56898,6 +57427,15 @@
56898
57427
  }
56899
57428
  return this.completed.has(taskId);
56900
57429
  }
57430
+ /**
57431
+ * Starts a background task.
57432
+ *
57433
+ * Returns immediately with WORKING status. The task executes asynchronously
57434
+ * via {@link BackgroundTaskAgent.runBackgroundTask}.
57435
+ *
57436
+ * @param params - Task parameters.
57437
+ * @returns The task with initial WORKING status.
57438
+ */
56901
57439
  async startTask(params) {
56902
57440
  this.taskEventQueues.set(params.id, new AsyncEventQueue(this.maxQueueSize));
56903
57441
  await this.updateTaskState(params.id, exports.TaskState.WORKING);
@@ -56907,6 +57445,7 @@
56907
57445
  }
56908
57446
  return await this.getTaskStatus({ id: params.id });
56909
57447
  }
57448
+ /** @internal */
56910
57449
  async enforceMaxLifetime(taskId) {
56911
57450
  if (this.maxTaskLifetimeMs === null) {
56912
57451
  return;
@@ -56920,6 +57459,7 @@
56920
57459
  await queue.put(END_OF_STREAM_SENTINEL);
56921
57460
  }
56922
57461
  }
57462
+ /** @internal */
56923
57463
  async runBackgroundTaskInternal(params) {
56924
57464
  try {
56925
57465
  const result = await this.runBackgroundTask(params);
@@ -56942,6 +57482,12 @@
56942
57482
  }
56943
57483
  }
56944
57484
  }
57485
+ /**
57486
+ * Gets the current state of a task.
57487
+ *
57488
+ * @param taskId - The task identifier.
57489
+ * @returns The current task state, or UNKNOWN if not found.
57490
+ */
56945
57491
  async getTaskState(taskId) {
56946
57492
  try {
56947
57493
  const task = await this.getTaskStatus({ id: taskId });
@@ -56951,6 +57497,13 @@
56951
57497
  return exports.TaskState.UNKNOWN;
56952
57498
  }
56953
57499
  }
57500
+ /**
57501
+ * Retrieves the full status of a task.
57502
+ *
57503
+ * @param params - Query parameters including the task ID.
57504
+ * @returns The task with current status.
57505
+ * @throws Error if the task is unknown or expired.
57506
+ */
56954
57507
  async getTaskStatus(params) {
56955
57508
  return await this.statusLock.runExclusive(async () => {
56956
57509
  const status = this.taskStatuses.get(params.id);
@@ -56967,6 +57520,17 @@
56967
57520
  throw new Error(`Unknown or expired task ${params.id}`);
56968
57521
  });
56969
57522
  }
57523
+ /**
57524
+ * Updates the state of a running task.
57525
+ *
57526
+ * Call this from {@link BackgroundTaskAgent.runBackgroundTask} to report progress.
57527
+ * Status updates are delivered to subscribers.
57528
+ *
57529
+ * @param taskId - The task identifier.
57530
+ * @param state - The new task state.
57531
+ * @param message - Optional message with details.
57532
+ * @returns True if the update was applied, false if the task is already terminal.
57533
+ */
56970
57534
  async updateTaskState(taskId, state, message) {
56971
57535
  return await this.statusLock.runExclusive(async () => {
56972
57536
  if (this.isTerminalTaskState(taskId)) {
@@ -56998,6 +57562,7 @@
56998
57562
  return true;
56999
57563
  });
57000
57564
  }
57565
+ /** @internal */
57001
57566
  addToCompleted(taskId, status) {
57002
57567
  if (this.completedCacheSize <= 0) {
57003
57568
  return;
@@ -57017,6 +57582,14 @@
57017
57582
  timestamp: monotonicSeconds(),
57018
57583
  });
57019
57584
  }
57585
+ /**
57586
+ * Emits an artifact for a running task.
57587
+ *
57588
+ * Artifacts are delivered to subscribers as TaskArtifactUpdateEvents.
57589
+ *
57590
+ * @param taskId - The task identifier.
57591
+ * @param artifact - The artifact to emit.
57592
+ */
57020
57593
  async updateTaskArtifact(taskId, artifact) {
57021
57594
  const queue = this.taskEventQueues.get(taskId);
57022
57595
  if (!queue) {
@@ -57030,6 +57603,15 @@
57030
57603
  };
57031
57604
  await queue.put(event);
57032
57605
  }
57606
+ /**
57607
+ * Subscribes to updates for a task.
57608
+ *
57609
+ * Returns an async iterable that yields status and artifact events.
57610
+ * For completed tasks, yields the cached final status if still available.
57611
+ *
57612
+ * @param params - Task parameters including the task ID.
57613
+ * @returns Async iterable of task events.
57614
+ */
57033
57615
  subscribeToTaskUpdates(params) {
57034
57616
  const queue = this.taskEventQueues.get(params.id);
57035
57617
  const self = this;
@@ -57073,6 +57655,11 @@
57073
57655
  };
57074
57656
  return stream();
57075
57657
  }
57658
+ /**
57659
+ * Cancels a task subscription.
57660
+ *
57661
+ * @param params - Parameters including the task ID.
57662
+ */
57076
57663
  async unsubscribeTask(params) {
57077
57664
  const queue = this.taskEventQueues.get(params.id);
57078
57665
  if (queue) {
@@ -57080,15 +57667,26 @@
57080
57667
  await queue.put(END_OF_STREAM_SENTINEL);
57081
57668
  }
57082
57669
  }
57670
+ /**
57671
+ * Cancels a running task.
57672
+ *
57673
+ * Sets the task state to CANCELED. Does not interrupt runBackgroundTask,
57674
+ * but prevents further state updates.
57675
+ *
57676
+ * @param params - Parameters including the task ID.
57677
+ * @returns The task with CANCELED status.
57678
+ */
57083
57679
  async cancelTask(params) {
57084
57680
  await this.updateTaskState(params.id, exports.TaskState.CANCELED);
57085
57681
  return await this.getTaskStatus({ id: params.id });
57086
57682
  }
57683
+ /** @internal */
57087
57684
  async purgeCompletedAfterTtl(taskId) {
57088
57685
  await delay(this.completedCacheTtlSec * 1000);
57089
57686
  this.completed.delete(taskId);
57090
57687
  this.taskEventQueues.delete(taskId);
57091
57688
  }
57689
+ /** @internal */
57092
57690
  normalizeResultPayload(result) {
57093
57691
  if (result === null || result === undefined) {
57094
57692
  return null;
@@ -57103,15 +57701,31 @@
57103
57701
  }
57104
57702
  }
57105
57703
 
57704
+ /**
57705
+ * Agent proxy module for remote agent communication.
57706
+ *
57707
+ * An {@link AgentProxy} is a client-side handle for invoking methods on a remote
57708
+ * agent. Use it when you need to call an agent that lives in another process,
57709
+ * container, or network location.
57710
+ *
57711
+ * @remarks
57712
+ * Create proxies via {@link Agent.remote}, {@link Agent.remoteByAddress}, or
57713
+ * {@link Agent.remoteByCapabilities} rather than instantiating AgentProxy directly.
57714
+ *
57715
+ * @module
57716
+ */
57717
+ /** @internal */
57106
57718
  function toRecord(value) {
57107
57719
  if (!value || typeof value !== 'object') {
57108
57720
  return {};
57109
57721
  }
57110
57722
  return value;
57111
57723
  }
57724
+ /** @internal */
57112
57725
  function toFameAddress(address) {
57113
57726
  return address instanceof FameAddress ? address : new FameAddress(String(address));
57114
57727
  }
57728
+ /** @internal */
57115
57729
  function wrapAgentProxy(proxy) {
57116
57730
  // Create RPC proxy options - only include address or capabilities, not both
57117
57731
  const proxyOptions = {
@@ -57140,6 +57754,7 @@
57140
57754
  },
57141
57755
  });
57142
57756
  }
57757
+ /** @internal */
57143
57758
  async function nextWithTimeout(iterator, timeoutMs) {
57144
57759
  if (timeoutMs == null) {
57145
57760
  return await iterator.next();
@@ -57157,7 +57772,44 @@
57157
57772
  }
57158
57773
  }
57159
57774
  }
57775
+ /**
57776
+ * Client-side proxy for communicating with remote agents.
57777
+ *
57778
+ * AgentProxy implements the {@link Agent} interface, allowing you to call
57779
+ * remote agents as if they were local objects. Method calls are serialized
57780
+ * and sent over the Fame fabric.
57781
+ *
57782
+ * @remarks
57783
+ * Do not instantiate AgentProxy directly. Use the factory methods on
57784
+ * {@link Agent} to create proxies:
57785
+ * - {@link Agent.remote} for flexible options
57786
+ * - {@link Agent.remoteByAddress} for direct addressing
57787
+ * - {@link Agent.remoteByCapabilities} for capability-based discovery
57788
+ *
57789
+ * The proxy also supports arbitrary RPC method calls. Any method not defined
57790
+ * on the proxy class is forwarded as an RPC call to the remote agent.
57791
+ *
57792
+ * @example
57793
+ * ```typescript
57794
+ * import { Agent } from '@naylence/agent-sdk';
57795
+ *
57796
+ * // Create a proxy to a remote agent
57797
+ * const proxy = Agent.remoteByAddress('fame://calculator');
57798
+ *
57799
+ * // Run a task synchronously
57800
+ * const result = await proxy.runTask({ a: 1, b: 2 });
57801
+ *
57802
+ * // Or start a task and poll for completion
57803
+ * const task = await proxy.startTask({
57804
+ * id: 'task-1',
57805
+ * message: { role: 'user', parts: [{ type: 'text', text: 'compute' }] },
57806
+ * });
57807
+ * ```
57808
+ *
57809
+ * @typeParam TAgent - The type of the remote agent for result typing.
57810
+ */
57160
57811
  class AgentProxy extends Agent {
57812
+ /** @internal */
57161
57813
  constructor(options) {
57162
57814
  const { address = null, capabilities = null, intentNl = null, fabric } = options;
57163
57815
  const provided = Number(address != null) + Number(capabilities != null) + Number(intentNl != null);
@@ -57173,9 +57825,11 @@
57173
57825
  this.intentNl = intentNl;
57174
57826
  this.fabric = fabric;
57175
57827
  }
57828
+ /** Returns null as proxies do not have a local name. */
57176
57829
  get name() {
57177
57830
  return null;
57178
57831
  }
57832
+ /** Returns the proxy's targeting specification. */
57179
57833
  get spec() {
57180
57834
  const spec = {
57181
57835
  address: this.targetAddress ? this.targetAddress.toString() : null,
@@ -57188,15 +57842,22 @@
57188
57842
  }
57189
57843
  return spec;
57190
57844
  }
57845
+ /**
57846
+ * The target agent's address, if specified.
57847
+ * @deprecated Use {@link AgentProxy.address} instead.
57848
+ */
57191
57849
  get addressRef() {
57192
57850
  return this.targetAddress;
57193
57851
  }
57852
+ /** The target agent's address, if specified. */
57194
57853
  get address() {
57195
57854
  return this.targetAddress;
57196
57855
  }
57856
+ /** The required capabilities for discovery, if specified. */
57197
57857
  get capabilities() {
57198
57858
  return this.targetCapabilities ?? undefined;
57199
57859
  }
57860
+ /** The fabric this proxy uses for communication. */
57200
57861
  get proxyFabric() {
57201
57862
  return this.fabric;
57202
57863
  }
@@ -57206,6 +57867,24 @@
57206
57867
  authenticate(_credentials) {
57207
57868
  throw new Error('Proxy authentication is not supported');
57208
57869
  }
57870
+ /**
57871
+ * Executes a task on the remote agent and waits for completion.
57872
+ *
57873
+ * Starts the task, subscribes to updates, and returns when the task reaches
57874
+ * a terminal state (completed, failed, or canceled).
57875
+ *
57876
+ * @param payload - The task payload to send.
57877
+ * @param id - Optional task identifier. Generated if not provided.
57878
+ * @returns The task result extracted from the final status message.
57879
+ * @throws Error if the task fails.
57880
+ *
57881
+ * @example
57882
+ * ```typescript
57883
+ * const proxy = Agent.remoteByAddress('fame://echo');
57884
+ * const result = await proxy.runTask('hello');
57885
+ * console.log(result); // 'hello'
57886
+ * ```
57887
+ */
57209
57888
  async runTask(payload = null, id = null) {
57210
57889
  const taskId = id ?? generateId();
57211
57890
  const params = makeTaskParams({ id: taskId, payload });
@@ -57279,16 +57958,38 @@
57279
57958
  const result = await this._invokeTarget('tasks/send', params);
57280
57959
  return TaskSchema.parse(result);
57281
57960
  }
57961
+ /**
57962
+ * Retrieves the current status of a task.
57963
+ *
57964
+ * @param params - Query parameters including the task ID.
57965
+ * @returns The task with current status.
57966
+ */
57282
57967
  async getTaskStatus(params) {
57283
57968
  const payload = TaskQueryParamsSchema.parse(params);
57284
57969
  const result = await this._invokeTarget('tasks/get', payload);
57285
57970
  return TaskSchema.parse(result);
57286
57971
  }
57972
+ /**
57973
+ * Requests cancellation of a running task.
57974
+ *
57975
+ * @param params - Parameters including the task ID.
57976
+ * @returns The task with updated status.
57977
+ */
57287
57978
  async cancelTask(params) {
57288
57979
  const payload = TaskIdParamsSchema.parse(params);
57289
57980
  const result = await this._invokeTarget('tasks/cancel', payload);
57290
57981
  return TaskSchema.parse(result);
57291
57982
  }
57983
+ /**
57984
+ * Subscribes to real-time updates for a task.
57985
+ *
57986
+ * Returns an async iterable that yields status and artifact events
57987
+ * until the task reaches a terminal state or the stream is closed.
57988
+ *
57989
+ * @param params - Task parameters.
57990
+ * @param options - Optional timeout and item limit settings.
57991
+ * @returns Async iterable of task events.
57992
+ */
57292
57993
  subscribeToTaskUpdates(params, options = {}) {
57293
57994
  const payload = TaskSendParamsSchema.parse(params);
57294
57995
  return this._streamRpc('tasks/sendSubscribe', payload, (frame) => {
@@ -57298,20 +57999,38 @@
57298
57999
  return TaskStatusUpdateEventSchema.parse(frame);
57299
58000
  }, 'tasks/sendUnsubscribe', TaskIdParamsSchema.parse({ id: payload.id }), options);
57300
58001
  }
58002
+ /**
58003
+ * Cancels a task subscription.
58004
+ *
58005
+ * @param params - Parameters including the task ID.
58006
+ */
57301
58007
  async unsubscribeTask(params) {
57302
58008
  const payload = TaskIdParamsSchema.parse(params);
57303
58009
  return await this._invokeTarget('tasks/sendUnsubscribe', payload);
57304
58010
  }
58011
+ /**
58012
+ * Registers a push notification endpoint for task updates.
58013
+ *
58014
+ * @param config - Push notification configuration.
58015
+ * @returns The registered configuration.
58016
+ */
57305
58017
  async registerPushEndpoint(config) {
57306
58018
  const payload = TaskPushNotificationConfigSchema.parse(config);
57307
58019
  const result = await this._invokeTarget('tasks/pushNotification/set', payload);
57308
58020
  return TaskPushNotificationConfigSchema.parse(result ?? payload);
57309
58021
  }
58022
+ /**
58023
+ * Retrieves the push notification config for a task.
58024
+ *
58025
+ * @param params - Parameters including the task ID.
58026
+ * @returns The push notification configuration.
58027
+ */
57310
58028
  async getPushNotificationConfig(params) {
57311
58029
  const payload = TaskIdParamsSchema.parse(params);
57312
58030
  const result = await this._invokeTarget('tasks/pushNotification/get', payload);
57313
58031
  return TaskPushNotificationConfigSchema.parse(result ?? payload);
57314
58032
  }
58033
+ /** @internal */
57315
58034
  _streamRpc(method, params, parseFrame, unsubscribeMethod, unsubscribeParams, options) {
57316
58035
  const self = this;
57317
58036
  return {
@@ -57380,6 +58099,7 @@
57380
58099
  },
57381
58100
  };
57382
58101
  }
58102
+ /** @internal */
57383
58103
  async _invokeTarget(method, params, options = {}) {
57384
58104
  if (this.intentNl) {
57385
58105
  throw new Error('Intent-based routing not yet supported');
@@ -57399,10 +58119,18 @@
57399
58119
  }
57400
58120
  throw new Error('Proxy has no routing target');
57401
58121
  }
58122
+ /**
58123
+ * Creates a proxy for a remote agent by address.
58124
+ * @internal Use {@link Agent.remoteByAddress} instead.
58125
+ */
57402
58126
  static remoteByAddress(address, options) {
57403
58127
  const proxy = new AgentProxy({ address, fabric: options.fabric });
57404
58128
  return wrapAgentProxy(proxy);
57405
58129
  }
58130
+ /**
58131
+ * Creates a proxy for a remote agent by capabilities.
58132
+ * @internal Use {@link Agent.remoteByCapabilities} instead.
58133
+ */
57406
58134
  static remoteByCapabilities(capabilities, options) {
57407
58135
  const proxy = new AgentProxy({ capabilities, fabric: options.fabric });
57408
58136
  return wrapAgentProxy(proxy);