@elizaos/agent 2.0.0-alpha.410 → 2.0.0-alpha.413
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/apps/app-companion/src/components/companion/CompanionAppView.d.ts.map +1 -1
- package/apps/app-companion/src/components/companion/CompanionAppView.js +5 -5
- package/apps/app-companion/src/components/companion/CompanionView.d.ts.map +1 -1
- package/apps/app-companion/src/components/companion/CompanionView.js +5 -5
- package/package.json +4 -4
- package/packages/agent/src/api/provider-switch-config.d.ts +3 -3
- package/packages/agent/src/api/provider-switch-config.d.ts.map +1 -1
- package/packages/agent/src/auth/account-storage.d.ts +48 -0
- package/packages/agent/src/auth/account-storage.d.ts.map +1 -0
- package/packages/agent/src/auth/account-storage.js +238 -0
- package/packages/agent/src/auth/credentials.d.ts +44 -25
- package/packages/agent/src/auth/credentials.d.ts.map +1 -1
- package/packages/agent/src/auth/credentials.js +175 -137
- package/packages/agent/src/auth/refresh-mutex.d.ts +19 -0
- package/packages/agent/src/auth/refresh-mutex.d.ts.map +1 -0
- package/packages/agent/src/auth/refresh-mutex.js +33 -0
- package/packages/agent/src/config/types.eliza.d.ts +8 -3
- package/packages/agent/src/config/types.eliza.d.ts.map +1 -1
- package/packages/app-core/src/components/apps/launch-history.d.ts.map +1 -1
- package/packages/app-core/src/components/auth/LoginView.d.ts +1 -1
- package/packages/app-core/src/components/auth/LoginView.d.ts.map +1 -1
- package/packages/app-core/src/components/auth/LoginView.js +1 -1
- package/packages/app-core/src/components/pages/AppDetailsView.d.ts.map +1 -1
- package/packages/app-core/src/components/pages/AppDetailsView.js +10 -10
- package/packages/app-core/src/components/pages/AppsView.d.ts.map +1 -1
- package/packages/app-core/src/components/pages/AppsView.js +1 -0
- package/packages/app-core/src/components/pages/AutomationsView.d.ts.map +1 -1
- package/packages/app-core/src/components/pages/AutomationsView.js +0 -1
- package/packages/app-core/src/components/settings/ProviderSwitcher.d.ts.map +1 -1
- package/packages/app-core/src/components/settings/SubscriptionStatus.d.ts +2 -0
- package/packages/app-core/src/components/settings/SubscriptionStatus.d.ts.map +1 -1
- package/packages/app-core/src/onboarding-config.d.ts +2 -2
- package/packages/app-core/src/onboarding-config.d.ts.map +1 -1
- package/packages/app-core/src/services/auth-store.d.ts.map +1 -1
- package/packages/app-core/src/shell/AppWindowRenderer.d.ts.map +1 -1
- package/packages/app-core/src/shell/AppWindowRenderer.js +11 -17
- package/packages/app-core/src/shell/DetachedShellRoot.d.ts.map +1 -1
- package/packages/app-core/src/state/startup-phase-poll.js +1 -1
- package/packages/shared/src/config/types.eliza.d.ts +8 -3
- package/packages/shared/src/config/types.eliza.d.ts.map +1 -1
- package/packages/shared/src/contracts/onboarding.d.ts +10 -2
- package/packages/shared/src/contracts/onboarding.d.ts.map +1 -1
- package/packages/shared/src/contracts/onboarding.js +2 -2
- package/packages/shared/src/contracts/service-routing.d.ts +87 -3
- package/packages/shared/src/contracts/service-routing.d.ts.map +1 -1
- package/packages/shared/src/contracts/service-routing.js +171 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CompanionAppView.d.ts","sourceRoot":"","sources":["../../../../../../../../apps/app-companion/src/components/companion/CompanionAppView.tsx"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,iBAAiB,EAGvB,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"CompanionAppView.d.ts","sourceRoot":"","sources":["../../../../../../../../apps/app-companion/src/components/companion/CompanionAppView.tsx"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,iBAAiB,EAGvB,MAAM,mBAAmB,CAAC;AA8P3B;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,iBAAiB,2CAQzD"}
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { ChatModalView, useApp, useRenderGuard, } from "@elizaos/app-core";
|
|
3
|
+
// Static import: CharacterEditor is statically re-exported by app-core's
|
|
4
|
+
// browser entry, so the previous lazy() was eagerly merged back into the
|
|
5
|
+
// main chunk. Drop the wrapper to silence the dynamic↔static collision
|
|
6
|
+
// warning and remove the unnecessary Suspense boundary overhead.
|
|
7
|
+
import { CharacterEditor } from "@elizaos/app-core/components/character/CharacterEditor";
|
|
3
8
|
import { usePtySessions } from "@elizaos/app-core/state/PtySessionsContext";
|
|
4
9
|
import { PtyConsoleSidePanel } from "@elizaos/app-task-coordinator";
|
|
5
10
|
import { memo, Suspense, useCallback, useEffect, useMemo, useState, } from "react";
|
|
@@ -9,11 +14,6 @@ import { useCompanionSceneStatus } from "./companion-scene-status-context";
|
|
|
9
14
|
import { EmotePicker } from "./EmotePicker";
|
|
10
15
|
import { InferenceCloudAlertButton } from "./InferenceCloudAlertButton";
|
|
11
16
|
import { resolveCompanionInferenceNotice } from "./resolve-companion-inference-notice";
|
|
12
|
-
// Static import: CharacterEditor is statically re-exported by app-core's
|
|
13
|
-
// browser entry, so the previous lazy() was eagerly merged back into the
|
|
14
|
-
// main chunk. Drop the wrapper to silence the dynamic↔static collision
|
|
15
|
-
// warning and remove the unnecessary Suspense boundary overhead.
|
|
16
|
-
import { CharacterEditor } from "@elizaos/app-core/components/character/CharacterEditor";
|
|
17
17
|
const COMPANION_UI_REVEAL_FALLBACK_MS = 1400;
|
|
18
18
|
const COMPANION_DOCK_HEIGHT = "min(42vh, 24rem)";
|
|
19
19
|
/** Isolated PTY panel — avoids polling ptySessions in the main overlay. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CompanionView.d.ts","sourceRoot":"","sources":["../../../../../../../../apps/app-companion/src/components/companion/CompanionView.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"CompanionView.d.ts","sourceRoot":"","sources":["../../../../../../../../apps/app-companion/src/components/companion/CompanionView.tsx"],"names":[],"mappings":"AAoQA;;;;GAIG;AACH,eAAO,MAAM,aAAa,oFAMxB,CAAC"}
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { ChatModalView, useApp, useRenderGuard } from "@elizaos/app-core";
|
|
3
|
+
// Static import: CharacterEditor is statically re-exported by app-core's
|
|
4
|
+
// browser entry, so the previous lazy() was eagerly merged back into the
|
|
5
|
+
// main chunk. Drop the wrapper to silence the dynamic↔static collision
|
|
6
|
+
// warning and remove the unnecessary Suspense boundary overhead.
|
|
7
|
+
import { CharacterEditor } from "@elizaos/app-core/components/character/CharacterEditor";
|
|
3
8
|
import { usePtySessions } from "@elizaos/app-core/state/PtySessionsContext";
|
|
4
9
|
import { PtyConsoleSidePanel } from "@elizaos/app-task-coordinator";
|
|
5
10
|
import { memo, Suspense, useCallback, useEffect, useMemo, useState, } from "react";
|
|
@@ -9,11 +14,6 @@ import { useCompanionSceneStatus } from "./companion-scene-status-context";
|
|
|
9
14
|
import { EmotePicker } from "./EmotePicker";
|
|
10
15
|
import { InferenceCloudAlertButton } from "./InferenceCloudAlertButton";
|
|
11
16
|
import { resolveCompanionInferenceNotice } from "./resolve-companion-inference-notice";
|
|
12
|
-
// Static import: CharacterEditor is statically re-exported by app-core's
|
|
13
|
-
// browser entry, so the previous lazy() was eagerly merged back into the
|
|
14
|
-
// main chunk. Drop the wrapper to silence the dynamic↔static collision
|
|
15
|
-
// warning and remove the unnecessary Suspense boundary overhead.
|
|
16
|
-
import { CharacterEditor } from "@elizaos/app-core/components/character/CharacterEditor";
|
|
17
17
|
const COMPANION_UI_REVEAL_FALLBACK_MS = 1400;
|
|
18
18
|
const COMPANION_DOCK_HEIGHT = "min(42vh, 24rem)";
|
|
19
19
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elizaos/agent",
|
|
3
|
-
"version": "2.0.0-alpha.
|
|
3
|
+
"version": "2.0.0-alpha.413",
|
|
4
4
|
"description": "Standalone elizaOS-based agent and backend server package.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -467,7 +467,7 @@
|
|
|
467
467
|
"@elizaos/app-steward": "^0.0.0",
|
|
468
468
|
"@elizaos/app-task-coordinator": "^0.0.0",
|
|
469
469
|
"@elizaos/app-training": "^0.0.1",
|
|
470
|
-
"@elizaos/core": "^2.0.0-alpha.
|
|
470
|
+
"@elizaos/core": "^2.0.0-alpha.413",
|
|
471
471
|
"@elizaos/plugin-agent-orchestrator": "^0.6.2-alpha.0",
|
|
472
472
|
"@elizaos/plugin-browser-bridge": "^0.1.0",
|
|
473
473
|
"@elizaos/plugin-local-embedding": "^2.0.0-alpha.12",
|
|
@@ -476,8 +476,8 @@
|
|
|
476
476
|
"@elizaos/plugin-solana": "^2.0.0-alpha.6",
|
|
477
477
|
"@elizaos/plugin-sql": "^2.0.0-alpha.19",
|
|
478
478
|
"@elizaos/plugin-wechat": "^0.1.0",
|
|
479
|
-
"@elizaos/shared": "^2.0.0-alpha.
|
|
480
|
-
"@elizaos/skills": "^2.0.0-alpha.
|
|
479
|
+
"@elizaos/shared": "^2.0.0-alpha.413",
|
|
480
|
+
"@elizaos/skills": "^2.0.0-alpha.413",
|
|
481
481
|
"@hapi/boom": "^10.0.1",
|
|
482
482
|
"@noble/curves": "^2.0.1",
|
|
483
483
|
"@solana/web3.js": "^1.98.4",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ElizaConfig } from "../config/types.eliza.js";
|
|
2
2
|
import { type OnboardingConnection, type OnboardingCredentialInputs } from "../contracts/onboarding.js";
|
|
3
|
-
import type { DeploymentTargetConfig,
|
|
3
|
+
import type { DeploymentTargetConfig, LinkedAccountFlagsConfig, ServiceCapability, ServiceRoutingConfig } from "../contracts/service-routing.js";
|
|
4
4
|
type MutableElizaConfig = Partial<ElizaConfig> & {
|
|
5
5
|
cloud?: Record<string, unknown>;
|
|
6
6
|
models?: Record<string, unknown>;
|
|
@@ -8,12 +8,12 @@ type MutableElizaConfig = Partial<ElizaConfig> & {
|
|
|
8
8
|
rpcProviders?: Record<string, string>;
|
|
9
9
|
};
|
|
10
10
|
deploymentTarget?: DeploymentTargetConfig;
|
|
11
|
-
linkedAccounts?:
|
|
11
|
+
linkedAccounts?: LinkedAccountFlagsConfig;
|
|
12
12
|
serviceRouting?: ServiceRoutingConfig;
|
|
13
13
|
};
|
|
14
14
|
export declare function applyCanonicalOnboardingConfig(config: MutableElizaConfig, args: {
|
|
15
15
|
deploymentTarget?: DeploymentTargetConfig | null;
|
|
16
|
-
linkedAccounts?:
|
|
16
|
+
linkedAccounts?: LinkedAccountFlagsConfig | null;
|
|
17
17
|
serviceRouting?: ServiceRoutingConfig | null;
|
|
18
18
|
clearRoutes?: readonly ServiceCapability[];
|
|
19
19
|
}): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provider-switch-config.d.ts","sourceRoot":"","sources":["../../../../../src/api/provider-switch-config.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAQL,KAAK,oBAAoB,EACzB,KAAK,0BAA0B,EAIhC,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EACV,sBAAsB,EACtB,
|
|
1
|
+
{"version":3,"file":"provider-switch-config.d.ts","sourceRoot":"","sources":["../../../../../src/api/provider-switch-config.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAQL,KAAK,oBAAoB,EACzB,KAAK,0BAA0B,EAIhC,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EACV,sBAAsB,EACtB,wBAAwB,EACxB,iBAAiB,EACjB,oBAAoB,EACrB,MAAM,iCAAiC,CAAC;AAQzC,KAAK,kBAAkB,GAAG,OAAO,CAAC,WAAW,CAAC,GAAG;IAC/C,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,MAAM,CAAC,EAAE;QAAE,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,CAAC;IACnD,gBAAgB,CAAC,EAAE,sBAAsB,CAAC;IAC1C,cAAc,CAAC,EAAE,wBAAwB,CAAC;IAC1C,cAAc,CAAC,EAAE,oBAAoB,CAAC;CACvC,CAAC;AAuHF,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,kBAAkB,EAC1B,IAAI,EAAE;IACJ,gBAAgB,CAAC,EAAE,sBAAsB,GAAG,IAAI,CAAC;IACjD,cAAc,CAAC,EAAE,wBAAwB,GAAG,IAAI,CAAC;IACjD,cAAc,CAAC,EAAE,oBAAoB,GAAG,IAAI,CAAC;IAC7C,WAAW,CAAC,EAAE,SAAS,iBAAiB,EAAE,CAAC;CAC5C,GACA,IAAI,CAUN;AAuWD;;;;;;;;;;;;GAYG;AACH,wBAAgB,+BAA+B,CAC7C,MAAM,EAAE,OAAO,CAAC,WAAW,CAAC,EAC5B,QAAQ,EAAE,MAAM,GACf,IAAI,CAuBN;AAED;;;;;;;GAOG;AACH,wBAAgB,+BAA+B,CAC7C,MAAM,EAAE,OAAO,CAAC,WAAW,CAAC,GAC3B,IAAI,CAIN;AAED;;;GAGG;AACH,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,kBAAkB,GACzB,IAAI,CA8EN;AAED,wBAAgB,8BAA8B,CAAC,IAAI,EAAE;IACnD,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,GAAG,oBAAoB,GAAG,IAAI,CAmB9B;AAED,wBAAsB,+BAA+B,CACnD,MAAM,EAAE,kBAAkB,EAC1B,UAAU,EAAE,oBAAoB,GAC/B,OAAO,CAAC,IAAI,CAAC,CAmLf;AAED,wBAAsB,oCAAoC,CACxD,MAAM,EAAE,kBAAkB,EAC1B,IAAI,EAAE;IACJ,gBAAgB,CAAC,EAAE,0BAA0B,GAAG,IAAI,CAAC;IACrD,gBAAgB,CAAC,EAAE,sBAAsB,GAAG,IAAI,CAAC;IACjD,cAAc,CAAC,EAAE,oBAAoB,GAAG,IAAI,CAAC;CAC9C,GACA,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAkCxB"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-account credential storage.
|
|
3
|
+
*
|
|
4
|
+
* Layout: `~/.eliza/auth/{providerId}/{accountId}.json` (mode 0600,
|
|
5
|
+
* atomic writes). Multiple accounts per provider are supported.
|
|
6
|
+
*
|
|
7
|
+
* Migration: on first read of a provider, if the legacy single-file
|
|
8
|
+
* `~/.eliza/auth/{providerId}.json` exists and the per-account
|
|
9
|
+
* directory does not, the legacy file is moved to
|
|
10
|
+
* `<dir>/default.json` and the legacy file is removed.
|
|
11
|
+
*/
|
|
12
|
+
import type { OAuthCredentials, SubscriptionProvider } from "./types.js";
|
|
13
|
+
export interface AccountCredentialRecord {
|
|
14
|
+
/** accountId, e.g. "default" or a uuid */
|
|
15
|
+
id: string;
|
|
16
|
+
providerId: SubscriptionProvider;
|
|
17
|
+
/** user-facing name (e.g. "Personal", "Work") */
|
|
18
|
+
label: string;
|
|
19
|
+
source: "oauth" | "api-key";
|
|
20
|
+
/**
|
|
21
|
+
* Existing OAuth credential blob — `{ access, refresh, expires }`
|
|
22
|
+
* for OAuth accounts; for `api-key` accounts only `access` is
|
|
23
|
+
* meaningful (refresh is the empty string and expires is `0` /
|
|
24
|
+
* a far-future sentinel by convention of the caller).
|
|
25
|
+
*/
|
|
26
|
+
credentials: OAuthCredentials;
|
|
27
|
+
createdAt: number;
|
|
28
|
+
updatedAt: number;
|
|
29
|
+
lastUsedAt?: number;
|
|
30
|
+
organizationId?: string;
|
|
31
|
+
userId?: string;
|
|
32
|
+
email?: string;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Run the legacy → per-account migration for both known subscription
|
|
36
|
+
* providers. Idempotent: each provider migrates at most once per
|
|
37
|
+
* process. Returns the providers that were actually migrated this
|
|
38
|
+
* call.
|
|
39
|
+
*/
|
|
40
|
+
export declare function migrateLegacySingleAccount(): {
|
|
41
|
+
migrated: SubscriptionProvider[];
|
|
42
|
+
};
|
|
43
|
+
export declare function listAccounts(provider: SubscriptionProvider): AccountCredentialRecord[];
|
|
44
|
+
export declare function loadAccount(provider: SubscriptionProvider, accountId: string): AccountCredentialRecord | null;
|
|
45
|
+
export declare function saveAccount(record: AccountCredentialRecord): void;
|
|
46
|
+
export declare function deleteAccount(provider: SubscriptionProvider, accountId: string): void;
|
|
47
|
+
export declare function touchAccount(provider: SubscriptionProvider, accountId: string): void;
|
|
48
|
+
//# sourceMappingURL=account-storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"account-storage.d.ts","sourceRoot":"","sources":["../../../../../src/auth/account-storage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAMH,OAAO,KAAK,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAEzE,MAAM,WAAW,uBAAuB;IACtC,0CAA0C;IAC1C,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,oBAAoB,CAAC;IACjC,iDAAiD;IACjD,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,OAAO,GAAG,SAAS,CAAC;IAC5B;;;;;OAKG;IACH,WAAW,EAAE,gBAAgB,CAAC;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AA6ID;;;;;GAKG;AACH,wBAAgB,0BAA0B,IAAI;IAC5C,QAAQ,EAAE,oBAAoB,EAAE,CAAC;CAClC,CAWA;AAQD,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,oBAAoB,GAC7B,uBAAuB,EAAE,CAuC3B;AAED,wBAAgB,WAAW,CACzB,QAAQ,EAAE,oBAAoB,EAC9B,SAAS,EAAE,MAAM,GAChB,uBAAuB,GAAG,IAAI,CAgChC;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,uBAAuB,GAAG,IAAI,CAUjE;AAED,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,oBAAoB,EAC9B,SAAS,EAAE,MAAM,GAChB,IAAI,CAUN;AAED,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,oBAAoB,EAC9B,SAAS,EAAE,MAAM,GAChB,IAAI,CAQN"}
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-account credential storage.
|
|
3
|
+
*
|
|
4
|
+
* Layout: `~/.eliza/auth/{providerId}/{accountId}.json` (mode 0600,
|
|
5
|
+
* atomic writes). Multiple accounts per provider are supported.
|
|
6
|
+
*
|
|
7
|
+
* Migration: on first read of a provider, if the legacy single-file
|
|
8
|
+
* `~/.eliza/auth/{providerId}.json` exists and the per-account
|
|
9
|
+
* directory does not, the legacy file is moved to
|
|
10
|
+
* `<dir>/default.json` and the legacy file is removed.
|
|
11
|
+
*/
|
|
12
|
+
import fs from "node:fs";
|
|
13
|
+
import os from "node:os";
|
|
14
|
+
import path from "node:path";
|
|
15
|
+
import { logger } from "@elizaos/core";
|
|
16
|
+
function authRoot() {
|
|
17
|
+
return path.join(process.env.ELIZA_HOME || path.join(os.homedir(), ".eliza"), "auth");
|
|
18
|
+
}
|
|
19
|
+
function providerDir(provider) {
|
|
20
|
+
return path.join(authRoot(), provider);
|
|
21
|
+
}
|
|
22
|
+
function legacyProviderFile(provider) {
|
|
23
|
+
return path.join(authRoot(), `${provider}.json`);
|
|
24
|
+
}
|
|
25
|
+
function accountFile(provider, accountId) {
|
|
26
|
+
return path.join(providerDir(provider), `${accountId}.json`);
|
|
27
|
+
}
|
|
28
|
+
function ensureProviderDir(provider) {
|
|
29
|
+
const dir = providerDir(provider);
|
|
30
|
+
if (!fs.existsSync(dir)) {
|
|
31
|
+
fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function atomicWriteJsonSync(filePath, value) {
|
|
35
|
+
const dir = path.dirname(filePath);
|
|
36
|
+
if (!fs.existsSync(dir)) {
|
|
37
|
+
fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
38
|
+
}
|
|
39
|
+
const tmp = `${filePath}.tmp`;
|
|
40
|
+
fs.writeFileSync(tmp, JSON.stringify(value, null, 2), {
|
|
41
|
+
encoding: "utf-8",
|
|
42
|
+
mode: 0o600,
|
|
43
|
+
});
|
|
44
|
+
fs.renameSync(tmp, filePath);
|
|
45
|
+
}
|
|
46
|
+
function isAccountCredentialRecord(value) {
|
|
47
|
+
if (!value || typeof value !== "object")
|
|
48
|
+
return false;
|
|
49
|
+
const v = value;
|
|
50
|
+
return (typeof v.id === "string" &&
|
|
51
|
+
typeof v.providerId === "string" &&
|
|
52
|
+
typeof v.label === "string" &&
|
|
53
|
+
(v.source === "oauth" || v.source === "api-key") &&
|
|
54
|
+
typeof v.credentials === "object" &&
|
|
55
|
+
v.credentials !== null &&
|
|
56
|
+
typeof v.credentials.access === "string" &&
|
|
57
|
+
typeof v.createdAt === "number" &&
|
|
58
|
+
typeof v.updatedAt === "number");
|
|
59
|
+
}
|
|
60
|
+
const migratedProviders = new Set();
|
|
61
|
+
let migrationRunAtLeastOnce = false;
|
|
62
|
+
function migrateProvider(provider) {
|
|
63
|
+
if (migratedProviders.has(provider))
|
|
64
|
+
return false;
|
|
65
|
+
migratedProviders.add(provider);
|
|
66
|
+
const dir = providerDir(provider);
|
|
67
|
+
const legacy = legacyProviderFile(provider);
|
|
68
|
+
if (!fs.existsSync(legacy))
|
|
69
|
+
return false;
|
|
70
|
+
if (fs.existsSync(dir)) {
|
|
71
|
+
// Per-account directory already exists — leave the legacy file
|
|
72
|
+
// alone (operator may be mid-migration). Don't auto-delete.
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
let parsed = null;
|
|
76
|
+
try {
|
|
77
|
+
const raw = fs.readFileSync(legacy, "utf-8");
|
|
78
|
+
parsed = JSON.parse(raw);
|
|
79
|
+
}
|
|
80
|
+
catch (err) {
|
|
81
|
+
logger.warn(`[auth] Failed to read legacy credential file for migration ${legacy}: ${String(err)}`);
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
if (!parsed ||
|
|
85
|
+
typeof parsed !== "object" ||
|
|
86
|
+
!parsed.credentials ||
|
|
87
|
+
typeof parsed.credentials.access !== "string") {
|
|
88
|
+
logger.warn(`[auth] Legacy credential file ${legacy} is malformed — skipping migration`);
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
const now = Date.now();
|
|
92
|
+
const record = {
|
|
93
|
+
id: "default",
|
|
94
|
+
providerId: provider,
|
|
95
|
+
label: "Default",
|
|
96
|
+
source: "oauth",
|
|
97
|
+
credentials: parsed.credentials,
|
|
98
|
+
createdAt: typeof parsed.createdAt === "number" ? parsed.createdAt : now,
|
|
99
|
+
updatedAt: typeof parsed.updatedAt === "number" ? parsed.updatedAt : now,
|
|
100
|
+
};
|
|
101
|
+
ensureProviderDir(provider);
|
|
102
|
+
atomicWriteJsonSync(accountFile(provider, "default"), record);
|
|
103
|
+
// Atomic-ish delete: rename to a side path first so a concurrent
|
|
104
|
+
// reader sees either the legacy file or nothing — then unlink.
|
|
105
|
+
const removed = `${legacy}.migrated-${now}`;
|
|
106
|
+
try {
|
|
107
|
+
fs.renameSync(legacy, removed);
|
|
108
|
+
fs.unlinkSync(removed);
|
|
109
|
+
}
|
|
110
|
+
catch (err) {
|
|
111
|
+
logger.warn(`[auth] Failed to remove legacy credential file ${legacy} after migration: ${String(err)}`);
|
|
112
|
+
}
|
|
113
|
+
logger.info(`[auth] Migrated legacy ${provider} credentials to per-account store as "default"`);
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Run the legacy → per-account migration for both known subscription
|
|
118
|
+
* providers. Idempotent: each provider migrates at most once per
|
|
119
|
+
* process. Returns the providers that were actually migrated this
|
|
120
|
+
* call.
|
|
121
|
+
*/
|
|
122
|
+
export function migrateLegacySingleAccount() {
|
|
123
|
+
migrationRunAtLeastOnce = true;
|
|
124
|
+
const providers = [
|
|
125
|
+
"anthropic-subscription",
|
|
126
|
+
"openai-codex",
|
|
127
|
+
];
|
|
128
|
+
const migrated = [];
|
|
129
|
+
for (const p of providers) {
|
|
130
|
+
if (migrateProvider(p))
|
|
131
|
+
migrated.push(p);
|
|
132
|
+
}
|
|
133
|
+
return { migrated };
|
|
134
|
+
}
|
|
135
|
+
function ensureMigrationOnce() {
|
|
136
|
+
if (!migrationRunAtLeastOnce) {
|
|
137
|
+
migrateLegacySingleAccount();
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
export function listAccounts(provider) {
|
|
141
|
+
ensureMigrationOnce();
|
|
142
|
+
// Run provider-specific migration too in case a new provider was
|
|
143
|
+
// added after the first global pass.
|
|
144
|
+
migrateProvider(provider);
|
|
145
|
+
const dir = providerDir(provider);
|
|
146
|
+
if (!fs.existsSync(dir))
|
|
147
|
+
return [];
|
|
148
|
+
const entries = fs.readdirSync(dir);
|
|
149
|
+
const records = [];
|
|
150
|
+
for (const entry of entries) {
|
|
151
|
+
if (!entry.endsWith(".json"))
|
|
152
|
+
continue;
|
|
153
|
+
if (entry.endsWith(".tmp.json") || entry.endsWith(".json.tmp"))
|
|
154
|
+
continue;
|
|
155
|
+
const filePath = path.join(dir, entry);
|
|
156
|
+
let parsed;
|
|
157
|
+
try {
|
|
158
|
+
parsed = JSON.parse(fs.readFileSync(filePath, "utf-8"));
|
|
159
|
+
}
|
|
160
|
+
catch (err) {
|
|
161
|
+
logger.warn(`[auth] Skipping malformed credential file ${filePath}: ${String(err)}`);
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
if (!isAccountCredentialRecord(parsed)) {
|
|
165
|
+
logger.warn(`[auth] Skipping credential file ${filePath} — wrong shape`);
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
if (parsed.providerId !== provider) {
|
|
169
|
+
logger.warn(`[auth] Credential file ${filePath} declares providerId="${parsed.providerId}", expected "${provider}" — skipping`);
|
|
170
|
+
continue;
|
|
171
|
+
}
|
|
172
|
+
records.push(parsed);
|
|
173
|
+
}
|
|
174
|
+
records.sort((a, b) => a.createdAt - b.createdAt);
|
|
175
|
+
return records;
|
|
176
|
+
}
|
|
177
|
+
export function loadAccount(provider, accountId) {
|
|
178
|
+
ensureMigrationOnce();
|
|
179
|
+
migrateProvider(provider);
|
|
180
|
+
const file = accountFile(provider, accountId);
|
|
181
|
+
let raw;
|
|
182
|
+
try {
|
|
183
|
+
raw = fs.readFileSync(file, "utf-8");
|
|
184
|
+
}
|
|
185
|
+
catch (err) {
|
|
186
|
+
if (err.code === "ENOENT")
|
|
187
|
+
return null;
|
|
188
|
+
throw err;
|
|
189
|
+
}
|
|
190
|
+
let parsed;
|
|
191
|
+
try {
|
|
192
|
+
parsed = JSON.parse(raw);
|
|
193
|
+
}
|
|
194
|
+
catch (err) {
|
|
195
|
+
logger.warn(`[auth] Credential file ${file} is malformed JSON: ${String(err)}`);
|
|
196
|
+
return null;
|
|
197
|
+
}
|
|
198
|
+
if (!isAccountCredentialRecord(parsed)) {
|
|
199
|
+
logger.warn(`[auth] Credential file ${file} has wrong shape`);
|
|
200
|
+
return null;
|
|
201
|
+
}
|
|
202
|
+
if (parsed.providerId !== provider || parsed.id !== accountId) {
|
|
203
|
+
logger.warn(`[auth] Credential file ${file} provider/id mismatch (got ${parsed.providerId}/${parsed.id})`);
|
|
204
|
+
return null;
|
|
205
|
+
}
|
|
206
|
+
return parsed;
|
|
207
|
+
}
|
|
208
|
+
export function saveAccount(record) {
|
|
209
|
+
ensureProviderDir(record.providerId);
|
|
210
|
+
const next = {
|
|
211
|
+
...record,
|
|
212
|
+
updatedAt: Date.now(),
|
|
213
|
+
};
|
|
214
|
+
atomicWriteJsonSync(accountFile(record.providerId, record.id), next);
|
|
215
|
+
logger.info(`[auth] Saved ${record.providerId} account "${record.id}" (label="${record.label}")`);
|
|
216
|
+
}
|
|
217
|
+
export function deleteAccount(provider, accountId) {
|
|
218
|
+
const file = accountFile(provider, accountId);
|
|
219
|
+
try {
|
|
220
|
+
fs.unlinkSync(file);
|
|
221
|
+
logger.info(`[auth] Deleted ${provider} account "${accountId}"`);
|
|
222
|
+
}
|
|
223
|
+
catch (err) {
|
|
224
|
+
if (err.code !== "ENOENT") {
|
|
225
|
+
throw err;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
export function touchAccount(provider, accountId) {
|
|
230
|
+
const existing = loadAccount(provider, accountId);
|
|
231
|
+
if (!existing)
|
|
232
|
+
return;
|
|
233
|
+
const next = {
|
|
234
|
+
...existing,
|
|
235
|
+
lastUsedAt: Date.now(),
|
|
236
|
+
};
|
|
237
|
+
atomicWriteJsonSync(accountFile(provider, accountId), next);
|
|
238
|
+
}
|
|
@@ -1,49 +1,69 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Credential storage and token refresh for subscription providers.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* Credentials live under `~/.eliza/auth/{providerId}/{accountId}.json`
|
|
5
|
+
* (see `account-storage.ts` for the on-disk format and atomic-write
|
|
6
|
+
* details). The `loadCredentials` / `saveCredentials` /
|
|
7
|
+
* `deleteCredentials` / `hasValidCredentials` / `getAccessToken`
|
|
8
|
+
* helpers all default to `accountId="default"` so callers that pre-date
|
|
9
|
+
* multi-account support keep working without changes.
|
|
5
10
|
*/
|
|
11
|
+
import { type AccountCredentialRecord } from "./account-storage.js";
|
|
6
12
|
import { type OAuthCredentials, type StoredCredentials, type SubscriptionProvider } from "./types.js";
|
|
7
13
|
/**
|
|
8
|
-
* Save credentials for a provider.
|
|
14
|
+
* Save credentials for a provider account.
|
|
15
|
+
*
|
|
16
|
+
* The `accountId` defaults to `"default"`. New accounts are persisted
|
|
17
|
+
* with `source: "oauth"` and `label: "Default"` (or the existing
|
|
18
|
+
* record's label when overwriting).
|
|
9
19
|
*/
|
|
10
|
-
export declare function saveCredentials(provider: SubscriptionProvider, credentials: OAuthCredentials): void;
|
|
20
|
+
export declare function saveCredentials(provider: SubscriptionProvider, credentials: OAuthCredentials, accountId?: string): void;
|
|
11
21
|
/**
|
|
12
|
-
* Load stored credentials for a provider.
|
|
22
|
+
* Load stored credentials for a provider account.
|
|
23
|
+
* Returns `null` when no account is configured for the given id.
|
|
13
24
|
*/
|
|
14
|
-
export declare function loadCredentials(provider: SubscriptionProvider): StoredCredentials | null;
|
|
25
|
+
export declare function loadCredentials(provider: SubscriptionProvider, accountId?: string): StoredCredentials | null;
|
|
15
26
|
/**
|
|
16
|
-
* Delete stored credentials for a provider.
|
|
27
|
+
* Delete stored credentials for a provider account.
|
|
17
28
|
*/
|
|
18
|
-
export declare function deleteCredentials(provider: SubscriptionProvider): void;
|
|
29
|
+
export declare function deleteCredentials(provider: SubscriptionProvider, accountId?: string): void;
|
|
19
30
|
/**
|
|
20
31
|
* Check if credentials exist and are not expired.
|
|
21
32
|
*/
|
|
22
|
-
export declare function hasValidCredentials(provider: SubscriptionProvider): boolean;
|
|
33
|
+
export declare function hasValidCredentials(provider: SubscriptionProvider, accountId?: string): boolean;
|
|
23
34
|
/**
|
|
24
|
-
*
|
|
25
|
-
* Returns null if no credentials stored or refresh fails.
|
|
35
|
+
* List all accounts configured for a provider.
|
|
26
36
|
*/
|
|
27
|
-
export declare function
|
|
37
|
+
export declare function listProviderAccounts(provider: SubscriptionProvider): AccountCredentialRecord[];
|
|
28
38
|
/**
|
|
29
|
-
* Get
|
|
39
|
+
* Get a valid access token, refreshing if needed.
|
|
40
|
+
*
|
|
41
|
+
* Refreshes are serialized per `{provider}:{accountId}` via
|
|
42
|
+
* `accountRefreshMutex` so concurrent callers don't race on the
|
|
43
|
+
* refresh-token grant or the credential file write.
|
|
30
44
|
*
|
|
31
|
-
*
|
|
32
|
-
* Claude Code OAuth credential blob exists on disk or in the keychain
|
|
33
|
-
* via `readClaudeCodeOAuthBlob()` (sync, no refresh) rather than
|
|
34
|
-
* calling `importClaudeCodeOAuthToken()` which is async and returns
|
|
35
|
-
* a `Promise<string | null>` that would always be truthy when
|
|
36
|
-
* awaited without `await` — silently marking every user as
|
|
37
|
-
* "configured: true".
|
|
45
|
+
* Returns `null` when no credentials are stored or the refresh fails.
|
|
38
46
|
*/
|
|
47
|
+
export declare function getAccessToken(provider: SubscriptionProvider, accountId?: string): Promise<string | null>;
|
|
39
48
|
export type SubscriptionCredentialSource = "app" | "claude-code-cli" | "setup-token" | "codex-cli" | null;
|
|
40
|
-
|
|
49
|
+
/**
|
|
50
|
+
* Per-account subscription status row used by the dashboard / API.
|
|
51
|
+
*
|
|
52
|
+
* One row is emitted per stored account for each provider. CLI- /
|
|
53
|
+
* setup-token-derived sources also produce a row with a synthetic
|
|
54
|
+
* `accountId` (e.g. `"claude-code-cli"`); those rows are read-only
|
|
55
|
+
* (they cannot be deleted via `DELETE /api/subscription/{provider}`).
|
|
56
|
+
*/
|
|
57
|
+
export interface SubscriptionAccountStatus {
|
|
41
58
|
provider: SubscriptionProvider;
|
|
59
|
+
accountId: string;
|
|
60
|
+
label: string;
|
|
42
61
|
configured: boolean;
|
|
43
62
|
valid: boolean;
|
|
44
63
|
expiresAt: number | null;
|
|
45
64
|
source: SubscriptionCredentialSource;
|
|
46
|
-
}
|
|
65
|
+
}
|
|
66
|
+
export declare function getSubscriptionStatus(): SubscriptionAccountStatus[];
|
|
47
67
|
/**
|
|
48
68
|
* Apply subscription credentials to the environment.
|
|
49
69
|
* Called at startup to make credentials available to elizaOS plugins.
|
|
@@ -58,10 +78,9 @@ export declare function getSubscriptionStatus(): Array<{
|
|
|
58
78
|
* Codex / ChatGPT subscription tokens *are* applied to the environment
|
|
59
79
|
* because OpenAI permits direct API usage with those tokens.
|
|
60
80
|
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
* to the runtime (currently Codex only).
|
|
81
|
+
* For multi-account installs the FIRST configured Codex account is the one
|
|
82
|
+
* applied to `process.env.OPENAI_API_KEY`. Real account selection lands in
|
|
83
|
+
* WS2 (AccountPool).
|
|
65
84
|
*/
|
|
66
85
|
export declare function applySubscriptionCredentials(config?: {
|
|
67
86
|
agents?: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../../../../src/auth/credentials.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../../../../src/auth/credentials.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAOH,OAAO,EACL,KAAK,uBAAuB,EAM7B,MAAM,sBAAsB,CAAC;AAI9B,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EAEtB,KAAK,oBAAoB,EAC1B,MAAM,YAAY,CAAC;AAsBpB;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,oBAAoB,EAC9B,WAAW,EAAE,gBAAgB,EAC7B,SAAS,GAAE,MAA2B,GACrC,IAAI,CAuBN;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,oBAAoB,EAC9B,SAAS,GAAE,MAA2B,GACrC,iBAAiB,GAAG,IAAI,CAI1B;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,oBAAoB,EAC9B,SAAS,GAAE,MAA2B,GACrC,IAAI,CAEN;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,oBAAoB,EAC9B,SAAS,GAAE,MAA2B,GACrC,OAAO,CAIT;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,oBAAoB,GAC7B,uBAAuB,EAAE,CAE3B;AAED;;;;;;;;GAQG;AACH,wBAAsB,cAAc,CAClC,QAAQ,EAAE,oBAAoB,EAC9B,SAAS,GAAE,MAA2B,GACrC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAyCxB;AAuCD,MAAM,MAAM,4BAA4B,GACpC,KAAK,GACL,iBAAiB,GACjB,aAAa,GACb,WAAW,GACX,IAAI,CAAC;AAET;;;;;;;GAOG;AACH,MAAM,WAAW,yBAAyB;IACxC,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,OAAO,CAAC;IACpB,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,MAAM,EAAE,4BAA4B,CAAC;CACtC;AAED,wBAAgB,qBAAqB,IAAI,yBAAyB,EAAE,CAwEnE;AA+ID;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,4BAA4B,CAAC,MAAM,CAAC,EAAE;IAC1D,MAAM,CAAC,EAAE;QACP,QAAQ,CAAC,EAAE;YAAE,oBAAoB,CAAC,EAAE,MAAM,CAAC;YAAC,KAAK,CAAC,EAAE;gBAAE,OAAO,CAAC,EAAE,MAAM,CAAA;aAAE,CAAA;SAAE,CAAC;KAC5E,CAAC;CACH,GAAG,OAAO,CAAC,IAAI,CAAC,CAmFhB"}
|