@vybestack/llxprt-code 0.4.8 → 0.5.0-nightly.251102.6bb3db7a
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/dist/package.json +5 -3
- package/dist/src/auth/__tests__/oauthManager.safety.test.d.ts +6 -0
- package/dist/src/auth/__tests__/oauthManager.safety.test.js +49 -0
- package/dist/src/auth/__tests__/oauthManager.safety.test.js.map +1 -0
- package/dist/src/auth/oauth-manager.d.ts +11 -0
- package/dist/src/auth/oauth-manager.js +62 -29
- package/dist/src/auth/oauth-manager.js.map +1 -1
- package/dist/src/auth/oauth-manager.spec.js +7 -2
- package/dist/src/auth/oauth-manager.spec.js.map +1 -1
- package/dist/src/config/__tests__/nonInteractiveTools.test.d.ts +6 -0
- package/dist/src/config/__tests__/nonInteractiveTools.test.js +13 -0
- package/dist/src/config/__tests__/nonInteractiveTools.test.js.map +1 -0
- package/dist/src/config/__tests__/profileBootstrap.test.d.ts +6 -0
- package/dist/src/config/__tests__/profileBootstrap.test.js +91 -0
- package/dist/src/config/__tests__/profileBootstrap.test.js.map +1 -0
- package/dist/src/config/config.d.ts +6 -2
- package/dist/src/config/config.js +219 -18
- package/dist/src/config/config.js.map +1 -1
- package/dist/src/config/profileBootstrap.d.ts +64 -0
- package/dist/src/config/profileBootstrap.js +140 -0
- package/dist/src/config/profileBootstrap.js.map +1 -0
- package/dist/src/gemini.js +68 -23
- package/dist/src/gemini.js.map +1 -1
- package/dist/src/gemini.test.js +1 -2
- package/dist/src/gemini.test.js.map +1 -1
- package/dist/src/generated/git-commit.d.ts +1 -1
- package/dist/src/generated/git-commit.js +1 -1
- package/dist/src/integration-tests/base-url-behavior.integration.test.js +110 -450
- package/dist/src/integration-tests/base-url-behavior.integration.test.js.map +1 -1
- package/dist/src/integration-tests/model-params-isolation.integration.test.js +101 -539
- package/dist/src/integration-tests/model-params-isolation.integration.test.js.map +1 -1
- package/dist/src/integration-tests/modelParams.integration.test.js +86 -761
- package/dist/src/integration-tests/modelParams.integration.test.js.map +1 -1
- package/dist/src/integration-tests/provider-multi-runtime.integration.test.d.ts +6 -0
- package/dist/src/integration-tests/provider-multi-runtime.integration.test.js +198 -0
- package/dist/src/integration-tests/provider-multi-runtime.integration.test.js.map +1 -0
- package/dist/src/integration-tests/provider-switching.integration.test.js +97 -151
- package/dist/src/integration-tests/provider-switching.integration.test.js.map +1 -1
- package/dist/src/integration-tests/runtime-isolation.test.d.ts +13 -0
- package/dist/src/integration-tests/runtime-isolation.test.js +170 -0
- package/dist/src/integration-tests/runtime-isolation.test.js.map +1 -0
- package/dist/src/integration-tests/test-utils.js +19 -2
- package/dist/src/integration-tests/test-utils.js.map +1 -1
- package/dist/src/integration-tests/test-utils.test.js +9 -8
- package/dist/src/integration-tests/test-utils.test.js.map +1 -1
- package/dist/src/integration-tests/todo-continuation.integration.test.js +5 -2
- package/dist/src/integration-tests/todo-continuation.integration.test.js.map +1 -1
- package/dist/src/integration-tests/tools-governance.integration.test.d.ts +6 -0
- package/dist/src/integration-tests/tools-governance.integration.test.js +98 -0
- package/dist/src/integration-tests/tools-governance.integration.test.js.map +1 -0
- package/dist/src/nonInteractiveCli.js +36 -11
- package/dist/src/nonInteractiveCli.js.map +1 -1
- package/dist/src/providers/logging/git-stats.test.js +11 -1
- package/dist/src/providers/logging/git-stats.test.js.map +1 -1
- package/dist/src/providers/logging/multi-provider-logging.integration.test.js +1 -2
- package/dist/src/providers/logging/multi-provider-logging.integration.test.js.map +1 -1
- package/dist/src/providers/logging/performance.test.js +1 -1
- package/dist/src/providers/logging/performance.test.js.map +1 -1
- package/dist/src/providers/oauth-provider-registration.d.ts +2 -2
- package/dist/src/providers/oauth-provider-registration.js +25 -9
- package/dist/src/providers/oauth-provider-registration.js.map +1 -1
- package/dist/src/providers/provider-gemini-switching.test.js +67 -89
- package/dist/src/providers/provider-gemini-switching.test.js.map +1 -1
- package/dist/src/providers/provider-switching.integration.test.js +42 -98
- package/dist/src/providers/provider-switching.integration.test.js.map +1 -1
- package/dist/src/providers/providerConfigUtils.d.ts +12 -7
- package/dist/src/providers/providerConfigUtils.js +31 -99
- package/dist/src/providers/providerConfigUtils.js.map +1 -1
- package/dist/src/providers/providerManagerInstance.d.ts +17 -1
- package/dist/src/providers/providerManagerInstance.js +157 -175
- package/dist/src/providers/providerManagerInstance.js.map +1 -1
- package/dist/src/providers/providerManagerInstance.oauthRegistration.test.js +19 -15
- package/dist/src/providers/providerManagerInstance.oauthRegistration.test.js.map +1 -1
- package/dist/src/providers/providerManagerInstance.test.js +2 -5
- package/dist/src/providers/providerManagerInstance.test.js.map +1 -1
- package/dist/src/runtime/__tests__/profileApplication.test.d.ts +5 -0
- package/dist/src/runtime/__tests__/profileApplication.test.js +232 -0
- package/dist/src/runtime/__tests__/profileApplication.test.js.map +1 -0
- package/dist/src/runtime/__tests__/runtimeIsolation.test.d.ts +5 -0
- package/dist/src/runtime/__tests__/runtimeIsolation.test.js +376 -0
- package/dist/src/runtime/__tests__/runtimeIsolation.test.js.map +1 -0
- package/dist/src/runtime/agentRuntimeAdapter.d.ts +249 -0
- package/dist/src/runtime/agentRuntimeAdapter.js +506 -0
- package/dist/src/runtime/agentRuntimeAdapter.js.map +1 -0
- package/dist/src/runtime/agentRuntimeAdapter.spec.d.ts +6 -0
- package/dist/src/runtime/agentRuntimeAdapter.spec.js +866 -0
- package/dist/src/runtime/agentRuntimeAdapter.spec.js.map +1 -0
- package/dist/src/runtime/messages.d.ts +28 -0
- package/dist/src/runtime/messages.js +64 -0
- package/dist/src/runtime/messages.js.map +1 -0
- package/dist/src/runtime/profileApplication.d.ts +33 -0
- package/dist/src/runtime/profileApplication.js +191 -0
- package/dist/src/runtime/profileApplication.js.map +1 -0
- package/dist/src/runtime/providerConfigUtils.test.d.ts +1 -0
- package/dist/src/runtime/providerConfigUtils.test.js +68 -0
- package/dist/src/runtime/providerConfigUtils.test.js.map +1 -0
- package/dist/src/runtime/runtimeContextFactory.d.ts +102 -0
- package/dist/src/runtime/runtimeContextFactory.js +190 -0
- package/dist/src/runtime/runtimeContextFactory.js.map +1 -0
- package/dist/src/runtime/runtimeSettings.d.ts +217 -0
- package/dist/src/runtime/runtimeSettings.js +1094 -0
- package/dist/src/runtime/runtimeSettings.js.map +1 -0
- package/dist/src/runtime/runtimeSettings.test.d.ts +1 -0
- package/dist/src/runtime/runtimeSettings.test.js +320 -0
- package/dist/src/runtime/runtimeSettings.test.js.map +1 -0
- package/dist/src/services/BuiltinCommandLoader.d.ts +13 -4
- package/dist/src/services/BuiltinCommandLoader.js +17 -4
- package/dist/src/services/BuiltinCommandLoader.js.map +1 -1
- package/dist/src/services/McpPromptLoader.js +34 -13
- package/dist/src/services/McpPromptLoader.js.map +1 -1
- package/dist/src/test-utils/mockCommandContext.js +5 -2
- package/dist/src/test-utils/mockCommandContext.js.map +1 -1
- package/dist/src/ui/App.js +29 -49
- package/dist/src/ui/App.js.map +1 -1
- package/dist/src/ui/commands/aboutCommand.js +59 -38
- package/dist/src/ui/commands/aboutCommand.js.map +1 -1
- package/dist/src/ui/commands/authCommand.js +7 -9
- package/dist/src/ui/commands/authCommand.js.map +1 -1
- package/dist/src/ui/commands/baseurlCommand.js +8 -44
- package/dist/src/ui/commands/baseurlCommand.js.map +1 -1
- package/dist/src/ui/commands/chatCommand.js +28 -12
- package/dist/src/ui/commands/chatCommand.js.map +1 -1
- package/dist/src/ui/commands/diagnosticsCommand.d.ts +0 -3
- package/dist/src/ui/commands/diagnosticsCommand.js +45 -191
- package/dist/src/ui/commands/diagnosticsCommand.js.map +1 -1
- package/dist/src/ui/commands/keyCommand.js +9 -58
- package/dist/src/ui/commands/keyCommand.js.map +1 -1
- package/dist/src/ui/commands/keyCommand.test.js +48 -102
- package/dist/src/ui/commands/keyCommand.test.js.map +1 -1
- package/dist/src/ui/commands/keyfileCommand.js +42 -93
- package/dist/src/ui/commands/keyfileCommand.js.map +1 -1
- package/dist/src/ui/commands/logoutCommand.js +2 -2
- package/dist/src/ui/commands/logoutCommand.js.map +1 -1
- package/dist/src/ui/commands/mcpCommand.js +29 -7
- package/dist/src/ui/commands/mcpCommand.js.map +1 -1
- package/dist/src/ui/commands/modelCommand.js +8 -59
- package/dist/src/ui/commands/modelCommand.js.map +1 -1
- package/dist/src/ui/commands/profileCommand.js +151 -267
- package/dist/src/ui/commands/profileCommand.js.map +1 -1
- package/dist/src/ui/commands/profileCommand.test.js +88 -344
- package/dist/src/ui/commands/profileCommand.test.js.map +1 -1
- package/dist/src/ui/commands/providerCommand.js +9 -3
- package/dist/src/ui/commands/providerCommand.js.map +1 -1
- package/dist/src/ui/commands/restoreCommand.js +38 -18
- package/dist/src/ui/commands/restoreCommand.js.map +1 -1
- package/dist/src/ui/commands/schema/argumentResolver.test.d.ts +6 -0
- package/dist/src/ui/commands/schema/argumentResolver.test.js +619 -0
- package/dist/src/ui/commands/schema/argumentResolver.test.js.map +1 -0
- package/dist/src/ui/commands/schema/index.d.ts +15 -0
- package/dist/src/ui/commands/schema/index.js +320 -0
- package/dist/src/ui/commands/schema/index.js.map +1 -0
- package/dist/src/ui/commands/schema/types.d.ts +61 -0
- package/dist/src/ui/commands/schema/types.js +12 -0
- package/dist/src/ui/commands/schema/types.js.map +1 -0
- package/dist/src/ui/commands/setCommand.js +641 -325
- package/dist/src/ui/commands/setCommand.js.map +1 -1
- package/dist/src/ui/commands/setCommand.test.js +92 -388
- package/dist/src/ui/commands/setCommand.test.js.map +1 -1
- package/dist/src/ui/commands/statusCommand.js +2 -2
- package/dist/src/ui/commands/statusCommand.js.map +1 -1
- package/dist/src/ui/commands/subagentCommand.d.ts +16 -0
- package/dist/src/ui/commands/subagentCommand.js +674 -0
- package/dist/src/ui/commands/subagentCommand.js.map +1 -0
- package/dist/src/ui/commands/test/setCommand.mutation.test.d.ts +6 -0
- package/dist/src/ui/commands/test/setCommand.mutation.test.js +132 -0
- package/dist/src/ui/commands/test/setCommand.mutation.test.js.map +1 -0
- package/dist/src/ui/commands/test/setCommand.phase09.test.d.ts +6 -0
- package/dist/src/ui/commands/test/setCommand.phase09.test.js +222 -0
- package/dist/src/ui/commands/test/setCommand.phase09.test.js.map +1 -0
- package/dist/src/ui/commands/test/subagentCommand.schema.test.d.ts +6 -0
- package/dist/src/ui/commands/test/subagentCommand.schema.test.js +125 -0
- package/dist/src/ui/commands/test/subagentCommand.schema.test.js.map +1 -0
- package/dist/src/ui/commands/test/subagentCommand.test.d.ts +1 -0
- package/dist/src/ui/commands/test/subagentCommand.test.js +598 -0
- package/dist/src/ui/commands/test/subagentCommand.test.js.map +1 -0
- package/dist/src/ui/commands/toolformatCommand.js +25 -98
- package/dist/src/ui/commands/toolformatCommand.js.map +1 -1
- package/dist/src/ui/commands/toolformatCommand.test.js +56 -102
- package/dist/src/ui/commands/toolformatCommand.test.js.map +1 -1
- package/dist/src/ui/commands/toolsCommand.js +187 -31
- package/dist/src/ui/commands/toolsCommand.js.map +1 -1
- package/dist/src/ui/commands/types.d.ts +11 -2
- package/dist/src/ui/commands/types.js.map +1 -1
- package/dist/src/ui/components/AuthDialog.js +16 -55
- package/dist/src/ui/components/AuthDialog.js.map +1 -1
- package/dist/src/ui/components/Footer.js +4 -5
- package/dist/src/ui/components/Footer.js.map +1 -1
- package/dist/src/ui/components/HistoryItemDisplay.js +1 -1
- package/dist/src/ui/components/HistoryItemDisplay.js.map +1 -1
- package/dist/src/ui/components/InputPrompt.js +1 -1
- package/dist/src/ui/components/InputPrompt.js.map +1 -1
- package/dist/src/ui/components/StatsDisplay.js +6 -11
- package/dist/src/ui/components/StatsDisplay.js.map +1 -1
- package/dist/src/ui/components/SuggestionsDisplay.d.ts +13 -1
- package/dist/src/ui/components/SuggestionsDisplay.js +22 -3
- package/dist/src/ui/components/SuggestionsDisplay.js.map +1 -1
- package/dist/src/ui/components/messages/ToolGroupMessage.d.ts +1 -0
- package/dist/src/ui/components/messages/ToolGroupMessage.js +14 -14
- package/dist/src/ui/components/messages/ToolGroupMessage.js.map +1 -1
- package/dist/src/ui/components/messages/ToolGroupMessage.test.js +1 -0
- package/dist/src/ui/components/messages/ToolGroupMessage.test.js.map +1 -1
- package/dist/src/ui/containers/SessionController.js +61 -117
- package/dist/src/ui/containers/SessionController.js.map +1 -1
- package/dist/src/ui/contexts/RuntimeContext.d.ts +61 -0
- package/dist/src/ui/contexts/RuntimeContext.js +118 -0
- package/dist/src/ui/contexts/RuntimeContext.js.map +1 -0
- package/dist/src/ui/contexts/TodoProvider.d.ts +1 -0
- package/dist/src/ui/contexts/TodoProvider.js +10 -8
- package/dist/src/ui/contexts/TodoProvider.js.map +1 -1
- package/dist/src/ui/contexts/ToolCallProvider.d.ts +1 -0
- package/dist/src/ui/contexts/ToolCallProvider.js +10 -9
- package/dist/src/ui/contexts/ToolCallProvider.js.map +1 -1
- package/dist/src/ui/hooks/__tests__/useSlashCompletion.set.phase09.test.d.ts +6 -0
- package/dist/src/ui/hooks/__tests__/useSlashCompletion.set.phase09.test.js +39 -0
- package/dist/src/ui/hooks/__tests__/useSlashCompletion.set.phase09.test.js.map +1 -0
- package/dist/src/ui/hooks/atCommandProcessor.js +11 -3
- package/dist/src/ui/hooks/atCommandProcessor.js.map +1 -1
- package/dist/src/ui/hooks/atCommandProcessor.test.js +3 -1
- package/dist/src/ui/hooks/atCommandProcessor.test.js.map +1 -1
- package/dist/src/ui/hooks/shellCommandProcessor.js +4 -1
- package/dist/src/ui/hooks/shellCommandProcessor.js.map +1 -1
- package/dist/src/ui/hooks/shellCommandProcessor.test.js +1 -0
- package/dist/src/ui/hooks/shellCommandProcessor.test.js.map +1 -1
- package/dist/src/ui/hooks/slashCommandProcessor.js +27 -1
- package/dist/src/ui/hooks/slashCommandProcessor.js.map +1 -1
- package/dist/src/ui/hooks/useAuthCommand.js +11 -3
- package/dist/src/ui/hooks/useAuthCommand.js.map +1 -1
- package/dist/src/ui/hooks/useCommandCompletion.d.ts +1 -0
- package/dist/src/ui/hooks/useCommandCompletion.js +2 -0
- package/dist/src/ui/hooks/useCommandCompletion.js.map +1 -1
- package/dist/src/ui/hooks/useGeminiStream.js +37 -11
- package/dist/src/ui/hooks/useGeminiStream.js.map +1 -1
- package/dist/src/ui/hooks/useGeminiStream.subagent.spec.d.ts +6 -0
- package/dist/src/ui/hooks/useGeminiStream.subagent.spec.js +232 -0
- package/dist/src/ui/hooks/useGeminiStream.subagent.spec.js.map +1 -0
- package/dist/src/ui/hooks/useLoadProfileDialog.d.ts +1 -1
- package/dist/src/ui/hooks/useLoadProfileDialog.js +18 -57
- package/dist/src/ui/hooks/useLoadProfileDialog.js.map +1 -1
- package/dist/src/ui/hooks/useOpenAIProviderInfo.d.ts +1 -1
- package/dist/src/ui/hooks/useOpenAIProviderInfo.js +12 -7
- package/dist/src/ui/hooks/useOpenAIProviderInfo.js.map +1 -1
- package/dist/src/ui/hooks/useProviderDialog.d.ts +1 -1
- package/dist/src/ui/hooks/useProviderDialog.js +17 -90
- package/dist/src/ui/hooks/useProviderDialog.js.map +1 -1
- package/dist/src/ui/hooks/useProviderModelDialog.d.ts +2 -2
- package/dist/src/ui/hooks/useProviderModelDialog.js +11 -12
- package/dist/src/ui/hooks/useProviderModelDialog.js.map +1 -1
- package/dist/src/ui/hooks/useReactToolScheduler.d.ts +3 -1
- package/dist/src/ui/hooks/useReactToolScheduler.js +144 -34
- package/dist/src/ui/hooks/useReactToolScheduler.js.map +1 -1
- package/dist/src/ui/hooks/useSlashCompletion.d.ts +32 -0
- package/dist/src/ui/hooks/useSlashCompletion.js +154 -77
- package/dist/src/ui/hooks/useSlashCompletion.js.map +1 -1
- package/dist/src/ui/hooks/useSlashCompletion.test.js +39 -14
- package/dist/src/ui/hooks/useSlashCompletion.test.js.map +1 -1
- package/dist/src/ui/hooks/useToolScheduler.test.js +108 -79
- package/dist/src/ui/hooks/useToolScheduler.test.js.map +1 -1
- package/dist/src/ui/types.d.ts +1 -0
- package/dist/src/ui/types.js.map +1 -1
- package/dist/src/utils/sandbox.js +7 -5
- package/dist/src/utils/sandbox.js.map +1 -1
- package/dist/src/validateNonInterActiveAuth.js +4 -2
- package/dist/src/validateNonInterActiveAuth.js.map +1 -1
- package/dist/src/zed-integration/schema.d.ts +30 -30
- package/dist/src/zed-integration/zedIntegration.js +112 -39
- package/dist/src/zed-integration/zedIntegration.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -0
- package/package.json +5 -3
- package/dist/tsconfig.tsbuildinfo +0 -1
|
@@ -0,0 +1,866 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Vybestack LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* @plan PLAN-20251027-STATELESS5.P07
|
|
8
|
+
* @requirement REQ-STAT5-002
|
|
9
|
+
* @pseudocode cli-runtime-adapter.md lines 51-609
|
|
10
|
+
*
|
|
11
|
+
* Comprehensive TDD tests for AgentRuntimeAdapter behavior.
|
|
12
|
+
* RED phase: All tests fail against stub implementation.
|
|
13
|
+
* GREEN phase: Phase 08 implements the actual adapter logic.
|
|
14
|
+
*/
|
|
15
|
+
import { describe, it, expect, beforeEach, vi, afterEach } from 'vitest';
|
|
16
|
+
import { AgentRuntimeAdapter, bootstrapForegroundAgent, resolveRuntimeStateFromFlags, setRuntimeAdapter, getRuntimeAdapter, resetRuntimeAdapter, setRuntimeProvider, getRuntimeProvider, setRuntimeModel, getRuntimeModel, switchRuntimeProvider, } from './agentRuntimeAdapter.js';
|
|
17
|
+
import { createAgentRuntimeState, updateAgentRuntimeState, subscribeToAgentRuntimeState, AuthType, } from '@vybestack/llxprt-code-core';
|
|
18
|
+
// Mock fs module for keyfile reading
|
|
19
|
+
vi.mock('fs', async (importOriginal) => {
|
|
20
|
+
const actual = await importOriginal();
|
|
21
|
+
return {
|
|
22
|
+
...actual,
|
|
23
|
+
readFileSync: vi.fn((path) => {
|
|
24
|
+
if (path === '/path/to/keyfile') {
|
|
25
|
+
return 'test-api-key-from-file';
|
|
26
|
+
}
|
|
27
|
+
throw new Error(`ENOENT: no such file or directory, open '${path}'`);
|
|
28
|
+
}),
|
|
29
|
+
};
|
|
30
|
+
});
|
|
31
|
+
// Mock Config for testing
|
|
32
|
+
function createMockConfig() {
|
|
33
|
+
const mockProviderManager = {
|
|
34
|
+
hasProvider: vi.fn((name) => ['gemini', 'anthropic', 'openai'].includes(name)),
|
|
35
|
+
getProvider: vi.fn((name) => ({
|
|
36
|
+
getDefaultModel: vi.fn(() => {
|
|
37
|
+
const defaults = {
|
|
38
|
+
gemini: 'gemini-2.0-flash',
|
|
39
|
+
anthropic: 'claude-3-5-sonnet-20241022',
|
|
40
|
+
openai: 'gpt-4',
|
|
41
|
+
};
|
|
42
|
+
return defaults[name] || 'default-model';
|
|
43
|
+
}),
|
|
44
|
+
})),
|
|
45
|
+
getProviderByName: vi.fn((name) => {
|
|
46
|
+
if (!['gemini', 'anthropic', 'openai'].includes(name)) {
|
|
47
|
+
return undefined;
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
getDefaultModel: vi.fn(() => {
|
|
51
|
+
const defaults = {
|
|
52
|
+
gemini: 'gemini-2.0-flash',
|
|
53
|
+
anthropic: 'claude-3-5-sonnet-20241022',
|
|
54
|
+
openai: 'gpt-4',
|
|
55
|
+
};
|
|
56
|
+
return defaults[name] || 'default-model';
|
|
57
|
+
}),
|
|
58
|
+
};
|
|
59
|
+
}),
|
|
60
|
+
getProviderNames: vi.fn(() => ['gemini', 'anthropic', 'openai']),
|
|
61
|
+
listProviders: vi.fn(() => ['gemini', 'anthropic', 'openai']),
|
|
62
|
+
};
|
|
63
|
+
return {
|
|
64
|
+
getProvider: vi.fn(() => 'gemini'),
|
|
65
|
+
setProvider: vi.fn(),
|
|
66
|
+
getModel: vi.fn(() => 'gemini-2.0-flash'),
|
|
67
|
+
setModel: vi.fn(),
|
|
68
|
+
getAuthType: vi.fn(() => AuthType.USE_GEMINI),
|
|
69
|
+
getSessionId: vi.fn(() => 'test-session-id'),
|
|
70
|
+
getProxy: vi.fn(() => undefined),
|
|
71
|
+
setProxy: vi.fn(),
|
|
72
|
+
getEphemeralSetting: vi.fn((key) => {
|
|
73
|
+
if (key === 'base-url')
|
|
74
|
+
return undefined;
|
|
75
|
+
return undefined;
|
|
76
|
+
}),
|
|
77
|
+
setEphemeralSetting: vi.fn(),
|
|
78
|
+
getProviderManager: vi.fn(() => mockProviderManager),
|
|
79
|
+
refreshAuth: vi.fn(async () => { }),
|
|
80
|
+
getSettingsService: vi.fn(() => ({})),
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
describe('AgentRuntimeAdapter - Constructor and Initialization', () => {
|
|
84
|
+
/**
|
|
85
|
+
* @plan PLAN-20251027-STATELESS5.P07
|
|
86
|
+
* @requirement REQ-STAT5-002.1
|
|
87
|
+
* @pseudocode cli-runtime-adapter.md lines 51-88
|
|
88
|
+
*
|
|
89
|
+
* Tests adapter construction, state initialization, and config mirroring.
|
|
90
|
+
*/
|
|
91
|
+
it('should initialize adapter with runtime state and legacy config', () => {
|
|
92
|
+
// @plan PLAN-20251027-STATELESS5.P07
|
|
93
|
+
// @requirement REQ-STAT5-002.1
|
|
94
|
+
// @pseudocode cli-runtime-adapter.md lines 56-75
|
|
95
|
+
const params = {
|
|
96
|
+
runtimeId: 'test-runtime',
|
|
97
|
+
provider: 'gemini',
|
|
98
|
+
model: 'gemini-2.0-flash',
|
|
99
|
+
authType: AuthType.USE_GEMINI,
|
|
100
|
+
sessionId: 'test-session',
|
|
101
|
+
};
|
|
102
|
+
const runtimeState = createAgentRuntimeState(params);
|
|
103
|
+
const config = createMockConfig();
|
|
104
|
+
const adapter = new AgentRuntimeAdapter(runtimeState, config);
|
|
105
|
+
expect(adapter.getProvider()).toBe('gemini');
|
|
106
|
+
expect(adapter.getModel()).toBe('gemini-2.0-flash');
|
|
107
|
+
expect(adapter.getAuthType()).toBe(AuthType.USE_GEMINI);
|
|
108
|
+
});
|
|
109
|
+
it('should mirror initial state to legacy config on construction', () => {
|
|
110
|
+
// @plan PLAN-20251027-STATELESS5.P07
|
|
111
|
+
// @requirement REQ-STAT5-002.3
|
|
112
|
+
// @pseudocode cli-runtime-adapter.md lines 67-68
|
|
113
|
+
const params = {
|
|
114
|
+
runtimeId: 'test-runtime',
|
|
115
|
+
provider: 'anthropic',
|
|
116
|
+
model: 'claude-3-5-sonnet-20241022',
|
|
117
|
+
authType: AuthType.OAUTH,
|
|
118
|
+
authPayload: { token: 'test-token' },
|
|
119
|
+
baseUrl: 'https://api.anthropic.com',
|
|
120
|
+
sessionId: 'test-session',
|
|
121
|
+
};
|
|
122
|
+
const runtimeState = createAgentRuntimeState(params);
|
|
123
|
+
const config = createMockConfig();
|
|
124
|
+
new AgentRuntimeAdapter(runtimeState, config);
|
|
125
|
+
expect(config.setProvider).toHaveBeenCalledWith('anthropic');
|
|
126
|
+
expect(config.setModel).toHaveBeenCalledWith('claude-3-5-sonnet-20241022');
|
|
127
|
+
expect(config.setEphemeralSetting).toHaveBeenCalledWith('base-url', 'https://api.anthropic.com');
|
|
128
|
+
});
|
|
129
|
+
it('should subscribe to runtime state changes on construction', () => {
|
|
130
|
+
// @plan PLAN-20251027-STATELESS5.P07
|
|
131
|
+
// @requirement REQ-STAT5-002.1
|
|
132
|
+
// @pseudocode cli-runtime-adapter.md lines 70-73
|
|
133
|
+
const params = {
|
|
134
|
+
runtimeId: 'test-runtime',
|
|
135
|
+
provider: 'gemini',
|
|
136
|
+
model: 'gemini-2.0-flash',
|
|
137
|
+
authType: AuthType.USE_GEMINI,
|
|
138
|
+
sessionId: 'test-session',
|
|
139
|
+
};
|
|
140
|
+
const runtimeState = createAgentRuntimeState(params);
|
|
141
|
+
const config = createMockConfig();
|
|
142
|
+
const adapter = new AgentRuntimeAdapter(runtimeState, config);
|
|
143
|
+
// Update state and verify adapter reflects the change
|
|
144
|
+
updateAgentRuntimeState(runtimeState, { model: 'gemini-2.5-flash' });
|
|
145
|
+
// After subscription, adapter should reflect new state
|
|
146
|
+
expect(adapter.getModel()).toBe('gemini-2.5-flash');
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
describe('AgentRuntimeAdapter - Read Operations', () => {
|
|
150
|
+
/**
|
|
151
|
+
* @plan PLAN-20251027-STATELESS5.P07
|
|
152
|
+
* @requirement REQ-STAT5-002.1
|
|
153
|
+
* @pseudocode cli-runtime-adapter.md lines 199-221
|
|
154
|
+
*
|
|
155
|
+
* Tests synchronous getters that delegate to runtime state.
|
|
156
|
+
*/
|
|
157
|
+
let adapter;
|
|
158
|
+
let runtimeState;
|
|
159
|
+
let config;
|
|
160
|
+
beforeEach(() => {
|
|
161
|
+
const params = {
|
|
162
|
+
runtimeId: 'test-runtime',
|
|
163
|
+
provider: 'gemini',
|
|
164
|
+
model: 'gemini-2.0-flash',
|
|
165
|
+
authType: AuthType.USE_GEMINI,
|
|
166
|
+
authPayload: { apiKey: 'test-key' },
|
|
167
|
+
baseUrl: 'https://custom.api.com',
|
|
168
|
+
sessionId: 'test-session-123',
|
|
169
|
+
modelParams: { temperature: 0.7 },
|
|
170
|
+
};
|
|
171
|
+
runtimeState = createAgentRuntimeState(params);
|
|
172
|
+
config = createMockConfig();
|
|
173
|
+
adapter = new AgentRuntimeAdapter(runtimeState, config);
|
|
174
|
+
});
|
|
175
|
+
it('should return current provider name via getProvider', () => {
|
|
176
|
+
// @plan PLAN-20251027-STATELESS5.P07
|
|
177
|
+
// @requirement REQ-STAT5-002.1
|
|
178
|
+
// @pseudocode cli-runtime-adapter.md lines 199-203
|
|
179
|
+
expect(adapter.getProvider()).toBe('gemini');
|
|
180
|
+
});
|
|
181
|
+
it('should return current model name via getModel', () => {
|
|
182
|
+
// @plan PLAN-20251027-STATELESS5.P07
|
|
183
|
+
// @requirement REQ-STAT5-002.1
|
|
184
|
+
// @pseudocode cli-runtime-adapter.md lines 205-206
|
|
185
|
+
expect(adapter.getModel()).toBe('gemini-2.0-flash');
|
|
186
|
+
});
|
|
187
|
+
it('should return current auth type via getAuthType', () => {
|
|
188
|
+
// @plan PLAN-20251027-STATELESS5.P07
|
|
189
|
+
// @requirement REQ-STAT5-002.1
|
|
190
|
+
// @pseudocode cli-runtime-adapter.md lines 208-209
|
|
191
|
+
expect(adapter.getAuthType()).toBe(AuthType.USE_GEMINI);
|
|
192
|
+
});
|
|
193
|
+
it('should return current session ID via getSessionId', () => {
|
|
194
|
+
// @plan PLAN-20251027-STATELESS5.P07
|
|
195
|
+
// @requirement REQ-STAT5-002.1
|
|
196
|
+
// @pseudocode cli-runtime-adapter.md lines 211-212
|
|
197
|
+
expect(adapter.getSessionId()).toBe('test-session-123');
|
|
198
|
+
});
|
|
199
|
+
it('should return current base URL via getBaseUrl', () => {
|
|
200
|
+
// @plan PLAN-20251027-STATELESS5.P07
|
|
201
|
+
// @requirement REQ-STAT5-002.1
|
|
202
|
+
// @pseudocode cli-runtime-adapter.md lines 214-215
|
|
203
|
+
expect(adapter.getBaseUrl()).toBe('https://custom.api.com');
|
|
204
|
+
});
|
|
205
|
+
it('should return runtime state reference via getRuntimeState', () => {
|
|
206
|
+
// @plan PLAN-20251027-STATELESS5.P07
|
|
207
|
+
// @requirement REQ-STAT5-002.1
|
|
208
|
+
// @pseudocode cli-runtime-adapter.md lines 217-218
|
|
209
|
+
const state = adapter.getRuntimeState();
|
|
210
|
+
expect(state.runtimeId).toBe('test-runtime');
|
|
211
|
+
expect(state.provider).toBe('gemini');
|
|
212
|
+
expect(state.model).toBe('gemini-2.0-flash');
|
|
213
|
+
});
|
|
214
|
+
it('should return sanitized snapshot via getSnapshot', () => {
|
|
215
|
+
// @plan PLAN-20251027-STATELESS5.P07
|
|
216
|
+
// @requirement REQ-STAT5-001.3
|
|
217
|
+
// @pseudocode cli-runtime-adapter.md lines 220-221
|
|
218
|
+
const snapshot = adapter.getSnapshot();
|
|
219
|
+
expect(snapshot.runtimeId).toBe('test-runtime');
|
|
220
|
+
expect(snapshot.provider).toBe('gemini');
|
|
221
|
+
expect(snapshot.model).toBe('gemini-2.0-flash');
|
|
222
|
+
expect(snapshot.authType).toBe(AuthType.USE_GEMINI);
|
|
223
|
+
// Auth payload should be sanitized
|
|
224
|
+
expect(snapshot.authPayload?.apiKey).not.toBe('test-key');
|
|
225
|
+
});
|
|
226
|
+
});
|
|
227
|
+
describe('AgentRuntimeAdapter - Write Operations (Single Field)', () => {
|
|
228
|
+
/**
|
|
229
|
+
* @plan PLAN-20251027-STATELESS5.P07
|
|
230
|
+
* @requirement REQ-STAT5-002.1, REQ-STAT5-002.3
|
|
231
|
+
* @pseudocode cli-runtime-adapter.md lines 227-272
|
|
232
|
+
*
|
|
233
|
+
* Tests single field updates with config mirroring.
|
|
234
|
+
*/
|
|
235
|
+
let adapter;
|
|
236
|
+
let config;
|
|
237
|
+
beforeEach(() => {
|
|
238
|
+
const params = {
|
|
239
|
+
runtimeId: 'test-runtime',
|
|
240
|
+
provider: 'gemini',
|
|
241
|
+
model: 'gemini-2.0-flash',
|
|
242
|
+
authType: AuthType.USE_GEMINI,
|
|
243
|
+
sessionId: 'test-session',
|
|
244
|
+
};
|
|
245
|
+
const runtimeState = createAgentRuntimeState(params);
|
|
246
|
+
config = createMockConfig();
|
|
247
|
+
adapter = new AgentRuntimeAdapter(runtimeState, config);
|
|
248
|
+
});
|
|
249
|
+
it('should update provider and default model via setProvider', () => {
|
|
250
|
+
// @plan PLAN-20251027-STATELESS5.P07
|
|
251
|
+
// @requirement REQ-STAT5-002.1, REQ-STAT5-002.3
|
|
252
|
+
// @pseudocode cli-runtime-adapter.md lines 227-249
|
|
253
|
+
adapter.setProvider('anthropic');
|
|
254
|
+
expect(adapter.getProvider()).toBe('anthropic');
|
|
255
|
+
expect(adapter.getModel()).toBe('claude-3-5-sonnet-20241022'); // Default for anthropic
|
|
256
|
+
expect(adapter.getBaseUrl()).toBeUndefined(); // Cleared
|
|
257
|
+
});
|
|
258
|
+
it('should mirror provider update to legacy config', () => {
|
|
259
|
+
// @plan PLAN-20251027-STATELESS5.P07
|
|
260
|
+
// @requirement REQ-STAT5-002.3
|
|
261
|
+
// @pseudocode cli-runtime-adapter.md lines 244-248
|
|
262
|
+
adapter.setProvider('anthropic');
|
|
263
|
+
expect(config.setProvider).toHaveBeenCalledWith('anthropic');
|
|
264
|
+
expect(config.setModel).toHaveBeenCalledWith('claude-3-5-sonnet-20241022');
|
|
265
|
+
});
|
|
266
|
+
it('should throw error when setting invalid provider', () => {
|
|
267
|
+
// @plan PLAN-20251027-STATELESS5.P07
|
|
268
|
+
// @requirement REQ-STAT5-002.1
|
|
269
|
+
// @pseudocode cli-runtime-adapter.md lines 229-231
|
|
270
|
+
expect(() => adapter.setProvider('invalid-provider')).toThrow();
|
|
271
|
+
expect(() => adapter.setProvider('invalid-provider')).toThrow(/not found/);
|
|
272
|
+
});
|
|
273
|
+
it('should update model via setModel', () => {
|
|
274
|
+
// @plan PLAN-20251027-STATELESS5.P07
|
|
275
|
+
// @requirement REQ-STAT5-002.1, REQ-STAT5-002.3
|
|
276
|
+
// @pseudocode cli-runtime-adapter.md lines 250-256
|
|
277
|
+
adapter.setModel('gemini-2.5-flash');
|
|
278
|
+
expect(adapter.getModel()).toBe('gemini-2.5-flash');
|
|
279
|
+
expect(config.setModel).toHaveBeenCalledWith('gemini-2.5-flash');
|
|
280
|
+
});
|
|
281
|
+
it('should update auth type via setAuthType', () => {
|
|
282
|
+
// @plan PLAN-20251027-STATELESS5.P07
|
|
283
|
+
// @requirement REQ-STAT5-002.1, REQ-STAT5-002.3
|
|
284
|
+
// @pseudocode cli-runtime-adapter.md lines 258-264
|
|
285
|
+
adapter.setAuthType(AuthType.API_KEY);
|
|
286
|
+
expect(adapter.getAuthType()).toBe(AuthType.API_KEY);
|
|
287
|
+
});
|
|
288
|
+
it('should update base URL via setBaseUrl', () => {
|
|
289
|
+
// @plan PLAN-20251027-STATELESS5.P07
|
|
290
|
+
// @requirement REQ-STAT5-002.1, REQ-STAT5-002.3
|
|
291
|
+
// @pseudocode cli-runtime-adapter.md lines 266-272
|
|
292
|
+
adapter.setBaseUrl('https://custom.api.com');
|
|
293
|
+
expect(adapter.getBaseUrl()).toBe('https://custom.api.com');
|
|
294
|
+
expect(config.setEphemeralSetting).toHaveBeenCalledWith('base-url', 'https://custom.api.com');
|
|
295
|
+
});
|
|
296
|
+
});
|
|
297
|
+
describe('AgentRuntimeAdapter - Batch Write Operations', () => {
|
|
298
|
+
/**
|
|
299
|
+
* @plan PLAN-20251027-STATELESS5.P07
|
|
300
|
+
* @requirement REQ-STAT5-002.1, REQ-STAT5-002.3
|
|
301
|
+
* @pseudocode cli-runtime-adapter.md lines 280-316
|
|
302
|
+
*
|
|
303
|
+
* Tests atomic multi-field updates via switchProvider.
|
|
304
|
+
*/
|
|
305
|
+
let adapter;
|
|
306
|
+
let config;
|
|
307
|
+
beforeEach(() => {
|
|
308
|
+
const params = {
|
|
309
|
+
runtimeId: 'test-runtime',
|
|
310
|
+
provider: 'gemini',
|
|
311
|
+
model: 'gemini-2.0-flash',
|
|
312
|
+
authType: AuthType.USE_GEMINI,
|
|
313
|
+
baseUrl: 'https://old.api.com',
|
|
314
|
+
sessionId: 'test-session',
|
|
315
|
+
};
|
|
316
|
+
const runtimeState = createAgentRuntimeState(params);
|
|
317
|
+
config = createMockConfig();
|
|
318
|
+
adapter = new AgentRuntimeAdapter(runtimeState, config);
|
|
319
|
+
});
|
|
320
|
+
it('should atomically switch provider with default model', () => {
|
|
321
|
+
// @plan PLAN-20251027-STATELESS5.P07
|
|
322
|
+
// @requirement REQ-STAT5-002.1, REQ-STAT5-002.3
|
|
323
|
+
// @pseudocode cli-runtime-adapter.md lines 280-316
|
|
324
|
+
adapter.switchProvider('anthropic');
|
|
325
|
+
expect(adapter.getProvider()).toBe('anthropic');
|
|
326
|
+
expect(adapter.getModel()).toBe('claude-3-5-sonnet-20241022'); // Default model
|
|
327
|
+
expect(adapter.getBaseUrl()).toBeUndefined(); // Base URL cleared
|
|
328
|
+
});
|
|
329
|
+
it('should switch provider with explicit model', () => {
|
|
330
|
+
// @plan PLAN-20251027-STATELESS5.P07
|
|
331
|
+
// @requirement REQ-STAT5-002.1, REQ-STAT5-002.3
|
|
332
|
+
// @pseudocode cli-runtime-adapter.md lines 290-293
|
|
333
|
+
adapter.switchProvider('anthropic', { model: 'claude-3-opus-20240229' });
|
|
334
|
+
expect(adapter.getProvider()).toBe('anthropic');
|
|
335
|
+
expect(adapter.getModel()).toBe('claude-3-opus-20240229'); // Explicit model
|
|
336
|
+
});
|
|
337
|
+
it('should clear ephemeral settings when clearSettings is true', () => {
|
|
338
|
+
// @plan PLAN-20251027-STATELESS5.P07
|
|
339
|
+
// @requirement REQ-STAT5-002.3
|
|
340
|
+
// @pseudocode cli-runtime-adapter.md lines 302-306
|
|
341
|
+
adapter.switchProvider('anthropic', { clearSettings: true });
|
|
342
|
+
expect(config.setEphemeralSetting).toHaveBeenCalledWith('base-url', undefined);
|
|
343
|
+
});
|
|
344
|
+
it('should preserve settings when clearSettings is false', () => {
|
|
345
|
+
// @plan PLAN-20251027-STATELESS5.P07
|
|
346
|
+
// @requirement REQ-STAT5-002.3
|
|
347
|
+
// @pseudocode cli-runtime-adapter.md lines 302-306
|
|
348
|
+
const setEphemeralCalls = config.setEphemeralSetting.mock.calls.length;
|
|
349
|
+
adapter.switchProvider('anthropic', { clearSettings: false });
|
|
350
|
+
// Should not call setEphemeralSetting with undefined (except for base-url clear)
|
|
351
|
+
const newCalls = config.setEphemeralSetting
|
|
352
|
+
.mock.calls.length;
|
|
353
|
+
expect(newCalls).toBeGreaterThan(setEphemeralCalls);
|
|
354
|
+
});
|
|
355
|
+
it('should throw error when switching to invalid provider', () => {
|
|
356
|
+
// @plan PLAN-20251027-STATELESS5.P07
|
|
357
|
+
// @requirement REQ-STAT5-002.1
|
|
358
|
+
// @pseudocode cli-runtime-adapter.md lines 286-289
|
|
359
|
+
expect(() => adapter.switchProvider('invalid-provider')).toThrow();
|
|
360
|
+
expect(() => adapter.switchProvider('invalid-provider')).toThrow(/not found/);
|
|
361
|
+
});
|
|
362
|
+
it('should not emit multiple events for batch update', () => {
|
|
363
|
+
// @plan PLAN-20251027-STATELESS5.P07
|
|
364
|
+
// @requirement REQ-STAT5-002.3
|
|
365
|
+
// @pseudocode cli-runtime-adapter.md lines 308-312
|
|
366
|
+
const callback = vi.fn();
|
|
367
|
+
subscribeToAgentRuntimeState('test-runtime', callback);
|
|
368
|
+
adapter.switchProvider('anthropic');
|
|
369
|
+
// Should emit only 1 event despite updating provider + model + baseUrl
|
|
370
|
+
expect(callback).toHaveBeenCalledTimes(1);
|
|
371
|
+
});
|
|
372
|
+
});
|
|
373
|
+
describe('AgentRuntimeAdapter - Config Mirroring', () => {
|
|
374
|
+
/**
|
|
375
|
+
* @plan PLAN-20251027-STATELESS5.P07
|
|
376
|
+
* @requirement REQ-STAT5-002.3
|
|
377
|
+
* @pseudocode cli-runtime-adapter.md lines 329-351
|
|
378
|
+
*
|
|
379
|
+
* Tests that runtime state changes mirror to legacy Config.
|
|
380
|
+
*/
|
|
381
|
+
let adapter;
|
|
382
|
+
let config;
|
|
383
|
+
beforeEach(() => {
|
|
384
|
+
const params = {
|
|
385
|
+
runtimeId: 'test-runtime',
|
|
386
|
+
provider: 'gemini',
|
|
387
|
+
model: 'gemini-2.0-flash',
|
|
388
|
+
authType: AuthType.USE_GEMINI,
|
|
389
|
+
sessionId: 'test-session',
|
|
390
|
+
};
|
|
391
|
+
const runtimeState = createAgentRuntimeState(params);
|
|
392
|
+
config = createMockConfig();
|
|
393
|
+
adapter = new AgentRuntimeAdapter(runtimeState, config);
|
|
394
|
+
});
|
|
395
|
+
it('should mirror provider updates to config', () => {
|
|
396
|
+
// @plan PLAN-20251027-STATELESS5.P07
|
|
397
|
+
// @requirement REQ-STAT5-002.3
|
|
398
|
+
// @pseudocode cli-runtime-adapter.md lines 331-333
|
|
399
|
+
adapter.setProvider('anthropic');
|
|
400
|
+
expect(config.setProvider).toHaveBeenCalledWith('anthropic');
|
|
401
|
+
});
|
|
402
|
+
it('should mirror model updates to config', () => {
|
|
403
|
+
// @plan PLAN-20251027-STATELESS5.P07
|
|
404
|
+
// @requirement REQ-STAT5-002.3
|
|
405
|
+
// @pseudocode cli-runtime-adapter.md lines 334
|
|
406
|
+
adapter.setModel('gemini-2.5-flash');
|
|
407
|
+
expect(config.setModel).toHaveBeenCalledWith('gemini-2.5-flash');
|
|
408
|
+
});
|
|
409
|
+
it('should mirror auth type updates to config', () => {
|
|
410
|
+
// @plan PLAN-20251027-STATELESS5.P07
|
|
411
|
+
// @requirement REQ-STAT5-002.3
|
|
412
|
+
// @pseudocode cli-runtime-adapter.md lines 335
|
|
413
|
+
adapter.setAuthType(AuthType.API_KEY);
|
|
414
|
+
// Auth type update should be reflected in adapter
|
|
415
|
+
expect(adapter.getAuthType()).toBe(AuthType.API_KEY);
|
|
416
|
+
});
|
|
417
|
+
it('should mirror base URL updates to config ephemeral settings', () => {
|
|
418
|
+
// @plan PLAN-20251027-STATELESS5.P07
|
|
419
|
+
// @requirement REQ-STAT5-002.3
|
|
420
|
+
// @pseudocode cli-runtime-adapter.md lines 337-341
|
|
421
|
+
adapter.setBaseUrl('https://custom.api.com');
|
|
422
|
+
expect(config.setEphemeralSetting).toHaveBeenCalledWith('base-url', 'https://custom.api.com');
|
|
423
|
+
});
|
|
424
|
+
it('should clear base URL in config when set to undefined', () => {
|
|
425
|
+
// @plan PLAN-20251027-STATELESS5.P07
|
|
426
|
+
// @requirement REQ-STAT5-002.3
|
|
427
|
+
// @pseudocode cli-runtime-adapter.md lines 340-341
|
|
428
|
+
adapter.setBaseUrl('https://custom.api.com');
|
|
429
|
+
config.setEphemeralSetting.mockClear();
|
|
430
|
+
adapter.switchProvider('anthropic'); // Clears base URL
|
|
431
|
+
expect(config.setEphemeralSetting).toHaveBeenCalledWith('base-url', undefined);
|
|
432
|
+
});
|
|
433
|
+
it('should not mirror session ID to config', () => {
|
|
434
|
+
// @plan PLAN-20251027-STATELESS5.P07
|
|
435
|
+
// @requirement REQ-STAT5-002.3
|
|
436
|
+
// @pseudocode cli-runtime-adapter.md lines 349
|
|
437
|
+
const sessionId = adapter.getSessionId();
|
|
438
|
+
expect(sessionId).toBe('test-session');
|
|
439
|
+
// Session ID is immutable and not mirrored
|
|
440
|
+
expect(config.setEphemeralSetting).not.toHaveBeenCalledWith('session-id', expect.anything());
|
|
441
|
+
});
|
|
442
|
+
it('should not mirror auth payload directly to config', () => {
|
|
443
|
+
// @plan PLAN-20251027-STATELESS5.P07
|
|
444
|
+
// @requirement REQ-STAT5-002.3
|
|
445
|
+
// @pseudocode cli-runtime-adapter.md lines 350
|
|
446
|
+
adapter.setAuthType(AuthType.API_KEY);
|
|
447
|
+
// Auth payload is sensitive and not mirrored as ephemeral setting
|
|
448
|
+
expect(config.setEphemeralSetting).not.toHaveBeenCalledWith('auth-payload', expect.anything());
|
|
449
|
+
});
|
|
450
|
+
});
|
|
451
|
+
describe('AgentRuntimeAdapter - Lifecycle Management', () => {
|
|
452
|
+
/**
|
|
453
|
+
* @plan PLAN-20251027-STATELESS5.P07
|
|
454
|
+
* @requirement REQ-STAT5-002.1
|
|
455
|
+
* @pseudocode cli-runtime-adapter.md lines 597-609
|
|
456
|
+
*
|
|
457
|
+
* Tests adapter disposal and resource cleanup.
|
|
458
|
+
*/
|
|
459
|
+
it('should unsubscribe from runtime state events on dispose', () => {
|
|
460
|
+
// @plan PLAN-20251027-STATELESS5.P07
|
|
461
|
+
// @requirement REQ-STAT5-002.1
|
|
462
|
+
// @pseudocode cli-runtime-adapter.md lines 598-601
|
|
463
|
+
const params = {
|
|
464
|
+
runtimeId: 'test-runtime',
|
|
465
|
+
provider: 'gemini',
|
|
466
|
+
model: 'gemini-2.0-flash',
|
|
467
|
+
authType: AuthType.USE_GEMINI,
|
|
468
|
+
sessionId: 'test-session',
|
|
469
|
+
};
|
|
470
|
+
const runtimeState = createAgentRuntimeState(params);
|
|
471
|
+
const config = createMockConfig();
|
|
472
|
+
const adapter = new AgentRuntimeAdapter(runtimeState, config);
|
|
473
|
+
const callback = vi.fn();
|
|
474
|
+
subscribeToAgentRuntimeState('test-runtime', callback);
|
|
475
|
+
adapter.dispose();
|
|
476
|
+
// After dispose, adapter should not respond to state changes
|
|
477
|
+
updateAgentRuntimeState(runtimeState, { model: 'gemini-2.5-flash' });
|
|
478
|
+
// Callback still called (not adapter's subscription)
|
|
479
|
+
expect(callback).toHaveBeenCalled();
|
|
480
|
+
});
|
|
481
|
+
it('should allow multiple dispose calls without error', () => {
|
|
482
|
+
// @plan PLAN-20251027-STATELESS5.P07
|
|
483
|
+
// @requirement REQ-STAT5-002.1
|
|
484
|
+
// @pseudocode cli-runtime-adapter.md lines 597-609
|
|
485
|
+
const params = {
|
|
486
|
+
runtimeId: 'test-runtime',
|
|
487
|
+
provider: 'gemini',
|
|
488
|
+
model: 'gemini-2.0-flash',
|
|
489
|
+
authType: AuthType.USE_GEMINI,
|
|
490
|
+
sessionId: 'test-session',
|
|
491
|
+
};
|
|
492
|
+
const runtimeState = createAgentRuntimeState(params);
|
|
493
|
+
const config = createMockConfig();
|
|
494
|
+
const adapter = new AgentRuntimeAdapter(runtimeState, config);
|
|
495
|
+
expect(() => {
|
|
496
|
+
adapter.dispose();
|
|
497
|
+
adapter.dispose();
|
|
498
|
+
}).not.toThrow();
|
|
499
|
+
});
|
|
500
|
+
});
|
|
501
|
+
describe('AgentRuntimeAdapter - Global Registry', () => {
|
|
502
|
+
/**
|
|
503
|
+
* @plan PLAN-20251027-STATELESS5.P07
|
|
504
|
+
* @requirement REQ-STAT5-002.1
|
|
505
|
+
* @pseudocode cli-runtime-adapter.md lines 366-376
|
|
506
|
+
*
|
|
507
|
+
* Tests global adapter registry for CLI helpers.
|
|
508
|
+
*/
|
|
509
|
+
afterEach(() => {
|
|
510
|
+
// Reset global adapter after each test
|
|
511
|
+
try {
|
|
512
|
+
getRuntimeAdapter()?.dispose();
|
|
513
|
+
}
|
|
514
|
+
catch {
|
|
515
|
+
// No adapter set
|
|
516
|
+
}
|
|
517
|
+
resetRuntimeAdapter();
|
|
518
|
+
});
|
|
519
|
+
it('should set and get global runtime adapter', () => {
|
|
520
|
+
// @plan PLAN-20251027-STATELESS5.P07
|
|
521
|
+
// @requirement REQ-STAT5-002.1
|
|
522
|
+
// @pseudocode cli-runtime-adapter.md lines 366-376
|
|
523
|
+
const params = {
|
|
524
|
+
runtimeId: 'test-runtime',
|
|
525
|
+
provider: 'gemini',
|
|
526
|
+
model: 'gemini-2.0-flash',
|
|
527
|
+
authType: AuthType.USE_GEMINI,
|
|
528
|
+
sessionId: 'test-session',
|
|
529
|
+
};
|
|
530
|
+
const runtimeState = createAgentRuntimeState(params);
|
|
531
|
+
const config = createMockConfig();
|
|
532
|
+
const adapter = new AgentRuntimeAdapter(runtimeState, config);
|
|
533
|
+
setRuntimeAdapter(adapter);
|
|
534
|
+
const retrievedAdapter = getRuntimeAdapter();
|
|
535
|
+
expect(retrievedAdapter).toBe(adapter);
|
|
536
|
+
});
|
|
537
|
+
it('should throw error when getting adapter before initialization', () => {
|
|
538
|
+
// @plan PLAN-20251027-STATELESS5.P07
|
|
539
|
+
// @requirement REQ-STAT5-002.1
|
|
540
|
+
// @pseudocode cli-runtime-adapter.md lines 369-375
|
|
541
|
+
expect(() => getRuntimeAdapter()).toThrow();
|
|
542
|
+
expect(() => getRuntimeAdapter()).toThrow(/not initialized/);
|
|
543
|
+
});
|
|
544
|
+
});
|
|
545
|
+
describe('CLI Bootstrap Functions - resolveRuntimeStateFromFlags', () => {
|
|
546
|
+
/**
|
|
547
|
+
* @plan PLAN-20251027-STATELESS5.P07
|
|
548
|
+
* @requirement REQ-STAT5-002.2
|
|
549
|
+
* @pseudocode cli-runtime-adapter.md lines 138-186
|
|
550
|
+
*
|
|
551
|
+
* Tests CLI flag resolution and precedence.
|
|
552
|
+
*/
|
|
553
|
+
let config;
|
|
554
|
+
beforeEach(() => {
|
|
555
|
+
config = createMockConfig();
|
|
556
|
+
});
|
|
557
|
+
it('should use config defaults when no flags provided', () => {
|
|
558
|
+
// @plan PLAN-20251027-STATELESS5.P07
|
|
559
|
+
// @requirement REQ-STAT5-002.2
|
|
560
|
+
// @pseudocode cli-runtime-adapter.md lines 145-152
|
|
561
|
+
const flags = {};
|
|
562
|
+
const params = resolveRuntimeStateFromFlags(flags, config);
|
|
563
|
+
expect(params.provider).toBe('gemini');
|
|
564
|
+
expect(params.model).toBe('gemini-2.0-flash');
|
|
565
|
+
expect(params.authType).toBe(AuthType.USE_GEMINI);
|
|
566
|
+
});
|
|
567
|
+
it('should override provider from CLI flag', () => {
|
|
568
|
+
// @plan PLAN-20251027-STATELESS5.P07
|
|
569
|
+
// @requirement REQ-STAT5-002.2
|
|
570
|
+
// @pseudocode cli-runtime-adapter.md lines 154-157
|
|
571
|
+
const flags = {
|
|
572
|
+
provider: 'anthropic',
|
|
573
|
+
};
|
|
574
|
+
const params = resolveRuntimeStateFromFlags(flags, config);
|
|
575
|
+
expect(params.provider).toBe('anthropic');
|
|
576
|
+
});
|
|
577
|
+
it('should override model from CLI flag', () => {
|
|
578
|
+
// @plan PLAN-20251027-STATELESS5.P07
|
|
579
|
+
// @requirement REQ-STAT5-002.2
|
|
580
|
+
// @pseudocode cli-runtime-adapter.md lines 159-160
|
|
581
|
+
const flags = {
|
|
582
|
+
model: 'gemini-2.5-flash',
|
|
583
|
+
};
|
|
584
|
+
const params = resolveRuntimeStateFromFlags(flags, config);
|
|
585
|
+
expect(params.model).toBe('gemini-2.5-flash');
|
|
586
|
+
});
|
|
587
|
+
it('should set API_KEY auth type from --key flag', () => {
|
|
588
|
+
// @plan PLAN-20251027-STATELESS5.P07
|
|
589
|
+
// @requirement REQ-STAT5-002.2
|
|
590
|
+
// @pseudocode cli-runtime-adapter.md lines 162-168
|
|
591
|
+
const flags = {
|
|
592
|
+
key: 'test-api-key-12345',
|
|
593
|
+
};
|
|
594
|
+
const params = resolveRuntimeStateFromFlags(flags, config);
|
|
595
|
+
expect(params.authType).toBe(AuthType.API_KEY);
|
|
596
|
+
expect(params.authPayload).toEqual({ apiKey: 'test-api-key-12345' });
|
|
597
|
+
});
|
|
598
|
+
it('should set API_KEY auth type from --keyfile flag', () => {
|
|
599
|
+
// @plan PLAN-20251027-STATELESS5.P07
|
|
600
|
+
// @requirement REQ-STAT5-002.2
|
|
601
|
+
// @pseudocode cli-runtime-adapter.md lines 162-168
|
|
602
|
+
const flags = {
|
|
603
|
+
keyfile: '/path/to/keyfile',
|
|
604
|
+
};
|
|
605
|
+
const params = resolveRuntimeStateFromFlags(flags, config);
|
|
606
|
+
expect(params.authType).toBe(AuthType.API_KEY);
|
|
607
|
+
expect(params.authPayload?.apiKey).toBeTruthy();
|
|
608
|
+
});
|
|
609
|
+
it('should process --set flag for base-url', () => {
|
|
610
|
+
// @plan PLAN-20251027-STATELESS5.P07
|
|
611
|
+
// @requirement REQ-STAT5-002.2
|
|
612
|
+
// @pseudocode cli-runtime-adapter.md lines 169-176
|
|
613
|
+
const flags = {
|
|
614
|
+
set: [['base-url', 'https://custom.api.com']],
|
|
615
|
+
};
|
|
616
|
+
const params = resolveRuntimeStateFromFlags(flags, config);
|
|
617
|
+
expect(params.baseUrl).toBe('https://custom.api.com');
|
|
618
|
+
});
|
|
619
|
+
it('should process --set flag for model params', () => {
|
|
620
|
+
// @plan PLAN-20251027-STATELESS5.P07
|
|
621
|
+
// @requirement REQ-STAT5-002.2
|
|
622
|
+
// @pseudocode cli-runtime-adapter.md lines 169-176
|
|
623
|
+
const flags = {
|
|
624
|
+
set: [
|
|
625
|
+
['temperature', '0.9'],
|
|
626
|
+
['max-tokens', '2000'],
|
|
627
|
+
],
|
|
628
|
+
};
|
|
629
|
+
const params = resolveRuntimeStateFromFlags(flags, config);
|
|
630
|
+
expect(params.modelParams?.temperature).toBe('0.9');
|
|
631
|
+
expect(params.modelParams?.['max-tokens']).toBe('2000');
|
|
632
|
+
});
|
|
633
|
+
it('should prioritize CLI flags over config defaults', () => {
|
|
634
|
+
// @plan PLAN-20251027-STATELESS5.P07
|
|
635
|
+
// @requirement REQ-STAT5-002.2
|
|
636
|
+
// @pseudocode cli-runtime-adapter.md lines 154-160
|
|
637
|
+
const flags = {
|
|
638
|
+
provider: 'anthropic',
|
|
639
|
+
model: 'claude-3-opus-20240229',
|
|
640
|
+
};
|
|
641
|
+
const params = resolveRuntimeStateFromFlags(flags, config);
|
|
642
|
+
expect(params.provider).toBe('anthropic');
|
|
643
|
+
expect(params.model).toBe('claude-3-opus-20240229');
|
|
644
|
+
});
|
|
645
|
+
});
|
|
646
|
+
describe('CLI Bootstrap Functions - bootstrapForegroundAgent', () => {
|
|
647
|
+
/**
|
|
648
|
+
* @plan PLAN-20251027-STATELESS5.P07
|
|
649
|
+
* @requirement REQ-STAT5-002.2
|
|
650
|
+
* @pseudocode cli-runtime-adapter.md lines 101-132
|
|
651
|
+
*
|
|
652
|
+
* Tests full foreground agent bootstrap flow.
|
|
653
|
+
*/
|
|
654
|
+
let config;
|
|
655
|
+
beforeEach(() => {
|
|
656
|
+
config = createMockConfig();
|
|
657
|
+
});
|
|
658
|
+
it('should bootstrap foreground agent with adapter and client', async () => {
|
|
659
|
+
// @plan PLAN-20251027-STATELESS5.P07
|
|
660
|
+
// @requirement REQ-STAT5-002.2
|
|
661
|
+
// @pseudocode cli-runtime-adapter.md lines 101-132
|
|
662
|
+
const flags = {
|
|
663
|
+
provider: 'gemini',
|
|
664
|
+
model: 'gemini-2.0-flash',
|
|
665
|
+
};
|
|
666
|
+
const result = await bootstrapForegroundAgent(flags, config);
|
|
667
|
+
expect(result.adapter.getProvider()).toBe('gemini');
|
|
668
|
+
expect(result.adapter.getModel()).toBe('gemini-2.0-flash');
|
|
669
|
+
});
|
|
670
|
+
it('should create runtime state from resolved flags', async () => {
|
|
671
|
+
// @plan PLAN-20251027-STATELESS5.P07
|
|
672
|
+
// @requirement REQ-STAT5-002.2
|
|
673
|
+
// @pseudocode cli-runtime-adapter.md lines 106-113
|
|
674
|
+
const flags = {
|
|
675
|
+
provider: 'anthropic',
|
|
676
|
+
model: 'claude-3-5-sonnet-20241022',
|
|
677
|
+
};
|
|
678
|
+
const result = await bootstrapForegroundAgent(flags, config);
|
|
679
|
+
expect(result.adapter.getProvider()).toBe('anthropic');
|
|
680
|
+
expect(result.adapter.getModel()).toBe('claude-3-5-sonnet-20241022');
|
|
681
|
+
});
|
|
682
|
+
it('should create adapter with runtime state and config', async () => {
|
|
683
|
+
// @plan PLAN-20251027-STATELESS5.P07
|
|
684
|
+
// @requirement REQ-STAT5-002.2
|
|
685
|
+
// @pseudocode cli-runtime-adapter.md lines 115-116
|
|
686
|
+
const flags = {
|
|
687
|
+
provider: 'gemini',
|
|
688
|
+
};
|
|
689
|
+
const result = await bootstrapForegroundAgent(flags, config);
|
|
690
|
+
const state = result.adapter.getRuntimeState();
|
|
691
|
+
expect(state.runtimeId).toBeTruthy();
|
|
692
|
+
expect(state.provider).toBe('gemini');
|
|
693
|
+
});
|
|
694
|
+
it('should pass runtime state to GeminiClient', async () => {
|
|
695
|
+
// @plan PLAN-20251027-STATELESS5.P07
|
|
696
|
+
// @requirement REQ-STAT5-002.2
|
|
697
|
+
// @pseudocode cli-runtime-adapter.md lines 124-129
|
|
698
|
+
const flags = {
|
|
699
|
+
provider: 'gemini',
|
|
700
|
+
};
|
|
701
|
+
const result = await bootstrapForegroundAgent(flags, config);
|
|
702
|
+
// Client should have access to runtime state
|
|
703
|
+
expect(result.client).toBeTruthy();
|
|
704
|
+
});
|
|
705
|
+
});
|
|
706
|
+
describe('Legacy Helper Functions - Provider Operations', () => {
|
|
707
|
+
/**
|
|
708
|
+
* @plan PLAN-20251027-STATELESS5.P07
|
|
709
|
+
* @requirement REQ-STAT5-002.1
|
|
710
|
+
* @pseudocode cli-runtime-adapter.md lines 378-398
|
|
711
|
+
*
|
|
712
|
+
* Tests legacy helper functions that delegate to adapter.
|
|
713
|
+
*/
|
|
714
|
+
let adapter;
|
|
715
|
+
beforeEach(() => {
|
|
716
|
+
const params = {
|
|
717
|
+
runtimeId: 'test-runtime',
|
|
718
|
+
provider: 'gemini',
|
|
719
|
+
model: 'gemini-2.0-flash',
|
|
720
|
+
authType: AuthType.USE_GEMINI,
|
|
721
|
+
sessionId: 'test-session',
|
|
722
|
+
};
|
|
723
|
+
const runtimeState = createAgentRuntimeState(params);
|
|
724
|
+
const config = createMockConfig();
|
|
725
|
+
adapter = new AgentRuntimeAdapter(runtimeState, config);
|
|
726
|
+
setRuntimeAdapter(adapter);
|
|
727
|
+
});
|
|
728
|
+
afterEach(() => {
|
|
729
|
+
adapter.dispose();
|
|
730
|
+
resetRuntimeAdapter();
|
|
731
|
+
});
|
|
732
|
+
it('should set provider via setRuntimeProvider helper', () => {
|
|
733
|
+
// @plan PLAN-20251027-STATELESS5.P07
|
|
734
|
+
// @requirement REQ-STAT5-002.1
|
|
735
|
+
// @pseudocode cli-runtime-adapter.md lines 378-381
|
|
736
|
+
setRuntimeProvider('anthropic');
|
|
737
|
+
expect(getRuntimeProvider()).toBe('anthropic');
|
|
738
|
+
});
|
|
739
|
+
it('should get provider via getRuntimeProvider helper', () => {
|
|
740
|
+
// @plan PLAN-20251027-STATELESS5.P07
|
|
741
|
+
// @requirement REQ-STAT5-002.1
|
|
742
|
+
// @pseudocode cli-runtime-adapter.md lines 383-386
|
|
743
|
+
const provider = getRuntimeProvider();
|
|
744
|
+
expect(provider).toBe('gemini');
|
|
745
|
+
});
|
|
746
|
+
it('should set model via setRuntimeModel helper', () => {
|
|
747
|
+
// @plan PLAN-20251027-STATELESS5.P07
|
|
748
|
+
// @requirement REQ-STAT5-002.1
|
|
749
|
+
// @pseudocode cli-runtime-adapter.md lines 388-390
|
|
750
|
+
setRuntimeModel('gemini-2.5-flash');
|
|
751
|
+
expect(getRuntimeModel()).toBe('gemini-2.5-flash');
|
|
752
|
+
});
|
|
753
|
+
it('should get model via getRuntimeModel helper', () => {
|
|
754
|
+
// @plan PLAN-20251027-STATELESS5.P07
|
|
755
|
+
// @requirement REQ-STAT5-002.1
|
|
756
|
+
// @pseudocode cli-runtime-adapter.md lines 392-394
|
|
757
|
+
const model = getRuntimeModel();
|
|
758
|
+
expect(model).toBe('gemini-2.0-flash');
|
|
759
|
+
});
|
|
760
|
+
it('should switch provider atomically via switchRuntimeProvider helper', () => {
|
|
761
|
+
// @plan PLAN-20251027-STATELESS5.P07
|
|
762
|
+
// @requirement REQ-STAT5-002.1
|
|
763
|
+
// @pseudocode cli-runtime-adapter.md lines 396-398
|
|
764
|
+
switchRuntimeProvider('anthropic', 'claude-3-opus-20240229');
|
|
765
|
+
expect(getRuntimeProvider()).toBe('anthropic');
|
|
766
|
+
expect(getRuntimeModel()).toBe('claude-3-opus-20240229');
|
|
767
|
+
});
|
|
768
|
+
it('should use default model when switching provider without explicit model', () => {
|
|
769
|
+
// @plan PLAN-20251027-STATELESS5.P07
|
|
770
|
+
// @requirement REQ-STAT5-002.1
|
|
771
|
+
// @pseudocode cli-runtime-adapter.md lines 396-398
|
|
772
|
+
switchRuntimeProvider('anthropic');
|
|
773
|
+
expect(getRuntimeProvider()).toBe('anthropic');
|
|
774
|
+
expect(getRuntimeModel()).toBe('claude-3-5-sonnet-20241022'); // Default model
|
|
775
|
+
});
|
|
776
|
+
});
|
|
777
|
+
describe('AgentRuntimeAdapter - Event Handling', () => {
|
|
778
|
+
/**
|
|
779
|
+
* @plan PLAN-20251027-STATELESS5.P07
|
|
780
|
+
* @requirement REQ-STAT5-002.1
|
|
781
|
+
* @pseudocode cli-runtime-adapter.md lines 76-87
|
|
782
|
+
*
|
|
783
|
+
* Tests that adapter responds to runtime state changes.
|
|
784
|
+
*/
|
|
785
|
+
it('should mirror state changes to config when subscribed', () => {
|
|
786
|
+
// @plan PLAN-20251027-STATELESS5.P07
|
|
787
|
+
// @requirement REQ-STAT5-002.3
|
|
788
|
+
// @pseudocode cli-runtime-adapter.md lines 76-87
|
|
789
|
+
const params = {
|
|
790
|
+
runtimeId: 'test-runtime',
|
|
791
|
+
provider: 'gemini',
|
|
792
|
+
model: 'gemini-2.0-flash',
|
|
793
|
+
authType: AuthType.USE_GEMINI,
|
|
794
|
+
sessionId: 'test-session',
|
|
795
|
+
};
|
|
796
|
+
const runtimeState = createAgentRuntimeState(params);
|
|
797
|
+
const config = createMockConfig();
|
|
798
|
+
new AgentRuntimeAdapter(runtimeState, config);
|
|
799
|
+
config.setModel.mockClear();
|
|
800
|
+
// Update runtime state externally
|
|
801
|
+
updateAgentRuntimeState(runtimeState, { model: 'gemini-2.5-flash' });
|
|
802
|
+
// Adapter should have mirrored to config
|
|
803
|
+
expect(config.setModel).toHaveBeenCalledWith('gemini-2.5-flash');
|
|
804
|
+
});
|
|
805
|
+
it('should update local runtime state reference on change event', () => {
|
|
806
|
+
// @plan PLAN-20251027-STATELESS5.P07
|
|
807
|
+
// @requirement REQ-STAT5-002.1
|
|
808
|
+
// @pseudocode cli-runtime-adapter.md lines 77-78
|
|
809
|
+
const params = {
|
|
810
|
+
runtimeId: 'test-runtime',
|
|
811
|
+
provider: 'gemini',
|
|
812
|
+
model: 'gemini-2.0-flash',
|
|
813
|
+
authType: AuthType.USE_GEMINI,
|
|
814
|
+
sessionId: 'test-session',
|
|
815
|
+
};
|
|
816
|
+
const runtimeState = createAgentRuntimeState(params);
|
|
817
|
+
const config = createMockConfig();
|
|
818
|
+
const adapter = new AgentRuntimeAdapter(runtimeState, config);
|
|
819
|
+
// Update runtime state externally
|
|
820
|
+
updateAgentRuntimeState(runtimeState, { model: 'gemini-2.5-flash' });
|
|
821
|
+
// Adapter should reflect the change
|
|
822
|
+
expect(adapter.getModel()).toBe('gemini-2.5-flash');
|
|
823
|
+
});
|
|
824
|
+
});
|
|
825
|
+
describe('AgentRuntimeAdapter - Error Handling', () => {
|
|
826
|
+
/**
|
|
827
|
+
* @plan PLAN-20251027-STATELESS5.P07
|
|
828
|
+
* @requirement REQ-STAT5-001.1
|
|
829
|
+
* @pseudocode cli-runtime-adapter.md lines 569-592
|
|
830
|
+
*
|
|
831
|
+
* Tests adapter-level error handling and validation.
|
|
832
|
+
*/
|
|
833
|
+
let adapter;
|
|
834
|
+
beforeEach(() => {
|
|
835
|
+
const params = {
|
|
836
|
+
runtimeId: 'test-runtime',
|
|
837
|
+
provider: 'gemini',
|
|
838
|
+
model: 'gemini-2.0-flash',
|
|
839
|
+
authType: AuthType.USE_GEMINI,
|
|
840
|
+
sessionId: 'test-session',
|
|
841
|
+
};
|
|
842
|
+
const runtimeState = createAgentRuntimeState(params);
|
|
843
|
+
const config = createMockConfig();
|
|
844
|
+
adapter = new AgentRuntimeAdapter(runtimeState, config);
|
|
845
|
+
});
|
|
846
|
+
it('should throw descriptive error for invalid provider', () => {
|
|
847
|
+
// @plan PLAN-20251027-STATELESS5.P07
|
|
848
|
+
// @requirement REQ-STAT5-001.1
|
|
849
|
+
// @pseudocode cli-runtime-adapter.md lines 575-579
|
|
850
|
+
expect(() => adapter.setProvider('invalid-provider')).toThrow();
|
|
851
|
+
expect(() => adapter.setProvider('invalid-provider')).toThrow(/not found/);
|
|
852
|
+
});
|
|
853
|
+
it('should include available providers in error message', () => {
|
|
854
|
+
// @plan PLAN-20251027-STATELESS5.P07
|
|
855
|
+
// @requirement REQ-STAT5-001.1
|
|
856
|
+
// @pseudocode cli-runtime-adapter.md lines 575-579
|
|
857
|
+
try {
|
|
858
|
+
adapter.setProvider('invalid-provider');
|
|
859
|
+
expect.fail('Should have thrown error');
|
|
860
|
+
}
|
|
861
|
+
catch (error) {
|
|
862
|
+
expect(error.message).toMatch(/gemini|anthropic|openai/);
|
|
863
|
+
}
|
|
864
|
+
});
|
|
865
|
+
});
|
|
866
|
+
//# sourceMappingURL=agentRuntimeAdapter.spec.js.map
|