@elizaos/autonomous 2.0.0-alpha.10
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/LICENSE +21 -0
- package/package.json +270 -0
- package/src/actions/emote.ts +101 -0
- package/src/actions/restart.ts +101 -0
- package/src/actions/send-message.ts +168 -0
- package/src/actions/stream-control.ts +439 -0
- package/src/actions/switch-stream-source.ts +126 -0
- package/src/actions/terminal.ts +186 -0
- package/src/api/agent-admin-routes.ts +178 -0
- package/src/api/agent-lifecycle-routes.ts +129 -0
- package/src/api/agent-model.ts +143 -0
- package/src/api/agent-transfer-routes.ts +211 -0
- package/src/api/apps-routes.ts +210 -0
- package/src/api/auth-routes.ts +90 -0
- package/src/api/bsc-trade.ts +736 -0
- package/src/api/bug-report-routes.ts +161 -0
- package/src/api/character-routes.ts +421 -0
- package/src/api/cloud-billing-routes.ts +598 -0
- package/src/api/cloud-compat-routes.ts +192 -0
- package/src/api/cloud-routes.ts +529 -0
- package/src/api/cloud-status-routes.ts +234 -0
- package/src/api/compat-utils.ts +154 -0
- package/src/api/connector-health.ts +135 -0
- package/src/api/coordinator-wiring.ts +179 -0
- package/src/api/credit-detection.ts +47 -0
- package/src/api/database.ts +1357 -0
- package/src/api/diagnostics-routes.ts +389 -0
- package/src/api/drop-service.ts +205 -0
- package/src/api/early-logs.ts +111 -0
- package/src/api/http-helpers.ts +252 -0
- package/src/api/index.ts +85 -0
- package/src/api/knowledge-routes.ts +1189 -0
- package/src/api/knowledge-service-loader.ts +92 -0
- package/src/api/memory-bounds.ts +121 -0
- package/src/api/memory-routes.ts +349 -0
- package/src/api/merkle-tree.ts +239 -0
- package/src/api/models-routes.ts +72 -0
- package/src/api/nfa-routes.ts +169 -0
- package/src/api/nft-verify.ts +188 -0
- package/src/api/og-tracker.ts +72 -0
- package/src/api/parse-action-block.ts +145 -0
- package/src/api/permissions-routes.ts +222 -0
- package/src/api/plugin-validation.ts +355 -0
- package/src/api/provider-switch-config.ts +455 -0
- package/src/api/registry-routes.ts +165 -0
- package/src/api/registry-service.ts +292 -0
- package/src/api/route-helpers.ts +21 -0
- package/src/api/sandbox-routes.ts +1480 -0
- package/src/api/server.ts +17674 -0
- package/src/api/signal-routes.ts +265 -0
- package/src/api/stream-persistence.ts +297 -0
- package/src/api/stream-route-state.ts +48 -0
- package/src/api/stream-routes.ts +1046 -0
- package/src/api/stream-voice-routes.ts +208 -0
- package/src/api/streaming-text.ts +129 -0
- package/src/api/streaming-types.ts +23 -0
- package/src/api/subscription-routes.ts +283 -0
- package/src/api/terminal-run-limits.ts +31 -0
- package/src/api/training-backend-check.ts +40 -0
- package/src/api/training-routes.ts +314 -0
- package/src/api/training-service-like.ts +46 -0
- package/src/api/trajectory-routes.ts +714 -0
- package/src/api/trigger-routes.ts +438 -0
- package/src/api/twitter-verify.ts +226 -0
- package/src/api/tx-service.ts +193 -0
- package/src/api/wallet-dex-prices.ts +206 -0
- package/src/api/wallet-evm-balance.ts +989 -0
- package/src/api/wallet-routes.ts +505 -0
- package/src/api/wallet-rpc.ts +523 -0
- package/src/api/wallet-trading-profile.ts +694 -0
- package/src/api/wallet.ts +745 -0
- package/src/api/whatsapp-routes.ts +282 -0
- package/src/api/zip-utils.ts +130 -0
- package/src/auth/anthropic.ts +63 -0
- package/src/auth/apply-stealth.ts +38 -0
- package/src/auth/claude-code-stealth.ts +141 -0
- package/src/auth/credentials.ts +226 -0
- package/src/auth/index.ts +18 -0
- package/src/auth/openai-codex.ts +94 -0
- package/src/auth/types.ts +24 -0
- package/src/awareness/registry.ts +220 -0
- package/src/bin.ts +10 -0
- package/src/cli/index.ts +36 -0
- package/src/cli/parse-duration.ts +43 -0
- package/src/cloud/auth.test.ts +370 -0
- package/src/cloud/auth.ts +176 -0
- package/src/cloud/backup.test.ts +150 -0
- package/src/cloud/backup.ts +50 -0
- package/src/cloud/base-url.ts +45 -0
- package/src/cloud/bridge-client.test.ts +481 -0
- package/src/cloud/bridge-client.ts +307 -0
- package/src/cloud/cloud-manager.test.ts +223 -0
- package/src/cloud/cloud-manager.ts +151 -0
- package/src/cloud/cloud-proxy.test.ts +122 -0
- package/src/cloud/cloud-proxy.ts +52 -0
- package/src/cloud/index.ts +23 -0
- package/src/cloud/reconnect.test.ts +178 -0
- package/src/cloud/reconnect.ts +108 -0
- package/src/cloud/validate-url.test.ts +147 -0
- package/src/cloud/validate-url.ts +176 -0
- package/src/config/character-schema.ts +44 -0
- package/src/config/config.ts +149 -0
- package/src/config/env-vars.ts +86 -0
- package/src/config/includes.ts +196 -0
- package/src/config/index.ts +15 -0
- package/src/config/object-utils.ts +10 -0
- package/src/config/paths.ts +92 -0
- package/src/config/plugin-auto-enable.ts +520 -0
- package/src/config/schema.ts +1342 -0
- package/src/config/telegram-custom-commands.ts +99 -0
- package/src/config/types.agent-defaults.ts +342 -0
- package/src/config/types.agents.ts +112 -0
- package/src/config/types.gateway.ts +243 -0
- package/src/config/types.hooks.ts +124 -0
- package/src/config/types.messages.ts +201 -0
- package/src/config/types.milady.ts +791 -0
- package/src/config/types.tools.ts +416 -0
- package/src/config/types.ts +7 -0
- package/src/config/zod-schema.agent-runtime.ts +777 -0
- package/src/config/zod-schema.core.ts +778 -0
- package/src/config/zod-schema.hooks.ts +139 -0
- package/src/config/zod-schema.providers-core.ts +1126 -0
- package/src/config/zod-schema.session.ts +98 -0
- package/src/config/zod-schema.ts +865 -0
- package/src/contracts/apps.ts +46 -0
- package/src/contracts/awareness.ts +56 -0
- package/src/contracts/config.ts +172 -0
- package/src/contracts/drop.ts +21 -0
- package/src/contracts/index.ts +8 -0
- package/src/contracts/onboarding.ts +592 -0
- package/src/contracts/permissions.ts +52 -0
- package/src/contracts/verification.ts +9 -0
- package/src/contracts/wallet.ts +503 -0
- package/src/diagnostics/integration-observability.ts +132 -0
- package/src/emotes/catalog.ts +655 -0
- package/src/external-modules.d.ts +7 -0
- package/src/hooks/discovery.test.ts +357 -0
- package/src/hooks/discovery.ts +231 -0
- package/src/hooks/eligibility.ts +146 -0
- package/src/hooks/hooks.test.ts +320 -0
- package/src/hooks/index.ts +8 -0
- package/src/hooks/loader.test.ts +418 -0
- package/src/hooks/loader.ts +256 -0
- package/src/hooks/registry.test.ts +168 -0
- package/src/hooks/registry.ts +74 -0
- package/src/hooks/types.ts +121 -0
- package/src/index.ts +19 -0
- package/src/onboarding-presets.ts +828 -0
- package/src/plugins/custom-rtmp/index.ts +40 -0
- package/src/providers/admin-trust.ts +76 -0
- package/src/providers/session-bridge.ts +143 -0
- package/src/providers/session-utils.ts +42 -0
- package/src/providers/simple-mode.ts +113 -0
- package/src/providers/ui-catalog.ts +135 -0
- package/src/providers/workspace-provider.ts +213 -0
- package/src/providers/workspace.ts +497 -0
- package/src/runtime/agent-event-service.ts +57 -0
- package/src/runtime/cloud-onboarding.test.ts +489 -0
- package/src/runtime/cloud-onboarding.ts +408 -0
- package/src/runtime/core-plugins.ts +53 -0
- package/src/runtime/custom-actions.ts +605 -0
- package/src/runtime/eliza.ts +4941 -0
- package/src/runtime/embedding-presets.ts +73 -0
- package/src/runtime/index.ts +8 -0
- package/src/runtime/milady-plugin.ts +180 -0
- package/src/runtime/onboarding-names.ts +76 -0
- package/src/runtime/release-plugin-policy.ts +119 -0
- package/src/runtime/restart.ts +59 -0
- package/src/runtime/trajectory-persistence.ts +2584 -0
- package/src/runtime/version.ts +6 -0
- package/src/security/audit-log.ts +222 -0
- package/src/security/network-policy.ts +91 -0
- package/src/server/index.ts +6 -0
- package/src/services/agent-export.ts +976 -0
- package/src/services/app-manager.ts +755 -0
- package/src/services/browser-capture.ts +215 -0
- package/src/services/coding-agent-context.ts +355 -0
- package/src/services/fallback-training-service.ts +196 -0
- package/src/services/index.ts +17 -0
- package/src/services/mcp-marketplace.ts +327 -0
- package/src/services/plugin-manager-types.ts +185 -0
- package/src/services/privy-wallets.ts +352 -0
- package/src/services/registry-client-app-meta.ts +201 -0
- package/src/services/registry-client-endpoints.ts +253 -0
- package/src/services/registry-client-local.ts +485 -0
- package/src/services/registry-client-network.ts +173 -0
- package/src/services/registry-client-queries.ts +176 -0
- package/src/services/registry-client-types.ts +104 -0
- package/src/services/registry-client.ts +366 -0
- package/src/services/remote-signing-service.ts +261 -0
- package/src/services/sandbox-engine.ts +753 -0
- package/src/services/sandbox-manager.ts +503 -0
- package/src/services/self-updater.ts +213 -0
- package/src/services/signal-pairing.ts +189 -0
- package/src/services/signing-policy.ts +230 -0
- package/src/services/skill-catalog-client.ts +195 -0
- package/src/services/skill-marketplace.ts +909 -0
- package/src/services/stream-manager.ts +707 -0
- package/src/services/tts-stream-bridge.ts +465 -0
- package/src/services/update-checker.ts +163 -0
- package/src/services/version-compat.ts +367 -0
- package/src/services/whatsapp-pairing.ts +279 -0
- package/src/shared/ui-catalog-prompt.ts +1158 -0
- package/src/test-support/process-helpers.ts +35 -0
- package/src/test-support/route-test-helpers.ts +113 -0
- package/src/test-support/test-helpers.ts +304 -0
- package/src/testing/index.ts +3 -0
- package/src/triggers/action.ts +342 -0
- package/src/triggers/runtime.ts +432 -0
- package/src/triggers/scheduling.ts +472 -0
- package/src/triggers/types.ts +133 -0
- package/src/types/app-hyperscape-routes-shim.d.ts +29 -0
- package/src/types/external-modules.d.ts +7 -0
- package/src/utils/exec-safety.ts +23 -0
- package/src/utils/number-parsing.ts +112 -0
- package/src/utils/spoken-text.ts +65 -0
- package/src/version-resolver.ts +60 -0
- package/test/api/agent-admin-routes.test.ts +160 -0
- package/test/api/agent-lifecycle-routes.test.ts +164 -0
- package/test/api/agent-transfer-routes.test.ts +136 -0
- package/test/api/apps-routes.test.ts +140 -0
- package/test/api/auth-routes.test.ts +160 -0
- package/test/api/bug-report-routes.test.ts +88 -0
- package/test/api/knowledge-routes.test.ts +73 -0
- package/test/api/lifecycle.test.ts +342 -0
- package/test/api/memory-routes.test.ts +74 -0
- package/test/api/models-routes.test.ts +112 -0
- package/test/api/nfa-routes.test.ts +78 -0
- package/test/api/permissions-routes.test.ts +185 -0
- package/test/api/registry-routes.test.ts +157 -0
- package/test/api/signal-routes.test.ts +113 -0
- package/test/api/subscription-routes.test.ts +90 -0
- package/test/api/trigger-routes.test.ts +87 -0
- package/test/api/wallet-routes.observability.test.ts +191 -0
- package/test/api/wallet-routes.test.ts +502 -0
- package/test/diagnostics/integration-observability.test.ts +135 -0
- package/test/security/audit-log.test.ts +229 -0
- package/test/security/network-policy.test.ts +143 -0
- package/test/services/version-compat.test.ts +127 -0
- package/tsconfig.build.json +21 -0
- package/tsconfig.json +19 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { UUID } from "@elizaos/core";
|
|
2
|
+
|
|
3
|
+
export interface AgentEventPayloadLike {
|
|
4
|
+
runId: string;
|
|
5
|
+
seq: number;
|
|
6
|
+
stream: string;
|
|
7
|
+
ts: number;
|
|
8
|
+
data: Record<string, unknown>;
|
|
9
|
+
sessionKey?: string;
|
|
10
|
+
agentId?: string;
|
|
11
|
+
roomId?: UUID;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface HeartbeatEventPayloadLike {
|
|
15
|
+
ts: number;
|
|
16
|
+
status: string;
|
|
17
|
+
to?: string;
|
|
18
|
+
preview?: string;
|
|
19
|
+
durationMs?: number;
|
|
20
|
+
hasMedia?: boolean;
|
|
21
|
+
reason?: string;
|
|
22
|
+
channel?: string;
|
|
23
|
+
silent?: boolean;
|
|
24
|
+
indicatorType?: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface AgentEventServiceLike {
|
|
28
|
+
subscribe: (listener: (event: AgentEventPayloadLike) => void) => () => void;
|
|
29
|
+
subscribeHeartbeat: (
|
|
30
|
+
listener: (event: HeartbeatEventPayloadLike) => void,
|
|
31
|
+
) => () => void;
|
|
32
|
+
getLastHeartbeat?: () => HeartbeatEventPayloadLike | null;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
type RuntimeWithServiceGetter = {
|
|
36
|
+
getService: (serviceType: string) => unknown | null;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export const AGENT_EVENT_SERVICE_TYPES = [
|
|
40
|
+
"agent_event",
|
|
41
|
+
"AGENT_EVENT",
|
|
42
|
+
] as const;
|
|
43
|
+
|
|
44
|
+
export function getAgentEventService(
|
|
45
|
+
runtime: RuntimeWithServiceGetter | null | undefined,
|
|
46
|
+
): AgentEventServiceLike | null {
|
|
47
|
+
if (!runtime) return null;
|
|
48
|
+
|
|
49
|
+
for (const serviceType of AGENT_EVENT_SERVICE_TYPES) {
|
|
50
|
+
const service = runtime.getService(serviceType);
|
|
51
|
+
if (service) {
|
|
52
|
+
return service as AgentEventServiceLike;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
@@ -0,0 +1,489 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for cloud-onboarding.ts
|
|
3
|
+
*
|
|
4
|
+
* Mocks fetch, @clack/prompts, and the cloud auth/bridge modules to verify
|
|
5
|
+
* the orchestration logic without requiring a live Eliza Cloud instance.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
afterEach,
|
|
10
|
+
assert,
|
|
11
|
+
beforeEach,
|
|
12
|
+
describe,
|
|
13
|
+
expect,
|
|
14
|
+
it,
|
|
15
|
+
vi,
|
|
16
|
+
} from "vitest";
|
|
17
|
+
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
// Module-level mocks — must be declared before any imports that pull in
|
|
20
|
+
// the module under test.
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
|
|
23
|
+
// Mock the cloud auth module
|
|
24
|
+
const mockCloudLogin = vi.fn();
|
|
25
|
+
vi.mock("../cloud/auth", () => ({
|
|
26
|
+
cloudLogin: (...args: unknown[]) => mockCloudLogin(...args),
|
|
27
|
+
}));
|
|
28
|
+
|
|
29
|
+
// Mock the cloud bridge client
|
|
30
|
+
const mockCreateAgent = vi.fn();
|
|
31
|
+
const mockGetAgent = vi.fn();
|
|
32
|
+
vi.mock("../cloud/bridge-client", () => ({
|
|
33
|
+
ElizaCloudClient: class {
|
|
34
|
+
createAgent = mockCreateAgent;
|
|
35
|
+
getAgent = mockGetAgent;
|
|
36
|
+
},
|
|
37
|
+
}));
|
|
38
|
+
|
|
39
|
+
// ---------------------------------------------------------------------------
|
|
40
|
+
// Import after mocks are set up
|
|
41
|
+
// ---------------------------------------------------------------------------
|
|
42
|
+
|
|
43
|
+
import {
|
|
44
|
+
type CloudOnboardingResult,
|
|
45
|
+
checkCloudAvailability,
|
|
46
|
+
runCloudOnboarding,
|
|
47
|
+
} from "./cloud-onboarding";
|
|
48
|
+
|
|
49
|
+
// ---------------------------------------------------------------------------
|
|
50
|
+
// Helpers — fake @clack/prompts module
|
|
51
|
+
// ---------------------------------------------------------------------------
|
|
52
|
+
|
|
53
|
+
function makeClack(
|
|
54
|
+
overrides: { selectReturn?: string; confirmReturns?: boolean[] } = {},
|
|
55
|
+
) {
|
|
56
|
+
const { selectReturn = "cloud", confirmReturns = [] } = overrides;
|
|
57
|
+
let confirmIdx = 0;
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
log: {
|
|
61
|
+
info: vi.fn(),
|
|
62
|
+
warn: vi.fn(),
|
|
63
|
+
success: vi.fn(),
|
|
64
|
+
error: vi.fn(),
|
|
65
|
+
message: vi.fn(),
|
|
66
|
+
},
|
|
67
|
+
spinner: () => ({
|
|
68
|
+
start: vi.fn(),
|
|
69
|
+
stop: vi.fn(),
|
|
70
|
+
message: vi.fn(),
|
|
71
|
+
}),
|
|
72
|
+
select: vi.fn().mockResolvedValue(selectReturn),
|
|
73
|
+
confirm: vi.fn().mockImplementation(() => {
|
|
74
|
+
const val = confirmReturns[confirmIdx] ?? true;
|
|
75
|
+
confirmIdx++;
|
|
76
|
+
return Promise.resolve(val);
|
|
77
|
+
}),
|
|
78
|
+
isCancel: vi.fn().mockReturnValue(false),
|
|
79
|
+
} as unknown as typeof import("@clack/prompts");
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// ---------------------------------------------------------------------------
|
|
83
|
+
// checkCloudAvailability
|
|
84
|
+
// ---------------------------------------------------------------------------
|
|
85
|
+
|
|
86
|
+
describe("checkCloudAvailability", () => {
|
|
87
|
+
const originalFetch = globalThis.fetch;
|
|
88
|
+
|
|
89
|
+
afterEach(() => {
|
|
90
|
+
globalThis.fetch = originalFetch;
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it("returns null when cloud is accepting new agents", async () => {
|
|
94
|
+
globalThis.fetch = vi.fn().mockResolvedValue({
|
|
95
|
+
ok: true,
|
|
96
|
+
json: async () => ({
|
|
97
|
+
success: true,
|
|
98
|
+
data: { acceptingNewAgents: true, availableSlots: 5 },
|
|
99
|
+
}),
|
|
100
|
+
}) as unknown as typeof fetch;
|
|
101
|
+
|
|
102
|
+
const result = await checkCloudAvailability("https://www.elizacloud.ai");
|
|
103
|
+
expect(result).toBeNull();
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
it("returns error message when cloud is at capacity", async () => {
|
|
107
|
+
globalThis.fetch = vi.fn().mockResolvedValue({
|
|
108
|
+
ok: true,
|
|
109
|
+
json: async () => ({
|
|
110
|
+
success: true,
|
|
111
|
+
data: { acceptingNewAgents: false, availableSlots: 0 },
|
|
112
|
+
}),
|
|
113
|
+
}) as unknown as typeof fetch;
|
|
114
|
+
|
|
115
|
+
const result = await checkCloudAvailability("https://www.elizacloud.ai");
|
|
116
|
+
expect(result).toContain("at capacity");
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
it("returns error message when cloud returns HTTP error", async () => {
|
|
120
|
+
globalThis.fetch = vi.fn().mockResolvedValue({
|
|
121
|
+
ok: false,
|
|
122
|
+
status: 503,
|
|
123
|
+
}) as unknown as typeof fetch;
|
|
124
|
+
|
|
125
|
+
const result = await checkCloudAvailability("https://www.elizacloud.ai");
|
|
126
|
+
expect(result).toContain("503");
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
it("returns error message when fetch throws (network error)", async () => {
|
|
130
|
+
globalThis.fetch = vi
|
|
131
|
+
.fn()
|
|
132
|
+
.mockRejectedValue(new Error("ECONNREFUSED")) as unknown as typeof fetch;
|
|
133
|
+
|
|
134
|
+
const result = await checkCloudAvailability("https://www.elizacloud.ai");
|
|
135
|
+
expect(result).toContain("ECONNREFUSED");
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
it("returns timeout message on timeout", async () => {
|
|
139
|
+
const err = new Error("timed out");
|
|
140
|
+
err.name = "TimeoutError";
|
|
141
|
+
globalThis.fetch = vi
|
|
142
|
+
.fn()
|
|
143
|
+
.mockRejectedValue(err) as unknown as typeof fetch;
|
|
144
|
+
|
|
145
|
+
const result = await checkCloudAvailability("https://www.elizacloud.ai");
|
|
146
|
+
expect(result).toContain("timed out");
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
it("normalises the base URL before fetching", async () => {
|
|
150
|
+
const mockFetch = vi.fn().mockResolvedValue({
|
|
151
|
+
ok: true,
|
|
152
|
+
json: async () => ({
|
|
153
|
+
success: true,
|
|
154
|
+
data: { acceptingNewAgents: true, availableSlots: 1 },
|
|
155
|
+
}),
|
|
156
|
+
}) as unknown as typeof fetch;
|
|
157
|
+
globalThis.fetch = mockFetch;
|
|
158
|
+
|
|
159
|
+
await checkCloudAvailability("https://elizacloud.ai/api/v1/");
|
|
160
|
+
|
|
161
|
+
// normalizeCloudSiteUrl should strip the /api/v1 and add www
|
|
162
|
+
const calledUrl = (mockFetch as unknown as ReturnType<typeof vi.fn>).mock
|
|
163
|
+
.calls[0][0];
|
|
164
|
+
expect(calledUrl).toContain("www.elizacloud.ai");
|
|
165
|
+
expect(calledUrl).toContain("/api/compat/availability");
|
|
166
|
+
expect(calledUrl).not.toContain("/api/v1/api/compat");
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
// ---------------------------------------------------------------------------
|
|
171
|
+
// runCloudOnboarding
|
|
172
|
+
// ---------------------------------------------------------------------------
|
|
173
|
+
|
|
174
|
+
describe("runCloudOnboarding", () => {
|
|
175
|
+
const originalFetch = globalThis.fetch;
|
|
176
|
+
|
|
177
|
+
beforeEach(() => {
|
|
178
|
+
mockCloudLogin.mockReset();
|
|
179
|
+
mockCreateAgent.mockReset();
|
|
180
|
+
mockGetAgent.mockReset();
|
|
181
|
+
|
|
182
|
+
// Default: cloud is available
|
|
183
|
+
globalThis.fetch = vi.fn().mockResolvedValue({
|
|
184
|
+
ok: true,
|
|
185
|
+
json: async () => ({
|
|
186
|
+
success: true,
|
|
187
|
+
data: { acceptingNewAgents: true, availableSlots: 5 },
|
|
188
|
+
}),
|
|
189
|
+
}) as unknown as typeof fetch;
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
afterEach(() => {
|
|
193
|
+
globalThis.fetch = originalFetch;
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
it("returns full result when auth + provisioning succeed", async () => {
|
|
197
|
+
const clack = makeClack();
|
|
198
|
+
|
|
199
|
+
mockCloudLogin.mockResolvedValue({
|
|
200
|
+
apiKey: "test-key-123",
|
|
201
|
+
keyPrefix: "test",
|
|
202
|
+
expiresAt: null,
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
mockCreateAgent.mockResolvedValue({
|
|
206
|
+
id: "agent-abc",
|
|
207
|
+
status: "running",
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
mockGetAgent.mockResolvedValue({
|
|
211
|
+
status: "running",
|
|
212
|
+
bridgeUrl: "https://bridge.example.com",
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
const result = await runCloudOnboarding(
|
|
216
|
+
clack,
|
|
217
|
+
"TestAgent",
|
|
218
|
+
undefined,
|
|
219
|
+
"https://www.elizacloud.ai",
|
|
220
|
+
);
|
|
221
|
+
|
|
222
|
+
assert(result != null, "expected a non-null result");
|
|
223
|
+
expect(result.apiKey).toBe("test-key-123");
|
|
224
|
+
expect(result.agentId).toBe("agent-abc");
|
|
225
|
+
expect(result.baseUrl).toContain("elizacloud.ai");
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
it("returns null when cloud is unavailable and user falls back to local", async () => {
|
|
229
|
+
const clack = makeClack({ confirmReturns: [true] }); // "run locally?"
|
|
230
|
+
|
|
231
|
+
globalThis.fetch = vi.fn().mockResolvedValue({
|
|
232
|
+
ok: true,
|
|
233
|
+
json: async () => ({
|
|
234
|
+
success: true,
|
|
235
|
+
data: { acceptingNewAgents: false, availableSlots: 0 },
|
|
236
|
+
}),
|
|
237
|
+
}) as unknown as typeof fetch;
|
|
238
|
+
|
|
239
|
+
const result = await runCloudOnboarding(
|
|
240
|
+
clack,
|
|
241
|
+
"TestAgent",
|
|
242
|
+
undefined,
|
|
243
|
+
"https://www.elizacloud.ai",
|
|
244
|
+
);
|
|
245
|
+
|
|
246
|
+
expect(result).toBeNull();
|
|
247
|
+
expect(mockCloudLogin).not.toHaveBeenCalled();
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
it("returns null when auth fails and user declines retry", async () => {
|
|
251
|
+
const clack = makeClack({ confirmReturns: [false] }); // "run locally" (cancel)
|
|
252
|
+
|
|
253
|
+
mockCloudLogin.mockResolvedValue(null);
|
|
254
|
+
|
|
255
|
+
const result = await runCloudOnboarding(
|
|
256
|
+
clack,
|
|
257
|
+
"TestAgent",
|
|
258
|
+
undefined,
|
|
259
|
+
"https://www.elizacloud.ai",
|
|
260
|
+
);
|
|
261
|
+
|
|
262
|
+
expect(result).toBeNull();
|
|
263
|
+
expect(mockCloudLogin).toHaveBeenCalledTimes(1);
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
it("retries auth once when user requests it", async () => {
|
|
267
|
+
const clack = makeClack({ confirmReturns: [true] }); // "try again"
|
|
268
|
+
|
|
269
|
+
// First attempt fails, second succeeds
|
|
270
|
+
mockCloudLogin.mockResolvedValueOnce(null).mockResolvedValueOnce({
|
|
271
|
+
apiKey: "retry-key",
|
|
272
|
+
keyPrefix: "retry",
|
|
273
|
+
expiresAt: null,
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
mockCreateAgent.mockResolvedValue({
|
|
277
|
+
id: "agent-retry",
|
|
278
|
+
status: "running",
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
mockGetAgent.mockResolvedValue({
|
|
282
|
+
status: "running",
|
|
283
|
+
bridgeUrl: "https://bridge.example.com",
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
const result = await runCloudOnboarding(
|
|
287
|
+
clack,
|
|
288
|
+
"TestAgent",
|
|
289
|
+
undefined,
|
|
290
|
+
"https://www.elizacloud.ai",
|
|
291
|
+
);
|
|
292
|
+
|
|
293
|
+
expect(mockCloudLogin).toHaveBeenCalledTimes(2);
|
|
294
|
+
assert(result != null, "expected a non-null result after retry");
|
|
295
|
+
expect(result.apiKey).toBe("retry-key");
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
it("returns auth-only result (agentId undefined) when provisioning fails and user declines local", async () => {
|
|
299
|
+
// User declines "continue with local setup?" AND declines "run locally?"
|
|
300
|
+
const clack = makeClack({ confirmReturns: [false] });
|
|
301
|
+
|
|
302
|
+
mockCloudLogin.mockResolvedValue({
|
|
303
|
+
apiKey: "auth-only-key",
|
|
304
|
+
keyPrefix: "auth",
|
|
305
|
+
expiresAt: null,
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
// provisionCloudAgent fails
|
|
309
|
+
mockCreateAgent.mockRejectedValue(new Error("quota exceeded"));
|
|
310
|
+
|
|
311
|
+
const result = await runCloudOnboarding(
|
|
312
|
+
clack,
|
|
313
|
+
"TestAgent",
|
|
314
|
+
undefined,
|
|
315
|
+
"https://www.elizacloud.ai",
|
|
316
|
+
);
|
|
317
|
+
|
|
318
|
+
assert(result != null, "expected a non-null auth-only result");
|
|
319
|
+
expect(result.apiKey).toBe("auth-only-key");
|
|
320
|
+
expect(result.agentId).toBeUndefined();
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
it("returns null when provisioning fails and user wants local", async () => {
|
|
324
|
+
const clack = makeClack({ confirmReturns: [true] }); // "continue with local?"
|
|
325
|
+
|
|
326
|
+
mockCloudLogin.mockResolvedValue({
|
|
327
|
+
apiKey: "key-123",
|
|
328
|
+
keyPrefix: "k",
|
|
329
|
+
expiresAt: null,
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
mockCreateAgent.mockRejectedValue(new Error("server error"));
|
|
333
|
+
|
|
334
|
+
const result = await runCloudOnboarding(
|
|
335
|
+
clack,
|
|
336
|
+
"TestAgent",
|
|
337
|
+
undefined,
|
|
338
|
+
"https://www.elizacloud.ai",
|
|
339
|
+
);
|
|
340
|
+
|
|
341
|
+
expect(result).toBeNull();
|
|
342
|
+
});
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
// ---------------------------------------------------------------------------
|
|
346
|
+
// provisionCloudAgent — tested indirectly via runCloudOnboarding
|
|
347
|
+
// ---------------------------------------------------------------------------
|
|
348
|
+
|
|
349
|
+
describe("provisionCloudAgent (via runCloudOnboarding)", () => {
|
|
350
|
+
const originalFetch = globalThis.fetch;
|
|
351
|
+
|
|
352
|
+
beforeEach(() => {
|
|
353
|
+
mockCloudLogin.mockReset();
|
|
354
|
+
mockCreateAgent.mockReset();
|
|
355
|
+
mockGetAgent.mockReset();
|
|
356
|
+
|
|
357
|
+
// Cloud is available
|
|
358
|
+
globalThis.fetch = vi.fn().mockResolvedValue({
|
|
359
|
+
ok: true,
|
|
360
|
+
json: async () => ({
|
|
361
|
+
success: true,
|
|
362
|
+
data: { acceptingNewAgents: true, availableSlots: 5 },
|
|
363
|
+
}),
|
|
364
|
+
}) as unknown as typeof fetch;
|
|
365
|
+
|
|
366
|
+
// Auth always succeeds
|
|
367
|
+
mockCloudLogin.mockResolvedValue({
|
|
368
|
+
apiKey: "test-key",
|
|
369
|
+
keyPrefix: "test",
|
|
370
|
+
expiresAt: null,
|
|
371
|
+
});
|
|
372
|
+
});
|
|
373
|
+
|
|
374
|
+
afterEach(() => {
|
|
375
|
+
globalThis.fetch = originalFetch;
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
it("polls until agent reaches running status", async () => {
|
|
379
|
+
const clack = makeClack();
|
|
380
|
+
|
|
381
|
+
mockCreateAgent.mockResolvedValue({
|
|
382
|
+
id: "agent-poll",
|
|
383
|
+
status: "provisioning",
|
|
384
|
+
});
|
|
385
|
+
|
|
386
|
+
// First poll: still provisioning. Second poll: running.
|
|
387
|
+
mockGetAgent
|
|
388
|
+
.mockResolvedValueOnce({ status: "provisioning" })
|
|
389
|
+
.mockResolvedValueOnce({
|
|
390
|
+
status: "running",
|
|
391
|
+
bridgeUrl: "https://bridge.test",
|
|
392
|
+
});
|
|
393
|
+
|
|
394
|
+
const result = await runCloudOnboarding(
|
|
395
|
+
clack,
|
|
396
|
+
"PollAgent",
|
|
397
|
+
undefined,
|
|
398
|
+
"https://www.elizacloud.ai",
|
|
399
|
+
);
|
|
400
|
+
|
|
401
|
+
assert(result != null, "expected a non-null result after polling");
|
|
402
|
+
expect(result.agentId).toBe("agent-poll");
|
|
403
|
+
expect(result.bridgeUrl).toBe("https://bridge.test");
|
|
404
|
+
expect(mockGetAgent).toHaveBeenCalledTimes(2);
|
|
405
|
+
});
|
|
406
|
+
|
|
407
|
+
it("returns null when agent provisioning fails with error status", async () => {
|
|
408
|
+
const clack = makeClack({ confirmReturns: [true] }); // fall back to local
|
|
409
|
+
|
|
410
|
+
mockCreateAgent.mockResolvedValue({
|
|
411
|
+
id: "agent-fail",
|
|
412
|
+
status: "provisioning",
|
|
413
|
+
});
|
|
414
|
+
|
|
415
|
+
mockGetAgent.mockResolvedValue({
|
|
416
|
+
status: "failed",
|
|
417
|
+
errorMessage: "out of resources",
|
|
418
|
+
});
|
|
419
|
+
|
|
420
|
+
const result = await runCloudOnboarding(
|
|
421
|
+
clack,
|
|
422
|
+
"FailAgent",
|
|
423
|
+
undefined,
|
|
424
|
+
"https://www.elizacloud.ai",
|
|
425
|
+
);
|
|
426
|
+
|
|
427
|
+
// Falls back to null because user chose local
|
|
428
|
+
expect(result).toBeNull();
|
|
429
|
+
});
|
|
430
|
+
|
|
431
|
+
it("passes style preset through to createAgent", async () => {
|
|
432
|
+
const clack = makeClack();
|
|
433
|
+
|
|
434
|
+
mockCreateAgent.mockResolvedValue({
|
|
435
|
+
id: "agent-styled",
|
|
436
|
+
status: "running",
|
|
437
|
+
});
|
|
438
|
+
|
|
439
|
+
mockGetAgent.mockResolvedValue({
|
|
440
|
+
status: "running",
|
|
441
|
+
bridgeUrl: "https://bridge.test",
|
|
442
|
+
});
|
|
443
|
+
|
|
444
|
+
const preset = {
|
|
445
|
+
catchphrase: "test",
|
|
446
|
+
bio: ["A test agent"],
|
|
447
|
+
system: "You are a test agent.",
|
|
448
|
+
adjectives: ["testy"],
|
|
449
|
+
topics: ["testing"],
|
|
450
|
+
};
|
|
451
|
+
|
|
452
|
+
await runCloudOnboarding(
|
|
453
|
+
clack,
|
|
454
|
+
"StyledAgent",
|
|
455
|
+
preset as Parameters<typeof runCloudOnboarding>[2],
|
|
456
|
+
"https://www.elizacloud.ai",
|
|
457
|
+
);
|
|
458
|
+
|
|
459
|
+
expect(mockCreateAgent).toHaveBeenCalledTimes(1);
|
|
460
|
+
const params = mockCreateAgent.mock.calls[0][0];
|
|
461
|
+
expect(params.agentName).toBe("StyledAgent");
|
|
462
|
+
expect(params.agentConfig.bio).toEqual(["A test agent"]);
|
|
463
|
+
expect(params.agentConfig.system).toBe("You are a test agent.");
|
|
464
|
+
});
|
|
465
|
+
});
|
|
466
|
+
|
|
467
|
+
// ---------------------------------------------------------------------------
|
|
468
|
+
// CloudOnboardingResult interface
|
|
469
|
+
// ---------------------------------------------------------------------------
|
|
470
|
+
|
|
471
|
+
describe("CloudOnboardingResult", () => {
|
|
472
|
+
it("agentId accepts string value", () => {
|
|
473
|
+
const result: CloudOnboardingResult = {
|
|
474
|
+
apiKey: "key",
|
|
475
|
+
agentId: "agent-123",
|
|
476
|
+
baseUrl: "https://example.com",
|
|
477
|
+
};
|
|
478
|
+
expect(result.agentId).toBe("agent-123");
|
|
479
|
+
});
|
|
480
|
+
|
|
481
|
+
it("agentId accepts undefined", () => {
|
|
482
|
+
const result: CloudOnboardingResult = {
|
|
483
|
+
apiKey: "key",
|
|
484
|
+
agentId: undefined,
|
|
485
|
+
baseUrl: "https://example.com",
|
|
486
|
+
};
|
|
487
|
+
expect(result.agentId).toBeUndefined();
|
|
488
|
+
});
|
|
489
|
+
});
|