@vybestack/llxprt-code-core 0.4.8 → 0.5.0-nightly.251102.e5b51aa3
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/prompt-config/defaults/default-prompts.json +4 -17
- package/dist/src/auth/precedence.d.ts +69 -9
- package/dist/src/auth/precedence.js +467 -69
- package/dist/src/auth/precedence.js.map +1 -1
- package/dist/src/auth/types.d.ts +2 -2
- package/dist/src/config/config.d.ts +15 -1
- package/dist/src/config/config.js +118 -6
- package/dist/src/config/config.js.map +1 -1
- package/dist/src/config/index.d.ts +6 -0
- package/dist/src/config/index.js +5 -0
- package/dist/src/config/index.js.map +1 -1
- package/dist/src/config/profileManager.d.ts +23 -3
- package/dist/src/config/profileManager.js +54 -7
- package/dist/src/config/profileManager.js.map +1 -1
- package/dist/src/config/subagentManager.d.ts +96 -0
- package/dist/src/config/subagentManager.js +371 -0
- package/dist/src/config/subagentManager.js.map +1 -0
- package/dist/src/config/types.d.ts +18 -0
- package/dist/src/config/types.js +3 -0
- package/dist/src/config/types.js.map +1 -0
- package/dist/src/core/client.d.ts +27 -7
- package/dist/src/core/client.js +231 -55
- package/dist/src/core/client.js.map +1 -1
- package/dist/src/core/contentGenerator.d.ts +3 -1
- package/dist/src/core/contentGenerator.js +3 -0
- package/dist/src/core/contentGenerator.js.map +1 -1
- package/dist/src/core/coreToolScheduler.d.ts +1 -5
- package/dist/src/core/coreToolScheduler.js +95 -23
- package/dist/src/core/coreToolScheduler.js.map +1 -1
- package/dist/src/core/geminiChat.d.ts +42 -12
- package/dist/src/core/geminiChat.js +405 -205
- package/dist/src/core/geminiChat.js.map +1 -1
- package/dist/src/core/nonInteractiveToolExecutor.d.ts +3 -2
- package/dist/src/core/nonInteractiveToolExecutor.js +94 -10
- package/dist/src/core/nonInteractiveToolExecutor.js.map +1 -1
- package/dist/src/core/subagent.d.ts +86 -7
- package/dist/src/core/subagent.js +809 -79
- package/dist/src/core/subagent.js.map +1 -1
- package/dist/src/core/subagentOrchestrator.d.ts +73 -0
- package/dist/src/core/subagentOrchestrator.js +387 -0
- package/dist/src/core/subagentOrchestrator.js.map +1 -0
- package/dist/src/core/subagentScheduler.d.ts +16 -0
- package/dist/src/core/subagentScheduler.js +7 -0
- package/dist/src/core/subagentScheduler.js.map +1 -0
- package/dist/src/core/turn.d.ts +5 -1
- package/dist/src/core/turn.js +5 -1
- package/dist/src/core/turn.js.map +1 -1
- package/dist/src/hooks/tool-render-suppression-hook.js +6 -1
- package/dist/src/hooks/tool-render-suppression-hook.js.map +1 -1
- package/dist/src/ide/ideContext.d.ts +32 -32
- package/dist/src/index.d.ts +19 -1
- package/dist/src/index.js +15 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/interfaces/index.d.ts +1 -0
- package/dist/src/interfaces/index.js +4 -0
- package/dist/src/interfaces/index.js.map +1 -0
- package/dist/src/interfaces/nodejs-error.interface.d.ts +4 -0
- package/dist/src/interfaces/nodejs-error.interface.js +2 -0
- package/dist/src/interfaces/nodejs-error.interface.js.map +1 -0
- package/dist/src/parsers/TextToolCallParser.d.ts +17 -1
- package/dist/src/parsers/TextToolCallParser.js +542 -148
- package/dist/src/parsers/TextToolCallParser.js.map +1 -1
- package/dist/src/prompt-config/defaults/core.md +15 -0
- package/dist/src/prompt-config/defaults/providers/gemini/core.md +203 -119
- package/dist/src/prompt-config/defaults/tool-defaults.js +2 -0
- package/dist/src/prompt-config/defaults/tool-defaults.js.map +1 -1
- package/dist/src/prompt-config/defaults/tools/list-subagents.md +7 -0
- package/dist/src/prompt-config/defaults/tools/task.md +8 -0
- package/dist/src/providers/BaseProvider.d.ts +115 -30
- package/dist/src/providers/BaseProvider.js +445 -109
- package/dist/src/providers/BaseProvider.js.map +1 -1
- package/dist/src/providers/IProvider.d.ts +50 -18
- package/dist/src/providers/LoggingProviderWrapper.d.ts +60 -16
- package/dist/src/providers/LoggingProviderWrapper.js +213 -60
- package/dist/src/providers/LoggingProviderWrapper.js.map +1 -1
- package/dist/src/providers/ProviderManager.d.ts +73 -2
- package/dist/src/providers/ProviderManager.js +492 -40
- package/dist/src/providers/ProviderManager.js.map +1 -1
- package/dist/src/providers/anthropic/AnthropicProvider.d.ts +35 -38
- package/dist/src/providers/anthropic/AnthropicProvider.js +222 -227
- package/dist/src/providers/anthropic/AnthropicProvider.js.map +1 -1
- package/dist/src/providers/errors.d.ts +86 -0
- package/dist/src/providers/errors.js +89 -0
- package/dist/src/providers/errors.js.map +1 -1
- package/dist/src/providers/gemini/GeminiProvider.d.ts +101 -41
- package/dist/src/providers/gemini/GeminiProvider.js +386 -311
- package/dist/src/providers/gemini/GeminiProvider.js.map +1 -1
- package/dist/src/providers/openai/ConversationCache.d.ts +5 -3
- package/dist/src/providers/openai/ConversationCache.js +93 -32
- package/dist/src/providers/openai/ConversationCache.js.map +1 -1
- package/dist/src/providers/openai/OpenAIProvider.d.ts +82 -42
- package/dist/src/providers/openai/OpenAIProvider.js +391 -536
- package/dist/src/providers/openai/OpenAIProvider.js.map +1 -1
- package/dist/src/providers/openai/getOpenAIProviderInfo.d.ts +1 -1
- package/dist/src/providers/openai/getOpenAIProviderInfo.js +52 -22
- package/dist/src/providers/openai/getOpenAIProviderInfo.js.map +1 -1
- package/dist/src/providers/openai/openaiRequestParams.d.ts +7 -0
- package/dist/src/providers/openai/openaiRequestParams.js +66 -0
- package/dist/src/providers/openai/openaiRequestParams.js.map +1 -0
- package/dist/src/providers/openai-responses/OpenAIResponsesProvider.d.ts +6 -33
- package/dist/src/providers/openai-responses/OpenAIResponsesProvider.js +84 -183
- package/dist/src/providers/openai-responses/OpenAIResponsesProvider.js.map +1 -1
- package/dist/src/providers/types/providerRuntime.d.ts +17 -0
- package/dist/src/providers/types/providerRuntime.js +7 -0
- package/dist/src/providers/types/providerRuntime.js.map +1 -0
- package/dist/src/providers/utils/authToken.d.ts +12 -0
- package/dist/src/providers/utils/authToken.js +17 -0
- package/dist/src/providers/utils/authToken.js.map +1 -0
- package/dist/src/providers/utils/userMemory.d.ts +8 -0
- package/dist/src/providers/utils/userMemory.js +34 -0
- package/dist/src/providers/utils/userMemory.js.map +1 -0
- package/dist/src/runtime/AgentRuntimeContext.d.ts +213 -0
- package/dist/src/runtime/AgentRuntimeContext.js +17 -0
- package/dist/src/runtime/AgentRuntimeContext.js.map +1 -0
- package/dist/src/runtime/AgentRuntimeLoader.d.ts +47 -0
- package/dist/src/runtime/AgentRuntimeLoader.js +122 -0
- package/dist/src/runtime/AgentRuntimeLoader.js.map +1 -0
- package/dist/src/runtime/AgentRuntimeState.d.ts +232 -0
- package/dist/src/runtime/AgentRuntimeState.js +439 -0
- package/dist/src/runtime/AgentRuntimeState.js.map +1 -0
- package/dist/src/runtime/RuntimeInvocationContext.d.ts +51 -0
- package/dist/src/runtime/RuntimeInvocationContext.js +52 -0
- package/dist/src/runtime/RuntimeInvocationContext.js.map +1 -0
- package/dist/src/runtime/createAgentRuntimeContext.d.ts +7 -0
- package/dist/src/runtime/createAgentRuntimeContext.js +65 -0
- package/dist/src/runtime/createAgentRuntimeContext.js.map +1 -0
- package/dist/src/runtime/index.d.ts +13 -0
- package/dist/src/runtime/index.js +14 -0
- package/dist/src/runtime/index.js.map +1 -0
- package/dist/src/runtime/providerRuntimeContext.d.ts +30 -0
- package/dist/src/runtime/providerRuntimeContext.js +70 -0
- package/dist/src/runtime/providerRuntimeContext.js.map +1 -0
- package/dist/src/runtime/runtimeAdapters.d.ts +22 -0
- package/dist/src/runtime/runtimeAdapters.js +81 -0
- package/dist/src/runtime/runtimeAdapters.js.map +1 -0
- package/dist/src/runtime/runtimeStateFactory.d.ts +21 -0
- package/dist/src/runtime/runtimeStateFactory.js +104 -0
- package/dist/src/runtime/runtimeStateFactory.js.map +1 -0
- package/dist/src/services/todo-context-tracker.d.ts +10 -8
- package/dist/src/services/todo-context-tracker.js +26 -10
- package/dist/src/services/todo-context-tracker.js.map +1 -1
- package/dist/src/services/tool-call-tracker-service.d.ts +11 -7
- package/dist/src/services/tool-call-tracker-service.js +89 -29
- package/dist/src/services/tool-call-tracker-service.js.map +1 -1
- package/dist/src/settings/SettingsService.d.ts +4 -0
- package/dist/src/settings/SettingsService.js +65 -2
- package/dist/src/settings/SettingsService.js.map +1 -1
- package/dist/src/settings/settingsServiceInstance.d.ts +6 -1
- package/dist/src/settings/settingsServiceInstance.js +28 -8
- package/dist/src/settings/settingsServiceInstance.js.map +1 -1
- package/dist/src/telemetry/loggers.d.ts +5 -1
- package/dist/src/telemetry/loggers.js.map +1 -1
- package/dist/src/telemetry/loggers.test.circular.js +4 -0
- package/dist/src/telemetry/loggers.test.circular.js.map +1 -1
- package/dist/src/telemetry/metrics.d.ts +3 -1
- package/dist/src/telemetry/metrics.js.map +1 -1
- package/dist/src/telemetry/types.d.ts +1 -0
- package/dist/src/telemetry/types.js +3 -0
- package/dist/src/telemetry/types.js.map +1 -1
- package/dist/src/test-utils/index.d.ts +2 -0
- package/dist/src/test-utils/index.js +2 -0
- package/dist/src/test-utils/index.js.map +1 -1
- package/dist/src/test-utils/mockWorkspaceContext.d.ts +0 -3
- package/dist/src/test-utils/mockWorkspaceContext.js +3 -4
- package/dist/src/test-utils/mockWorkspaceContext.js.map +1 -1
- package/dist/src/test-utils/providerCallOptions.d.ts +43 -0
- package/dist/src/test-utils/providerCallOptions.js +137 -0
- package/dist/src/test-utils/providerCallOptions.js.map +1 -0
- package/dist/src/test-utils/runtime.d.ts +92 -0
- package/dist/src/test-utils/runtime.js +226 -0
- package/dist/src/test-utils/runtime.js.map +1 -0
- package/dist/src/test-utils/tools.d.ts +4 -4
- package/dist/src/test-utils/tools.js +20 -10
- package/dist/src/test-utils/tools.js.map +1 -1
- package/dist/src/tools/list-subagents.d.ts +31 -0
- package/dist/src/tools/list-subagents.js +109 -0
- package/dist/src/tools/list-subagents.js.map +1 -0
- package/dist/src/tools/task.d.ts +87 -0
- package/dist/src/tools/task.js +427 -0
- package/dist/src/tools/task.js.map +1 -0
- package/dist/src/tools/todo-read.js +1 -1
- package/dist/src/tools/todo-read.js.map +1 -1
- package/dist/src/tools/todo-store.js +4 -2
- package/dist/src/tools/todo-store.js.map +1 -1
- package/dist/src/tools/todo-write.js +4 -2
- package/dist/src/tools/todo-write.js.map +1 -1
- package/dist/src/tools/tool-error.d.ts +1 -0
- package/dist/src/tools/tool-error.js +1 -0
- package/dist/src/tools/tool-error.js.map +1 -1
- package/dist/src/tools/tool-registry.d.ts +2 -0
- package/dist/src/tools/tool-registry.js +46 -21
- package/dist/src/tools/tool-registry.js.map +1 -1
- package/dist/src/types/modelParams.d.ts +4 -0
- package/dist/src/utils/editor.js +10 -8
- package/dist/src/utils/editor.js.map +1 -1
- package/dist/src/utils/gitIgnoreParser.js +15 -3
- package/dist/src/utils/gitIgnoreParser.js.map +1 -1
- package/package.json +1 -1
- package/dist/src/prompt-config/defaults/providers/anthropic/core.md +0 -97
- package/dist/src/prompt-config/defaults/providers/anthropic/tools/glob.md +0 -34
- package/dist/src/prompt-config/defaults/providers/anthropic/tools/list-directory.md +0 -11
- package/dist/src/prompt-config/defaults/providers/anthropic/tools/read-file.md +0 -14
- package/dist/src/prompt-config/defaults/providers/anthropic/tools/read-many-files.md +0 -31
- package/dist/src/prompt-config/defaults/providers/anthropic/tools/replace.md +0 -41
- package/dist/src/prompt-config/defaults/providers/anthropic/tools/run-shell-command.md +0 -32
- package/dist/src/prompt-config/defaults/providers/anthropic/tools/save-memory.md +0 -35
- package/dist/src/prompt-config/defaults/providers/anthropic/tools/search-file-content.md +0 -44
- package/dist/src/prompt-config/defaults/providers/anthropic/tools/todo-write.md +0 -45
- package/dist/src/prompt-config/defaults/providers/anthropic/tools/write-file.md +0 -11
- package/dist/src/prompt-config/defaults/providers/openai/core.md +0 -97
- package/dist/src/prompt-config/defaults/providers/openai/tools/todo-pause.md +0 -28
- package/dist/src/prompt-config/defaults/providers/openai/tools/todo-read.md +0 -5
- package/dist/src/prompt-config/defaults/providers/openai/tools/todo-write.md +0 -45
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Vybestack LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { SubagentConfig } from '../config/types.js';
|
|
7
|
+
import { ProfileManager } from './profileManager.js';
|
|
8
|
+
/**
|
|
9
|
+
* Manages subagent configuration files in ~/.llxprt/subagents/
|
|
10
|
+
*
|
|
11
|
+
* @plan:PLAN-20250117-SUBAGENTCONFIG.P05
|
|
12
|
+
* @requirement:REQ-002
|
|
13
|
+
*
|
|
14
|
+
* Pattern: Follows ProfileManager design
|
|
15
|
+
* Storage: JSON files in baseDir directory
|
|
16
|
+
* Naming: <name>.json
|
|
17
|
+
*/
|
|
18
|
+
export declare class SubagentManager {
|
|
19
|
+
private readonly baseDir;
|
|
20
|
+
private readonly profileManager;
|
|
21
|
+
/**
|
|
22
|
+
* @param baseDir Directory where subagent configs are stored (e.g., ~/.llxprt/subagents/)
|
|
23
|
+
* @param profileManager ProfileManager instance for validation
|
|
24
|
+
*
|
|
25
|
+
* @plan:PLAN-20250117-SUBAGENTCONFIG.P05
|
|
26
|
+
* @requirement:REQ-002
|
|
27
|
+
* @pseudocode SubagentManager.md lines 1-8
|
|
28
|
+
*/
|
|
29
|
+
constructor(baseDir: string, profileManager: ProfileManager);
|
|
30
|
+
/**
|
|
31
|
+
* Save or update a subagent configuration
|
|
32
|
+
*
|
|
33
|
+
* @plan:PLAN-20250117-SUBAGENTCONFIG.P05
|
|
34
|
+
* @requirement:REQ-002
|
|
35
|
+
* @pseudocode SubagentManager.md lines 61-128
|
|
36
|
+
*/
|
|
37
|
+
saveSubagent(name: string, profile: string, systemPrompt: string): Promise<void>;
|
|
38
|
+
/**
|
|
39
|
+
* Load a subagent configuration from disk
|
|
40
|
+
*
|
|
41
|
+
* @plan:PLAN-20250117-SUBAGENTCONFIG.P05
|
|
42
|
+
* @requirement:REQ-002
|
|
43
|
+
* @pseudocode SubagentManager.md lines 129-180
|
|
44
|
+
*/
|
|
45
|
+
loadSubagent(name: string): Promise<SubagentConfig>;
|
|
46
|
+
/**
|
|
47
|
+
* List all subagent names
|
|
48
|
+
*
|
|
49
|
+
* @plan:PLAN-20250117-SUBAGENTCONFIG.P05
|
|
50
|
+
* @requirement:REQ-002
|
|
51
|
+
* @pseudocode SubagentManager.md lines 181-209
|
|
52
|
+
*/
|
|
53
|
+
listSubagents(): Promise<string[]>;
|
|
54
|
+
/**
|
|
55
|
+
* Delete a subagent configuration
|
|
56
|
+
*
|
|
57
|
+
* @plan:PLAN-20250117-SUBAGENTCONFIG.P05
|
|
58
|
+
* @requirement:REQ-002
|
|
59
|
+
* @pseudocode SubagentManager.md lines 210-236
|
|
60
|
+
*
|
|
61
|
+
* @returns true if deleted, false if not found
|
|
62
|
+
*/
|
|
63
|
+
deleteSubagent(name: string): Promise<boolean>;
|
|
64
|
+
/**
|
|
65
|
+
* Check if a subagent configuration exists
|
|
66
|
+
*
|
|
67
|
+
* @plan:PLAN-20250117-SUBAGENTCONFIG.P05
|
|
68
|
+
* @requirement:REQ-002
|
|
69
|
+
* @pseudocode SubagentManager.md lines 237-262
|
|
70
|
+
*/
|
|
71
|
+
subagentExists(name: string): Promise<boolean>;
|
|
72
|
+
/**
|
|
73
|
+
* Validate that a profile exists in ProfileManager
|
|
74
|
+
*
|
|
75
|
+
* @plan:PLAN-20250117-SUBAGENTCONFIG.P05
|
|
76
|
+
* @requirement:REQ-002
|
|
77
|
+
* @pseudocode SubagentManager.md lines 263-281
|
|
78
|
+
*/
|
|
79
|
+
validateProfileReference(profileName: string): Promise<boolean>;
|
|
80
|
+
/**
|
|
81
|
+
* Get full path to subagent config file
|
|
82
|
+
*
|
|
83
|
+
* @plan:PLAN-20250117-SUBAGENTCONFIG.P05
|
|
84
|
+
* @requirement:REQ-002
|
|
85
|
+
* @pseudocode SubagentManager.md lines 9-43
|
|
86
|
+
*/
|
|
87
|
+
private getSubagentPath;
|
|
88
|
+
/**
|
|
89
|
+
* Ensure subagent directory exists, create if not
|
|
90
|
+
*
|
|
91
|
+
* @plan:PLAN-20250117-SUBAGENTCONFIG.P05
|
|
92
|
+
* @requirement:REQ-002
|
|
93
|
+
* @pseudocode SubagentManager.md lines 45-60
|
|
94
|
+
*/
|
|
95
|
+
private ensureDirectory;
|
|
96
|
+
}
|
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Vybestack LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import * as fsPromises from 'fs/promises';
|
|
7
|
+
import * as path from 'path';
|
|
8
|
+
// Error message templates for consistency
|
|
9
|
+
// @plan:PLAN-20250117-SUBAGENTCONFIG.P05
|
|
10
|
+
const ERROR_MESSAGES = {
|
|
11
|
+
INVALID_NAME: 'Invalid subagent name. Only alphanumeric, hyphens, and underscores allowed.',
|
|
12
|
+
NAME_REQUIRED: 'Subagent name is required.',
|
|
13
|
+
PROFILE_REQUIRED: 'Profile name is required.',
|
|
14
|
+
PROMPT_REQUIRED: 'Empty system prompt not allowed.',
|
|
15
|
+
PROFILE_NOT_FOUND: "Profile '{profile}' not found. Use '/profile list' to see available profiles.",
|
|
16
|
+
SUBAGENT_NOT_FOUND: "Subagent '{name}' not found.",
|
|
17
|
+
PERMISSION_DENIED: 'Permission denied: {operation}.',
|
|
18
|
+
DISK_FULL: 'No disk space: {operation}.',
|
|
19
|
+
CORRUPTED_FILE: "Subagent '{name}' file is corrupted (invalid JSON).",
|
|
20
|
+
INVALID_CONFIG: "Subagent '{name}' is invalid: {reason}.",
|
|
21
|
+
DIRECTORY_NOT_FOUND: 'Directory not found: {path}',
|
|
22
|
+
CANNOT_PERFORM_OP: 'Cannot perform operation: {reason}',
|
|
23
|
+
MISSING_FIELDS: "Subagent '{name}' file is missing required configuration fields.",
|
|
24
|
+
INVALID_TIMESTAMP: "Subagent '{name}' has an invalid timestamp format. Expected ISO 8601.",
|
|
25
|
+
FILENAME_MISMATCH: "Subagent filename mismatch: expected '{expected}', found '{actual}'",
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Manages subagent configuration files in ~/.llxprt/subagents/
|
|
29
|
+
*
|
|
30
|
+
* @plan:PLAN-20250117-SUBAGENTCONFIG.P05
|
|
31
|
+
* @requirement:REQ-002
|
|
32
|
+
*
|
|
33
|
+
* Pattern: Follows ProfileManager design
|
|
34
|
+
* Storage: JSON files in baseDir directory
|
|
35
|
+
* Naming: <name>.json
|
|
36
|
+
*/
|
|
37
|
+
export class SubagentManager {
|
|
38
|
+
baseDir;
|
|
39
|
+
profileManager;
|
|
40
|
+
/**
|
|
41
|
+
* @param baseDir Directory where subagent configs are stored (e.g., ~/.llxprt/subagents/)
|
|
42
|
+
* @param profileManager ProfileManager instance for validation
|
|
43
|
+
*
|
|
44
|
+
* @plan:PLAN-20250117-SUBAGENTCONFIG.P05
|
|
45
|
+
* @requirement:REQ-002
|
|
46
|
+
* @pseudocode SubagentManager.md lines 1-8
|
|
47
|
+
*/
|
|
48
|
+
constructor(baseDir, profileManager) {
|
|
49
|
+
this.baseDir = baseDir;
|
|
50
|
+
this.profileManager = profileManager;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Save or update a subagent configuration
|
|
54
|
+
*
|
|
55
|
+
* @plan:PLAN-20250117-SUBAGENTCONFIG.P05
|
|
56
|
+
* @requirement:REQ-002
|
|
57
|
+
* @pseudocode SubagentManager.md lines 61-128
|
|
58
|
+
*/
|
|
59
|
+
async saveSubagent(name, profile, systemPrompt) {
|
|
60
|
+
if (profile === undefined || profile.trim() === '') {
|
|
61
|
+
throw new Error('Profile name is required.');
|
|
62
|
+
}
|
|
63
|
+
if (systemPrompt === undefined || systemPrompt.trim() === '') {
|
|
64
|
+
throw new Error(ERROR_MESSAGES.PROMPT_REQUIRED);
|
|
65
|
+
}
|
|
66
|
+
// Validate profile exists
|
|
67
|
+
const profileExists = await this.validateProfileReference(profile);
|
|
68
|
+
if (!profileExists) {
|
|
69
|
+
throw new Error(ERROR_MESSAGES.PROFILE_NOT_FOUND.replace('{profile}', profile));
|
|
70
|
+
}
|
|
71
|
+
// Check if subagent exists for update vs create
|
|
72
|
+
const exists = await this.subagentExists(name);
|
|
73
|
+
let config;
|
|
74
|
+
if (exists) {
|
|
75
|
+
// Load existing to preserve createdAt
|
|
76
|
+
const existing = await this.loadSubagent(name);
|
|
77
|
+
config = {
|
|
78
|
+
name,
|
|
79
|
+
profile,
|
|
80
|
+
systemPrompt,
|
|
81
|
+
createdAt: existing.createdAt, // Preserve original timestamp
|
|
82
|
+
updatedAt: new Date().toISOString(), // Update timestamp
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
// Create new with current timestamps
|
|
87
|
+
const now = new Date().toISOString();
|
|
88
|
+
config = {
|
|
89
|
+
name,
|
|
90
|
+
profile,
|
|
91
|
+
systemPrompt,
|
|
92
|
+
createdAt: now,
|
|
93
|
+
updatedAt: now,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
// Ensure directory exists
|
|
97
|
+
await this.ensureDirectory();
|
|
98
|
+
// Get file path via private helper
|
|
99
|
+
const filePath = this.getSubagentPath(name);
|
|
100
|
+
// Prepare JSON content
|
|
101
|
+
const jsonString = JSON.stringify(config, null, 2);
|
|
102
|
+
// Write to file
|
|
103
|
+
try {
|
|
104
|
+
await fsPromises.writeFile(filePath, jsonString, 'utf-8');
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
if (error instanceof Error && 'code' in error) {
|
|
108
|
+
const code = error.code;
|
|
109
|
+
if (code === 'EACCES') {
|
|
110
|
+
throw new Error(ERROR_MESSAGES.PERMISSION_DENIED.replace('{operation}', `Cannot write subagent file ${filePath}`));
|
|
111
|
+
}
|
|
112
|
+
else if (code === 'ENOSPC') {
|
|
113
|
+
throw new Error(ERROR_MESSAGES.DISK_FULL.replace('{operation}', `Cannot write subagent file ${filePath}`));
|
|
114
|
+
}
|
|
115
|
+
else if (code === 'ENOENT') {
|
|
116
|
+
throw new Error(ERROR_MESSAGES.DIRECTORY_NOT_FOUND.replace('{path}', this.baseDir));
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
throw new Error(ERROR_MESSAGES.CANNOT_PERFORM_OP.replace('{reason}', error instanceof Error ? error.message : 'Unknown error'));
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Load a subagent configuration from disk
|
|
124
|
+
*
|
|
125
|
+
* @plan:PLAN-20250117-SUBAGENTCONFIG.P05
|
|
126
|
+
* @requirement:REQ-002
|
|
127
|
+
* @pseudocode SubagentManager.md lines 129-180
|
|
128
|
+
*/
|
|
129
|
+
async loadSubagent(name) {
|
|
130
|
+
// Validate input via private helper
|
|
131
|
+
const filePath = this.getSubagentPath(name);
|
|
132
|
+
let content;
|
|
133
|
+
// Read file
|
|
134
|
+
try {
|
|
135
|
+
content = await fsPromises.readFile(filePath, 'utf-8');
|
|
136
|
+
}
|
|
137
|
+
catch (error) {
|
|
138
|
+
if (error instanceof Error && 'code' in error) {
|
|
139
|
+
const code = error.code;
|
|
140
|
+
if (code === 'ENOENT') {
|
|
141
|
+
throw new Error(ERROR_MESSAGES.SUBAGENT_NOT_FOUND.replace('{name}', name));
|
|
142
|
+
}
|
|
143
|
+
else if (code === 'EACCES') {
|
|
144
|
+
throw new Error(ERROR_MESSAGES.PERMISSION_DENIED.replace('{operation}', `Cannot read subagent file ${filePath}`));
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
throw new Error(ERROR_MESSAGES.CANNOT_PERFORM_OP.replace('{reason}', error instanceof Error ? error.message : 'Unknown error'));
|
|
148
|
+
}
|
|
149
|
+
let config;
|
|
150
|
+
// Parse JSON
|
|
151
|
+
try {
|
|
152
|
+
config = JSON.parse(content);
|
|
153
|
+
}
|
|
154
|
+
catch (error) {
|
|
155
|
+
if (error instanceof SyntaxError) {
|
|
156
|
+
throw new Error(ERROR_MESSAGES.CORRUPTED_FILE.replace('{name}', name));
|
|
157
|
+
}
|
|
158
|
+
throw new Error(ERROR_MESSAGES.CANNOT_PERFORM_OP.replace('{reason}', error instanceof Error ? error.message : 'Unknown error'));
|
|
159
|
+
}
|
|
160
|
+
// Validate required fields
|
|
161
|
+
const { name: configName, profile, systemPrompt, createdAt, updatedAt, } = config;
|
|
162
|
+
if (!configName || !profile || !systemPrompt) {
|
|
163
|
+
throw new Error(`Subagent '${name}' file is missing required field(s): name, profile, or systemPrompt.`);
|
|
164
|
+
}
|
|
165
|
+
if (!createdAt || !updatedAt) {
|
|
166
|
+
throw new Error(`Subagent '${name}' file is missing required field(s): createdAt or updatedAt.`);
|
|
167
|
+
} // @plan:PLAN-20250117-SUBAGENTCONFIG.P05 @requirement:REQ-002
|
|
168
|
+
// Validate timestamp format
|
|
169
|
+
if (Number.isNaN(Date.parse(config.createdAt)) ||
|
|
170
|
+
Number.isNaN(Date.parse(config.updatedAt))) {
|
|
171
|
+
throw new Error(ERROR_MESSAGES.INVALID_TIMESTAMP.replace('{name}', name));
|
|
172
|
+
}
|
|
173
|
+
// Validate name matches filename after sanitization
|
|
174
|
+
const canonicalName = config.name.replace(/[^a-zA-Z0-9_-]/g, '');
|
|
175
|
+
if (canonicalName !== path.basename(filePath, '.json')) {
|
|
176
|
+
throw new Error(ERROR_MESSAGES.FILENAME_MISMATCH.replace('{expected}', canonicalName).replace('{actual}', path.basename(filePath, '.json')));
|
|
177
|
+
}
|
|
178
|
+
return config;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* List all subagent names
|
|
182
|
+
*
|
|
183
|
+
* @plan:PLAN-20250117-SUBAGENTCONFIG.P05
|
|
184
|
+
* @requirement:REQ-002
|
|
185
|
+
* @pseudocode SubagentManager.md lines 181-209
|
|
186
|
+
*/
|
|
187
|
+
async listSubagents() {
|
|
188
|
+
try {
|
|
189
|
+
// Ensure directory exists
|
|
190
|
+
await this.ensureDirectory();
|
|
191
|
+
// Read directory contents
|
|
192
|
+
const files = await fsPromises.readdir(this.baseDir);
|
|
193
|
+
// Filter for .json files and extract names
|
|
194
|
+
const subagentFiles = files.filter((file) => file.endsWith('.json'));
|
|
195
|
+
const subagentNames = subagentFiles.map((file) => file.slice(0, -5)); // Remove .json extension
|
|
196
|
+
// Sort alphabetically
|
|
197
|
+
subagentNames.sort();
|
|
198
|
+
return subagentNames;
|
|
199
|
+
}
|
|
200
|
+
catch (error) {
|
|
201
|
+
if (error instanceof Error && 'code' in error) {
|
|
202
|
+
const code = error.code;
|
|
203
|
+
if (code === 'ENOENT') {
|
|
204
|
+
// Directory doesn't exist yet, return empty list
|
|
205
|
+
return [];
|
|
206
|
+
}
|
|
207
|
+
else if (code === 'EACCES') {
|
|
208
|
+
throw new Error(ERROR_MESSAGES.PERMISSION_DENIED.replace('{operation}', `Cannot read subagent directory ${this.baseDir}`));
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
throw new Error(ERROR_MESSAGES.CANNOT_PERFORM_OP.replace('{reason}', error instanceof Error ? error.message : 'Unknown error'));
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Delete a subagent configuration
|
|
216
|
+
*
|
|
217
|
+
* @plan:PLAN-20250117-SUBAGENTCONFIG.P05
|
|
218
|
+
* @requirement:REQ-002
|
|
219
|
+
* @pseudocode SubagentManager.md lines 210-236
|
|
220
|
+
*
|
|
221
|
+
* @returns true if deleted, false if not found
|
|
222
|
+
*/
|
|
223
|
+
async deleteSubagent(name) {
|
|
224
|
+
// Validate input via private helper
|
|
225
|
+
const filePath = this.getSubagentPath(name);
|
|
226
|
+
// Check if subagent exists
|
|
227
|
+
const exists = await this.subagentExists(name);
|
|
228
|
+
if (!exists) {
|
|
229
|
+
return false;
|
|
230
|
+
}
|
|
231
|
+
// Delete file
|
|
232
|
+
try {
|
|
233
|
+
await fsPromises.unlink(filePath);
|
|
234
|
+
return true;
|
|
235
|
+
}
|
|
236
|
+
catch (error) {
|
|
237
|
+
if (error instanceof Error && 'code' in error) {
|
|
238
|
+
const code = error.code;
|
|
239
|
+
if (code === 'ENOENT') {
|
|
240
|
+
// File already deleted
|
|
241
|
+
return false;
|
|
242
|
+
}
|
|
243
|
+
else if (code === 'EACCES') {
|
|
244
|
+
throw new Error(ERROR_MESSAGES.PERMISSION_DENIED.replace('{operation}', `Cannot delete subagent file ${filePath}`));
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
throw new Error(ERROR_MESSAGES.CANNOT_PERFORM_OP.replace('{reason}', error instanceof Error ? error.message : 'Unknown error'));
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Check if a subagent configuration exists
|
|
252
|
+
*
|
|
253
|
+
* @plan:PLAN-20250117-SUBAGENTCONFIG.P05
|
|
254
|
+
* @requirement:REQ-002
|
|
255
|
+
* @pseudocode SubagentManager.md lines 237-262
|
|
256
|
+
*/
|
|
257
|
+
async subagentExists(name) {
|
|
258
|
+
// Validate input via private helper
|
|
259
|
+
// This check will return false for empty or invalid names.
|
|
260
|
+
let filePath;
|
|
261
|
+
try {
|
|
262
|
+
filePath = this.getSubagentPath(name);
|
|
263
|
+
}
|
|
264
|
+
catch (_error) {
|
|
265
|
+
// getSubagentPath throws for invalid names. If it throws here, the agent doesn't exist.
|
|
266
|
+
return false;
|
|
267
|
+
}
|
|
268
|
+
// Check file existence
|
|
269
|
+
try {
|
|
270
|
+
await fsPromises.access(filePath);
|
|
271
|
+
return true;
|
|
272
|
+
}
|
|
273
|
+
catch (error) {
|
|
274
|
+
if (error instanceof Error && 'code' in error) {
|
|
275
|
+
const code = error.code;
|
|
276
|
+
if (code === 'ENOENT') {
|
|
277
|
+
return false;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
// For other access errors, treat as not existing to be safe (aligns with pseudocode).
|
|
281
|
+
return false;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Validate that a profile exists in ProfileManager
|
|
286
|
+
*
|
|
287
|
+
* @plan:PLAN-20250117-SUBAGENTCONFIG.P05
|
|
288
|
+
* @requirement:REQ-002
|
|
289
|
+
* @pseudocode SubagentManager.md lines 263-281
|
|
290
|
+
*/
|
|
291
|
+
async validateProfileReference(profileName) {
|
|
292
|
+
// Validate input
|
|
293
|
+
if (profileName === undefined ||
|
|
294
|
+
profileName === null ||
|
|
295
|
+
profileName.trim() === '') {
|
|
296
|
+
return false;
|
|
297
|
+
}
|
|
298
|
+
// Check if profile exists using the injected ProfileManager instance.
|
|
299
|
+
try {
|
|
300
|
+
const availableProfiles = await this.profileManager.listProfiles();
|
|
301
|
+
return availableProfiles.includes(profileName);
|
|
302
|
+
}
|
|
303
|
+
catch (error) {
|
|
304
|
+
// If ProfileManager fails, we cannot validate
|
|
305
|
+
console.warn(`Cannot validate profile reference '${profileName}': ${error instanceof Error ? error.message : 'unknown error'}`);
|
|
306
|
+
return false;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Get full path to subagent config file
|
|
311
|
+
*
|
|
312
|
+
* @plan:PLAN-20250117-SUBAGENTCONFIG.P05
|
|
313
|
+
* @requirement:REQ-002
|
|
314
|
+
* @pseudocode SubagentManager.md lines 9-43
|
|
315
|
+
*/
|
|
316
|
+
getSubagentPath(name) {
|
|
317
|
+
// Centralize all name validation in this helper
|
|
318
|
+
// 1. Validate name is not undefined or null
|
|
319
|
+
if (name === undefined || name === null) {
|
|
320
|
+
throw new Error(ERROR_MESSAGES.NAME_REQUIRED);
|
|
321
|
+
}
|
|
322
|
+
// 2. Validate name is not an empty string or just whitespace
|
|
323
|
+
if (name.trim() === '') {
|
|
324
|
+
throw new Error(ERROR_MESSAGES.INVALID_NAME);
|
|
325
|
+
}
|
|
326
|
+
// 3. Sanitize filename (prevent path traversal)
|
|
327
|
+
const sanitizedName = name.replace(/[^a-zA-Z0-9_-]/g, '');
|
|
328
|
+
// 4. Validate name after sanitization
|
|
329
|
+
if (sanitizedName !== name) {
|
|
330
|
+
throw new Error(ERROR_MESSAGES.INVALID_NAME);
|
|
331
|
+
}
|
|
332
|
+
// 5. Validate baseDir is provided to the instance
|
|
333
|
+
if (this.baseDir === undefined ||
|
|
334
|
+
this.baseDir === null ||
|
|
335
|
+
this.baseDir.trim() === '') {
|
|
336
|
+
throw new Error('Base directory is required');
|
|
337
|
+
}
|
|
338
|
+
// 6. Validate profileManager is provided to the instance
|
|
339
|
+
if (this.profileManager === undefined || this.profileManager === null) {
|
|
340
|
+
throw new Error('ProfileManager instance is required');
|
|
341
|
+
}
|
|
342
|
+
// Construct full path
|
|
343
|
+
return path.join(this.baseDir, `${sanitizedName}.json`);
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* Ensure subagent directory exists, create if not
|
|
347
|
+
*
|
|
348
|
+
* @plan:PLAN-20250117-SUBAGENTCONFIG.P05
|
|
349
|
+
* @requirement:REQ-002
|
|
350
|
+
* @pseudocode SubagentManager.md lines 45-60
|
|
351
|
+
*/
|
|
352
|
+
async ensureDirectory() {
|
|
353
|
+
try {
|
|
354
|
+
// Create directory if it doesn't exist
|
|
355
|
+
await fsPromises.mkdir(this.baseDir, { recursive: true });
|
|
356
|
+
}
|
|
357
|
+
catch (error) {
|
|
358
|
+
if (error instanceof Error && 'code' in error) {
|
|
359
|
+
const code = error.code;
|
|
360
|
+
if (code === 'EACCES') {
|
|
361
|
+
throw new Error(ERROR_MESSAGES.PERMISSION_DENIED.replace('{operation}', `Cannot create directory ${this.baseDir}`));
|
|
362
|
+
}
|
|
363
|
+
else if (code === 'ENOSPC') {
|
|
364
|
+
throw new Error(ERROR_MESSAGES.DISK_FULL.replace('{operation}', `Cannot create directory ${this.baseDir}`));
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
throw new Error(ERROR_MESSAGES.CANNOT_PERFORM_OP.replace('{reason}', error instanceof Error ? error.message : 'unknown error'));
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
//# sourceMappingURL=subagentManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subagentManager.js","sourceRoot":"","sources":["../../../src/config/subagentManager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Subagent configuration stored in ~/.llxprt/subagents/<name>.json
|
|
3
|
+
* @plan:PLAN-20250117-SUBAGENTCONFIG.P03
|
|
4
|
+
* @requirement:REQ-001
|
|
5
|
+
* @requirement:REQ-012
|
|
6
|
+
*/
|
|
7
|
+
export interface SubagentConfig {
|
|
8
|
+
/** Subagent identifier (matches filename without .json) */
|
|
9
|
+
name: string;
|
|
10
|
+
/** Reference to profile name in ~/.llxprt/profiles/ */
|
|
11
|
+
profile: string;
|
|
12
|
+
/** System prompt text for this subagent */
|
|
13
|
+
systemPrompt: string;
|
|
14
|
+
/** ISO 8601 timestamp when subagent was created */
|
|
15
|
+
createdAt: string;
|
|
16
|
+
/** ISO 8601 timestamp when subagent was last updated */
|
|
17
|
+
updatedAt: string;
|
|
18
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/config/types.ts"],"names":[],"mappings":";AAuBA,mFAAmF"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Copyright 2025 Google LLC
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
|
-
import { GenerateContentConfig, PartListUnion, Content, GenerateContentResponse } from '@google/genai';
|
|
6
|
+
import { GenerateContentConfig, PartListUnion, Content, GenerateContentResponse, SendMessageParameters } from '@google/genai';
|
|
7
7
|
import { Turn, ServerGeminiStreamEvent } from './turn.js';
|
|
8
8
|
import type { ChatCompressionInfo } from './turn.js';
|
|
9
9
|
import { Config } from '../config/config.js';
|
|
@@ -11,6 +11,7 @@ import { UserTierId } from '../code_assist/types.js';
|
|
|
11
11
|
import { GeminiChat } from './geminiChat.js';
|
|
12
12
|
import { HistoryService } from '../services/history/HistoryService.js';
|
|
13
13
|
import { ContentGenerator, ContentGeneratorConfig } from './contentGenerator.js';
|
|
14
|
+
import type { AgentRuntimeState } from '../runtime/AgentRuntimeState.js';
|
|
14
15
|
/**
|
|
15
16
|
* Returns the index of the content after the fraction of the total characters in the history.
|
|
16
17
|
*
|
|
@@ -33,6 +34,7 @@ export declare class GeminiClient {
|
|
|
33
34
|
private lastPromptId?;
|
|
34
35
|
private readonly complexityAnalyzer;
|
|
35
36
|
private readonly todoReminderService;
|
|
37
|
+
private todoToolsAvailable;
|
|
36
38
|
private lastComplexitySuggestionTime;
|
|
37
39
|
private readonly complexitySuggestionCooldown;
|
|
38
40
|
private lastSentIdeContext;
|
|
@@ -42,13 +44,30 @@ export declare class GeminiClient {
|
|
|
42
44
|
private lastComplexitySuggestionTurn?;
|
|
43
45
|
private toolActivityCount;
|
|
44
46
|
private toolCallReminderLevel;
|
|
45
|
-
private pendingInstallerNotices;
|
|
46
47
|
/**
|
|
47
48
|
* At any point in this conversation, was compression triggered without
|
|
48
49
|
* being forced and did it fail?
|
|
49
50
|
*/
|
|
50
51
|
private hasFailedCompressionAttempt;
|
|
51
|
-
|
|
52
|
+
/**
|
|
53
|
+
* Runtime state for stateless operation (Phase 5)
|
|
54
|
+
* @plan PLAN-20251027-STATELESS5.P10
|
|
55
|
+
* @requirement REQ-STAT5-003.1
|
|
56
|
+
* @pseudocode gemini-runtime.md lines 21-42
|
|
57
|
+
*/
|
|
58
|
+
private readonly runtimeState;
|
|
59
|
+
private _historyService?;
|
|
60
|
+
private _unsubscribe?;
|
|
61
|
+
/**
|
|
62
|
+
* @plan PLAN-20251027-STATELESS5.P10
|
|
63
|
+
* @requirement REQ-STAT5-003.1
|
|
64
|
+
* @pseudocode gemini-runtime.md lines 11-66
|
|
65
|
+
*
|
|
66
|
+
* Phase 5 constructor: Accept optional AgentRuntimeState and HistoryService
|
|
67
|
+
* When provided, client operates in stateless mode using runtime state
|
|
68
|
+
* Otherwise falls back to Config-based operation (backward compatibility)
|
|
69
|
+
*/
|
|
70
|
+
constructor(config: Config, runtimeState: AgentRuntimeState, historyService?: HistoryService);
|
|
52
71
|
initialize(contentGeneratorConfig: ContentGeneratorConfig): Promise<void>;
|
|
53
72
|
private lazyInitialize;
|
|
54
73
|
getContentGenerator(): ContentGenerator;
|
|
@@ -58,10 +77,6 @@ export declare class GeminiClient {
|
|
|
58
77
|
private isTodoToolCall;
|
|
59
78
|
private appendTodoSuffixToRequest;
|
|
60
79
|
private recordModelActivity;
|
|
61
|
-
/**
|
|
62
|
-
* Analyzes the current user request to determine if it's complex enough
|
|
63
|
-
* to warrant todo reminders
|
|
64
|
-
*/
|
|
65
80
|
addHistory(content: Content): Promise<void>;
|
|
66
81
|
getChat(): GeminiChat;
|
|
67
82
|
/**
|
|
@@ -89,6 +104,7 @@ export declare class GeminiClient {
|
|
|
89
104
|
setTools(): Promise<void>;
|
|
90
105
|
resetChat(): Promise<void>;
|
|
91
106
|
addDirectoryContext(): Promise<void>;
|
|
107
|
+
generateDirectMessage(params: SendMessageParameters, promptId: string): Promise<GenerateContentResponse>;
|
|
92
108
|
startChat(extraHistory?: Content[]): Promise<GeminiChat>;
|
|
93
109
|
private getIdeContextParts;
|
|
94
110
|
sendMessageStream(request: PartListUnion, signal: AbortSignal, prompt_id: string, turns?: number, originalModel?: string): AsyncGenerator<ServerGeminiStreamEvent, Turn>;
|
|
@@ -100,5 +116,9 @@ export declare class GeminiClient {
|
|
|
100
116
|
* Returns compression info if successful, null if not needed
|
|
101
117
|
*/
|
|
102
118
|
tryCompressChat(prompt_id: string, force?: boolean): Promise<ChatCompressionInfo>;
|
|
119
|
+
private getToolGovernanceEphemerals;
|
|
120
|
+
private readToolList;
|
|
121
|
+
private buildToolDeclarationsFromView;
|
|
103
122
|
private getEnabledToolNamesForPrompt;
|
|
123
|
+
private updateTodoToolAvailabilityFromDeclarations;
|
|
104
124
|
}
|