@elizaos/plugin-elizacloud 2.0.3-beta.6 → 2.0.3-beta.7

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.
@@ -2896,6 +2896,7 @@ var cloudStatusProvider = {
2896
2896
  const bridgeSvc = runtime.getService("CLOUD_BRIDGE");
2897
2897
  const containers = containerSvc?.getTrackedContainers() ?? [];
2898
2898
  const connected = bridgeSvc?.getConnectedContainerIds() ?? [];
2899
+ const apiKeyInvalid = auth.isApiKeyInvalid();
2899
2900
  const running = containers.filter((c) => c.status === "running").length;
2900
2901
  const deploying = containers.filter((c) => c.status === "pending" || c.status === "building" || c.status === "deploying").length;
2901
2902
  const summaries = containers.slice(0, MAX_CONTAINER_SUMMARIES).map((c) => ({
@@ -2908,6 +2909,7 @@ var cloudStatusProvider = {
2908
2909
  }));
2909
2910
  const lines = [
2910
2911
  `ElizaCloud: ${containers.length} container(s), ${running} running, ${connected.length} bridged`,
2912
+ ...apiKeyInvalid ? [" - WARNING: Eliza Cloud API key REVOKED/INVALID — model calls will 401 until re-provisioned"] : [],
2911
2913
  ...summaries.map((c) => ` - ${c.name} [${c.status}]${c.url ? ` @ ${c.url}` : ""}${c.bridged ? " (bridged)" : ""}`)
2912
2914
  ];
2913
2915
  return {
@@ -2915,6 +2917,7 @@ var cloudStatusProvider = {
2915
2917
  `),
2916
2918
  values: {
2917
2919
  cloudAuthenticated: true,
2920
+ cloudApiKeyInvalid: apiKeyInvalid,
2918
2921
  totalContainers: containers.length,
2919
2922
  runningContainers: running,
2920
2923
  deployingContainers: deploying
@@ -4968,7 +4971,6 @@ import {
4968
4971
  resolveApiSecurityConfig,
4969
4972
  resolveDesktopApiPort
4970
4973
  } from "@elizaos/core";
4971
- import { isCloudReachable } from "@elizaos/shared";
4972
4974
  import { createRemoteJWKSet, jwtVerify } from "jose";
4973
4975
 
4974
4976
  // src/types/cloud.ts
@@ -5032,11 +5034,57 @@ function detectPlatform() {
5032
5034
  };
5033
5035
  return map[process.platform] ?? "linux";
5034
5036
  }
5037
+ var DEFAULT_REVALIDATION_CONFIG = {
5038
+ retryMs: 60000,
5039
+ steadyMs: 1800000,
5040
+ invalidThreshold: 2
5041
+ };
5042
+ function decideRevalidation(prev, probe, cfg = DEFAULT_REVALIDATION_CONFIG) {
5043
+ if (probe === "valid") {
5044
+ const log = prev.keyState !== "valid" ? { level: "info", message: "[CloudAuth] API key validated" } : null;
5045
+ return {
5046
+ state: { keyState: "valid", consecutiveInvalid: 0 },
5047
+ delayMs: cfg.steadyMs,
5048
+ log
5049
+ };
5050
+ }
5051
+ if (probe === "invalid") {
5052
+ const consecutiveInvalid = prev.consecutiveInvalid + 1;
5053
+ const confirmed = consecutiveInvalid >= cfg.invalidThreshold;
5054
+ if (confirmed) {
5055
+ const log = prev.keyState !== "invalid" ? {
5056
+ level: "error",
5057
+ message: "[CloudAuth] Eliza Cloud API key is REVOKED/INVALID (cloud reachable, key rejected). Model calls will fail with 401 until the agent is re-provisioned or a valid ELIZAOS_CLOUD_API_KEY is set."
5058
+ } : null;
5059
+ return {
5060
+ state: { keyState: "invalid", consecutiveInvalid },
5061
+ delayMs: cfg.steadyMs,
5062
+ log
5063
+ };
5064
+ }
5065
+ return {
5066
+ state: { keyState: prev.keyState, consecutiveInvalid },
5067
+ delayMs: cfg.retryMs,
5068
+ log: null
5069
+ };
5070
+ }
5071
+ return {
5072
+ state: { ...prev },
5073
+ delayMs: cfg.retryMs,
5074
+ log: null
5075
+ };
5076
+ }
5077
+
5035
5078
  class CloudAuthService extends Service {
5036
5079
  static serviceType = "CLOUD_AUTH";
5037
5080
  capabilityDescription = "Eliza Cloud device authentication and SSO session helpers";
5038
5081
  client;
5039
5082
  credentials = null;
5083
+ revalidationTimer = null;
5084
+ revalidationState = {
5085
+ keyState: "unknown",
5086
+ consecutiveInvalid: 0
5087
+ };
5040
5088
  constructor(runtime) {
5041
5089
  super(runtime);
5042
5090
  this.client = new CloudApiClient2(DEFAULT_CLOUD_CONFIG.baseUrl);
@@ -5047,6 +5095,11 @@ class CloudAuthService extends Service {
5047
5095
  return service;
5048
5096
  }
5049
5097
  async stop() {
5098
+ if (this.revalidationTimer) {
5099
+ clearTimeout(this.revalidationTimer);
5100
+ this.revalidationTimer = null;
5101
+ }
5102
+ this.revalidationState = { keyState: "unknown", consecutiveInvalid: 0 };
5050
5103
  this.credentials = null;
5051
5104
  }
5052
5105
  async initialize() {
@@ -5063,11 +5116,7 @@ class CloudAuthService extends Service {
5063
5116
  authenticatedAt: Date.now()
5064
5117
  };
5065
5118
  logger10.info("[CloudAuth] Authenticated with saved API key");
5066
- this.validateApiKey(key).then((valid) => {
5067
- if (!valid) {
5068
- logger10.warn("[CloudAuth] Saved API key could not be validated (cloud may be unreachable or key revoked) — model calls will use the key anyway");
5069
- }
5070
- }).catch(() => {});
5119
+ this.scheduleRevalidation(0);
5071
5120
  return;
5072
5121
  }
5073
5122
  const enabled = this.runtime.getSetting("ELIZAOS_CLOUD_ENABLED");
@@ -5083,20 +5132,50 @@ class CloudAuthService extends Service {
5083
5132
  logger10.info("[CloudAuth] Cloud not enabled (set ELIZAOS_CLOUD_ENABLED=true)");
5084
5133
  }
5085
5134
  }
5086
- async validateApiKey(key) {
5087
- if (!await isCloudReachable()) {
5088
- logger10.warn("[CloudAuth] Cloud unreachable at boot — skipping API key validation; key will be used as-is");
5089
- return false;
5090
- }
5135
+ async probeApiKey(key) {
5091
5136
  try {
5092
5137
  const validationClient = new CloudApiClient2(this.client.getBaseUrl(), key);
5093
5138
  await validationClient.get("/models", { timeoutMs: 2500 });
5094
- return true;
5139
+ return "valid";
5095
5140
  } catch (err) {
5096
- const msg = err instanceof Error ? err.message : String(err);
5097
- logger10.warn(`[CloudAuth] Could not reach cloud API to validate key: ${msg}`);
5098
- return false;
5141
+ if (err instanceof CloudApiError2 && (err.statusCode === 401 || err.statusCode === 403)) {
5142
+ return "invalid";
5143
+ }
5144
+ return "unreachable";
5145
+ }
5146
+ }
5147
+ scheduleRevalidation(delayMs) {
5148
+ if (this.revalidationTimer) {
5149
+ clearTimeout(this.revalidationTimer);
5099
5150
  }
5151
+ const timer = setTimeout(() => {
5152
+ this.runRevalidation();
5153
+ }, delayMs);
5154
+ timer.unref?.();
5155
+ this.revalidationTimer = timer;
5156
+ }
5157
+ async runRevalidation() {
5158
+ const key = this.credentials?.apiKey;
5159
+ if (!key) {
5160
+ return;
5161
+ }
5162
+ const probe = await this.probeApiKey(key).catch(() => "unreachable");
5163
+ if (this.credentials?.apiKey !== key) {
5164
+ return;
5165
+ }
5166
+ const decision = decideRevalidation(this.revalidationState, probe);
5167
+ this.revalidationState = decision.state;
5168
+ if (decision.log) {
5169
+ if (decision.log.level === "error") {
5170
+ logger10.error(decision.log.message);
5171
+ } else {
5172
+ logger10.info(decision.log.message);
5173
+ }
5174
+ }
5175
+ this.scheduleRevalidation(decision.delayMs);
5176
+ }
5177
+ isApiKeyInvalid() {
5178
+ return this.revalidationState.keyState === "invalid";
5100
5179
  }
5101
5180
  async authenticateWithDevice() {
5102
5181
  const deviceId = await deriveDeviceId();
@@ -9648,4 +9727,4 @@ export {
9648
9727
  BackupScheduler
9649
9728
  };
9650
9729
 
9651
- //# debugId=A3451C99EA049FDB64756E2164756E21
9730
+ //# debugId=81B43B4EAB60446064756E2164756E21