@vybestack/llxprt-code-core 0.4.7 → 0.5.0-nightly.251102.f115237d
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 +18 -1
- package/dist/src/config/config.js +123 -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 +221 -56
- 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 +413 -207
- 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 +383 -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.js +41 -1
- 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 +374 -453
- 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 +58 -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/history/ContentConverters.js +3 -5
- package/dist/src/services/history/ContentConverters.js.map +1 -1
- package/dist/src/services/shellExecutionService.js +2 -2
- package/dist/src/services/shellExecutionService.js.map +1 -1
- 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 +58 -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/gitIgnoreParser.js +15 -3
- package/dist/src/utils/gitIgnoreParser.js.map +1 -1
- package/dist/src/utils/memoryImportProcessor.js +22 -3
- package/dist/src/utils/memoryImportProcessor.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
|
@@ -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
|
}
|
package/dist/src/core/client.js
CHANGED
|
@@ -4,18 +4,20 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
import { getDirectoryContextString, getEnvironmentContext, } from '../utils/environmentContext.js';
|
|
7
|
-
import { Turn, GeminiEventType } from './turn.js';
|
|
7
|
+
import { Turn, GeminiEventType, DEFAULT_AGENT_ID, } from './turn.js';
|
|
8
8
|
import { CompressionStatus } from './turn.js';
|
|
9
|
-
import { getCoreSystemPromptAsync, getCompressionPrompt
|
|
9
|
+
import { getCoreSystemPromptAsync, getCompressionPrompt } from './prompts.js';
|
|
10
10
|
import { getResponseText } from '../utils/generateContentResponseUtilities.js';
|
|
11
11
|
import { reportError } from '../utils/errorReporting.js';
|
|
12
12
|
import { GeminiChat } from './geminiChat.js';
|
|
13
13
|
import { DebugLogger } from '../debug/index.js';
|
|
14
14
|
import { HistoryService } from '../services/history/HistoryService.js';
|
|
15
15
|
import { ContentConverters } from '../services/history/ContentConverters.js';
|
|
16
|
+
import { createProviderRuntimeContext } from '../runtime/providerRuntimeContext.js';
|
|
17
|
+
import { loadAgentRuntime } from '../runtime/AgentRuntimeLoader.js';
|
|
16
18
|
import { retryWithBackoff } from '../utils/retry.js';
|
|
17
19
|
import { getErrorMessage } from '../utils/errors.js';
|
|
18
|
-
import { createContentGenerator, } from './contentGenerator.js';
|
|
20
|
+
import { AuthType, createContentGenerator, } from './contentGenerator.js';
|
|
19
21
|
import { ProxyAgent, setGlobalDispatcher } from 'undici';
|
|
20
22
|
import { tokenLimit } from './tokenLimits.js';
|
|
21
23
|
import { COMPRESSION_TOKEN_THRESHOLD, COMPRESSION_PRESERVE_THRESHOLD, } from './compression-config.js';
|
|
@@ -25,10 +27,11 @@ import { ComplexityAnalyzer, } from '../services/complexity-analyzer.js';
|
|
|
25
27
|
import { TodoReminderService } from '../services/todo-reminder-service.js';
|
|
26
28
|
import { isFunctionResponse } from '../utils/messageInspectors.js';
|
|
27
29
|
import { estimateTokens as estimateTextTokens } from '../utils/toolOutputLimiter.js';
|
|
30
|
+
import { subscribeToAgentRuntimeState } from '../runtime/AgentRuntimeState.js';
|
|
28
31
|
const COMPLEXITY_ESCALATION_TURN_THRESHOLD = 3;
|
|
29
|
-
const TODO_PROMPT_SUFFIX = '
|
|
30
|
-
const TOOL_BASE_TODO_MESSAGE = '
|
|
31
|
-
const TOOL_ESCALATED_TODO_MESSAGE = '
|
|
32
|
+
const TODO_PROMPT_SUFFIX = 'Use TODO List to organize this effort.';
|
|
33
|
+
const TOOL_BASE_TODO_MESSAGE = 'After this next tool call I need to call todo_write and create a todo list to organize this effort.';
|
|
34
|
+
const TOOL_ESCALATED_TODO_MESSAGE = 'I have already made several tool calls without a todo list. Immediately call todo_write after this next tool call to organize the work.';
|
|
32
35
|
function isThinkingSupported(model) {
|
|
33
36
|
if (model.startsWith('gemini-2.5'))
|
|
34
37
|
return true;
|
|
@@ -88,6 +91,7 @@ export class GeminiClient {
|
|
|
88
91
|
lastPromptId;
|
|
89
92
|
complexityAnalyzer;
|
|
90
93
|
todoReminderService;
|
|
94
|
+
todoToolsAvailable = false;
|
|
91
95
|
lastComplexitySuggestionTime = 0;
|
|
92
96
|
complexitySuggestionCooldown;
|
|
93
97
|
lastSentIdeContext;
|
|
@@ -97,21 +101,61 @@ export class GeminiClient {
|
|
|
97
101
|
lastComplexitySuggestionTurn;
|
|
98
102
|
toolActivityCount = 0;
|
|
99
103
|
toolCallReminderLevel = 'none';
|
|
100
|
-
pendingInstallerNotices = [];
|
|
101
104
|
/**
|
|
102
105
|
* At any point in this conversation, was compression triggered without
|
|
103
106
|
* being forced and did it fail?
|
|
104
107
|
*/
|
|
105
108
|
hasFailedCompressionAttempt = false;
|
|
106
|
-
|
|
109
|
+
/**
|
|
110
|
+
* Runtime state for stateless operation (Phase 5)
|
|
111
|
+
* @plan PLAN-20251027-STATELESS5.P10
|
|
112
|
+
* @requirement REQ-STAT5-003.1
|
|
113
|
+
* @pseudocode gemini-runtime.md lines 21-42
|
|
114
|
+
*/
|
|
115
|
+
runtimeState;
|
|
116
|
+
_historyService;
|
|
117
|
+
_unsubscribe;
|
|
118
|
+
/**
|
|
119
|
+
* @plan PLAN-20251027-STATELESS5.P10
|
|
120
|
+
* @requirement REQ-STAT5-003.1
|
|
121
|
+
* @pseudocode gemini-runtime.md lines 11-66
|
|
122
|
+
*
|
|
123
|
+
* Phase 5 constructor: Accept optional AgentRuntimeState and HistoryService
|
|
124
|
+
* When provided, client operates in stateless mode using runtime state
|
|
125
|
+
* Otherwise falls back to Config-based operation (backward compatibility)
|
|
126
|
+
*/
|
|
127
|
+
constructor(config, runtimeState, historyService) {
|
|
107
128
|
this.config = config;
|
|
108
|
-
if (
|
|
109
|
-
|
|
129
|
+
if (!runtimeState.provider || runtimeState.provider === '') {
|
|
130
|
+
throw new Error('AgentRuntimeState must have a valid provider');
|
|
131
|
+
}
|
|
132
|
+
if (!runtimeState.model || runtimeState.model === '') {
|
|
133
|
+
throw new Error('AgentRuntimeState must have a valid model');
|
|
134
|
+
}
|
|
135
|
+
if (runtimeState.authType === AuthType.API_KEY &&
|
|
136
|
+
!runtimeState.authPayload?.apiKey) {
|
|
137
|
+
throw new Error('AgentRuntimeState must include apiKey when authType is API_KEY');
|
|
138
|
+
}
|
|
139
|
+
if (runtimeState.authType === AuthType.OAUTH &&
|
|
140
|
+
!runtimeState.authPayload?.token) {
|
|
141
|
+
throw new Error('AgentRuntimeState must include token when authType is OAUTH');
|
|
110
142
|
}
|
|
143
|
+
this.runtimeState = runtimeState;
|
|
144
|
+
this._historyService = historyService;
|
|
111
145
|
this.logger = new DebugLogger('llxprt:core:client');
|
|
112
|
-
this.
|
|
146
|
+
this._unsubscribe = subscribeToAgentRuntimeState(runtimeState.runtimeId, (event) => {
|
|
147
|
+
this.logger.debug('Runtime state changed', event);
|
|
148
|
+
});
|
|
149
|
+
void this._historyService;
|
|
150
|
+
void this._unsubscribe;
|
|
151
|
+
const proxyUrl = runtimeState.proxyUrl;
|
|
152
|
+
if (proxyUrl) {
|
|
153
|
+
setGlobalDispatcher(new ProxyAgent(proxyUrl));
|
|
154
|
+
}
|
|
155
|
+
const embeddingModel = config.getEmbeddingModel();
|
|
156
|
+
this.embeddingModel = embeddingModel || runtimeState.model;
|
|
113
157
|
this.loopDetector = new LoopDetectionService(config);
|
|
114
|
-
this.lastPromptId =
|
|
158
|
+
this.lastPromptId = runtimeState.sessionId;
|
|
115
159
|
// Initialize complexity analyzer with config settings
|
|
116
160
|
const complexitySettings = config.getComplexityAnalyzerSettings();
|
|
117
161
|
this.complexityAnalyzer = new ComplexityAnalyzer({
|
|
@@ -121,7 +165,6 @@ export class GeminiClient {
|
|
|
121
165
|
this.complexitySuggestionCooldown =
|
|
122
166
|
complexitySettings.suggestionCooldownMs ?? 300000;
|
|
123
167
|
this.todoReminderService = new TodoReminderService();
|
|
124
|
-
this.pendingInstallerNotices = [];
|
|
125
168
|
}
|
|
126
169
|
async initialize(contentGeneratorConfig) {
|
|
127
170
|
// Preserve chat history before resetting, but only if we don't already have stored history
|
|
@@ -162,6 +205,10 @@ export class GeminiClient {
|
|
|
162
205
|
return this.contentGenerator?.userTier;
|
|
163
206
|
}
|
|
164
207
|
processComplexityAnalysis(analysis) {
|
|
208
|
+
if (!this.todoToolsAvailable) {
|
|
209
|
+
this.consecutiveComplexTurns = 0;
|
|
210
|
+
return undefined;
|
|
211
|
+
}
|
|
165
212
|
if (!analysis.isComplex || !analysis.shouldSuggestTodos) {
|
|
166
213
|
this.consecutiveComplexTurns = 0;
|
|
167
214
|
return undefined;
|
|
@@ -213,25 +260,22 @@ export class GeminiClient {
|
|
|
213
260
|
return request;
|
|
214
261
|
}
|
|
215
262
|
recordModelActivity(event) {
|
|
263
|
+
if (!this.todoToolsAvailable) {
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
216
266
|
if (event.type !== GeminiEventType.Content &&
|
|
217
267
|
event.type !== GeminiEventType.ToolCallRequest) {
|
|
218
268
|
return;
|
|
219
269
|
}
|
|
220
270
|
this.toolActivityCount += 1;
|
|
221
|
-
|
|
222
|
-
// regardless of complexity - this is the core safety feature
|
|
223
|
-
if (this.toolActivityCount > 5) {
|
|
271
|
+
if (this.toolActivityCount > 4) {
|
|
224
272
|
this.toolCallReminderLevel = 'escalated';
|
|
225
273
|
}
|
|
226
|
-
else if (this.toolActivityCount ===
|
|
274
|
+
else if (this.toolActivityCount === 4 &&
|
|
227
275
|
this.toolCallReminderLevel === 'none') {
|
|
228
276
|
this.toolCallReminderLevel = 'base';
|
|
229
277
|
}
|
|
230
278
|
}
|
|
231
|
-
/**
|
|
232
|
-
* Analyzes the current user request to determine if it's complex enough
|
|
233
|
-
* to warrant todo reminders
|
|
234
|
-
*/
|
|
235
279
|
async addHistory(content) {
|
|
236
280
|
// Ensure chat is initialized before adding history
|
|
237
281
|
if (!this.hasChatInitialized()) {
|
|
@@ -331,7 +375,16 @@ export class GeminiClient {
|
|
|
331
375
|
}
|
|
332
376
|
async setTools() {
|
|
333
377
|
const toolRegistry = this.config.getToolRegistry();
|
|
334
|
-
|
|
378
|
+
if (!toolRegistry) {
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
381
|
+
const toolsView = typeof this.chat?.getToolsView === 'function'
|
|
382
|
+
? this.chat.getToolsView()
|
|
383
|
+
: undefined;
|
|
384
|
+
const toolDeclarations = toolsView
|
|
385
|
+
? this.buildToolDeclarationsFromView(toolRegistry, toolsView)
|
|
386
|
+
: toolRegistry.getFunctionDeclarations();
|
|
387
|
+
this.updateTodoToolAvailabilityFromDeclarations(toolDeclarations);
|
|
335
388
|
// Debug log for intermittent tool issues
|
|
336
389
|
const logger = new DebugLogger('llxprt:client:setTools');
|
|
337
390
|
logger.debug(() => `setTools called, declarations count: ${toolDeclarations.length}`);
|
|
@@ -378,6 +431,13 @@ export class GeminiClient {
|
|
|
378
431
|
parts: [{ text: await getDirectoryContextString(this.config) }],
|
|
379
432
|
});
|
|
380
433
|
}
|
|
434
|
+
async generateDirectMessage(params, promptId) {
|
|
435
|
+
await this.lazyInitialize();
|
|
436
|
+
if (!this.chat) {
|
|
437
|
+
this.chat = await this.startChat([]);
|
|
438
|
+
}
|
|
439
|
+
return this.getChat().generateDirectMessage(params, promptId);
|
|
440
|
+
}
|
|
381
441
|
async startChat(extraHistory) {
|
|
382
442
|
this.forceFullIdeContext = true;
|
|
383
443
|
this.hasFailedCompressionAttempt = false;
|
|
@@ -385,8 +445,6 @@ export class GeminiClient {
|
|
|
385
445
|
await this.lazyInitialize();
|
|
386
446
|
const envParts = await getEnvironmentContext(this.config);
|
|
387
447
|
const toolRegistry = this.config.getToolRegistry();
|
|
388
|
-
const toolDeclarations = toolRegistry.getFunctionDeclarations();
|
|
389
|
-
const tools = [{ functionDeclarations: toolDeclarations }];
|
|
390
448
|
const enabledToolNames = this.getEnabledToolNamesForPrompt();
|
|
391
449
|
// CRITICAL: Reuse stored HistoryService if available to preserve UI conversation display
|
|
392
450
|
// This is essential for maintaining conversation history across provider switches
|
|
@@ -403,21 +461,22 @@ export class GeminiClient {
|
|
|
403
461
|
}
|
|
404
462
|
// Add extraHistory if provided
|
|
405
463
|
if (extraHistory && extraHistory.length > 0) {
|
|
406
|
-
|
|
464
|
+
// @plan PLAN-20251027-STATELESS5.P10
|
|
465
|
+
// @requirement REQ-STAT5-003.1
|
|
466
|
+
const currentModel = this.runtimeState.model;
|
|
407
467
|
for (const content of extraHistory) {
|
|
408
468
|
historyService.add(ContentConverters.toIContent(content), currentModel);
|
|
409
469
|
}
|
|
410
470
|
}
|
|
411
471
|
try {
|
|
412
472
|
const userMemory = this.config.getUserMemory();
|
|
413
|
-
|
|
473
|
+
// @plan PLAN-20251027-STATELESS5.P10
|
|
474
|
+
// @requirement REQ-STAT5-003.1
|
|
475
|
+
const model = this.runtimeState.model;
|
|
476
|
+
// Provider name removed from prompt call signature
|
|
414
477
|
const logger = new DebugLogger('llxprt:client:start');
|
|
415
478
|
logger.debug(() => `DEBUG [client.startChat]: Model from config: ${model}`);
|
|
416
479
|
let systemInstruction = await getCoreSystemPromptAsync(userMemory, model, enabledToolNames);
|
|
417
|
-
const installerNotices = await drainPromptInstallerNotices();
|
|
418
|
-
if (installerNotices.length > 0) {
|
|
419
|
-
this.pendingInstallerNotices.push(...installerNotices);
|
|
420
|
-
}
|
|
421
480
|
// Add environment context to system instruction
|
|
422
481
|
const envContextText = envParts
|
|
423
482
|
.map((part) => ('text' in part ? part.text : ''))
|
|
@@ -435,7 +494,9 @@ export class GeminiClient {
|
|
|
435
494
|
}
|
|
436
495
|
historyService.setBaseTokenOffset(systemPromptTokens);
|
|
437
496
|
logger.debug(() => `DEBUG [client.startChat]: System instruction includes Flash instructions: ${systemInstruction.includes('IMPORTANT: You MUST use the provided tools')}`);
|
|
438
|
-
|
|
497
|
+
// @plan PLAN-20251027-STATELESS5.P10
|
|
498
|
+
// @requirement REQ-STAT5-003.1
|
|
499
|
+
const generateContentConfigWithThinking = isThinkingSupported(this.runtimeState.model)
|
|
439
500
|
? {
|
|
440
501
|
...this.generateContentConfig,
|
|
441
502
|
thinkingConfig: {
|
|
@@ -444,12 +505,48 @@ export class GeminiClient {
|
|
|
444
505
|
},
|
|
445
506
|
}
|
|
446
507
|
: this.generateContentConfig;
|
|
447
|
-
|
|
508
|
+
// @plan PLAN-20251028-STATELESS6.P10
|
|
509
|
+
// @requirement REQ-STAT6-001.2
|
|
510
|
+
// Create runtime context from config (foreground agent)
|
|
511
|
+
const settings = {
|
|
512
|
+
compressionThreshold: this.config.getEphemeralSetting('compression-threshold') ?? 0.8,
|
|
513
|
+
contextLimit: this.config.getEphemeralSetting('context-limit') ?? 60000,
|
|
514
|
+
preserveThreshold: this.config.getEphemeralSetting('compression-preserve-threshold') ?? 0.2,
|
|
515
|
+
telemetry: {
|
|
516
|
+
enabled: true,
|
|
517
|
+
target: null,
|
|
518
|
+
},
|
|
519
|
+
tools: this.getToolGovernanceEphemerals(),
|
|
520
|
+
};
|
|
521
|
+
const providerRuntime = createProviderRuntimeContext({
|
|
522
|
+
settingsService: this.config.getSettingsService(),
|
|
523
|
+
config: this.config,
|
|
524
|
+
runtimeId: this.runtimeState.runtimeId,
|
|
525
|
+
metadata: { source: 'GeminiClient.startChat' },
|
|
526
|
+
});
|
|
527
|
+
const runtimeBundle = await loadAgentRuntime({
|
|
528
|
+
profile: {
|
|
529
|
+
config: this.config,
|
|
530
|
+
state: this.runtimeState,
|
|
531
|
+
settings,
|
|
532
|
+
providerRuntime,
|
|
533
|
+
contentGeneratorConfig: this.config.getContentGeneratorConfig(),
|
|
534
|
+
toolRegistry,
|
|
535
|
+
providerManager: this.config.getProviderManager?.(),
|
|
536
|
+
},
|
|
537
|
+
overrides: {
|
|
538
|
+
historyService,
|
|
539
|
+
contentGenerator: this.getContentGenerator(),
|
|
540
|
+
},
|
|
541
|
+
});
|
|
542
|
+
const filteredDeclarations = this.buildToolDeclarationsFromView(toolRegistry, runtimeBundle.toolsView);
|
|
543
|
+
this.updateTodoToolAvailabilityFromDeclarations(filteredDeclarations);
|
|
544
|
+
const tools = [{ functionDeclarations: filteredDeclarations }];
|
|
545
|
+
return new GeminiChat(runtimeBundle.runtimeContext, runtimeBundle.contentGenerator, {
|
|
448
546
|
systemInstruction,
|
|
449
547
|
...generateContentConfigWithThinking,
|
|
450
548
|
tools,
|
|
451
|
-
}, []
|
|
452
|
-
historyService);
|
|
549
|
+
}, []);
|
|
453
550
|
}
|
|
454
551
|
catch (error) {
|
|
455
552
|
await reportError(error, 'Error initializing chat session.', extraHistory ?? [], 'startChat');
|
|
@@ -624,13 +721,6 @@ export class GeminiClient {
|
|
|
624
721
|
this.chat = await this.startChat();
|
|
625
722
|
}
|
|
626
723
|
}
|
|
627
|
-
if (this.pendingInstallerNotices.length > 0) {
|
|
628
|
-
const notices = [...this.pendingInstallerNotices];
|
|
629
|
-
this.pendingInstallerNotices = [];
|
|
630
|
-
for (const notice of notices) {
|
|
631
|
-
yield { type: GeminiEventType.SystemNotice, value: notice };
|
|
632
|
-
}
|
|
633
|
-
}
|
|
634
724
|
if (this.lastPromptId !== prompt_id) {
|
|
635
725
|
this.loopDetector.reset(prompt_id);
|
|
636
726
|
this.lastPromptId = prompt_id;
|
|
@@ -644,7 +734,7 @@ export class GeminiClient {
|
|
|
644
734
|
const contentGenConfig = this.config.getContentGeneratorConfig();
|
|
645
735
|
const providerManager = contentGenConfig?.providerManager;
|
|
646
736
|
const providerName = providerManager?.getActiveProviderName() || 'backend';
|
|
647
|
-
return new Turn(this.getChat(), prompt_id, providerName);
|
|
737
|
+
return new Turn(this.getChat(), prompt_id, DEFAULT_AGENT_ID, providerName);
|
|
648
738
|
}
|
|
649
739
|
// Ensure turns never exceeds MAX_TURNS to prevent infinite loops
|
|
650
740
|
const boundedTurns = Math.min(turns, this.MAX_TURNS);
|
|
@@ -652,16 +742,15 @@ export class GeminiClient {
|
|
|
652
742
|
const contentGenConfig = this.config.getContentGeneratorConfig();
|
|
653
743
|
const providerManager = contentGenConfig?.providerManager;
|
|
654
744
|
const providerName = providerManager?.getActiveProviderName() || 'backend';
|
|
655
|
-
return new Turn(this.getChat(), prompt_id, providerName);
|
|
745
|
+
return new Turn(this.getChat(), prompt_id, DEFAULT_AGENT_ID, providerName);
|
|
656
746
|
}
|
|
657
747
|
// Track the original model from the first call to detect model switching
|
|
658
|
-
|
|
659
|
-
//
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
}
|
|
748
|
+
// @plan PLAN-20251027-STATELESS5.P10
|
|
749
|
+
// @requirement REQ-STAT5-003.1
|
|
750
|
+
const initialModel = originalModel || this.runtimeState.model;
|
|
751
|
+
const compressed = await this.tryCompressChat(prompt_id);
|
|
752
|
+
if (compressed.compressionStatus === CompressionStatus.COMPRESSED) {
|
|
753
|
+
yield { type: GeminiEventType.ChatCompressed, value: compressed };
|
|
665
754
|
}
|
|
666
755
|
// Prevent context updates from being sent while a tool call is
|
|
667
756
|
// waiting for a response. The Gemini API requires that a functionResponse
|
|
@@ -712,7 +801,7 @@ export class GeminiClient {
|
|
|
712
801
|
const contentGenConfig = this.config.getContentGeneratorConfig();
|
|
713
802
|
const providerManager = contentGenConfig?.providerManager;
|
|
714
803
|
const providerName = providerManager?.getActiveProviderName() || 'backend';
|
|
715
|
-
const turn = new Turn(this.getChat(), prompt_id, providerName);
|
|
804
|
+
const turn = new Turn(this.getChat(), prompt_id, DEFAULT_AGENT_ID, providerName);
|
|
716
805
|
const loopDetected = await this.loopDetector.turnStarted(signal);
|
|
717
806
|
if (loopDetected) {
|
|
718
807
|
yield { type: GeminiEventType.LoopDetected };
|
|
@@ -735,7 +824,7 @@ export class GeminiClient {
|
|
|
735
824
|
return turn;
|
|
736
825
|
}
|
|
737
826
|
}
|
|
738
|
-
if (this.toolCallReminderLevel !== 'none') {
|
|
827
|
+
if (this.todoToolsAvailable && this.toolCallReminderLevel !== 'none') {
|
|
739
828
|
const reminderText = this.toolCallReminderLevel === 'escalated'
|
|
740
829
|
? TOOL_ESCALATED_TODO_MESSAGE
|
|
741
830
|
: TOOL_BASE_TODO_MESSAGE;
|
|
@@ -752,7 +841,9 @@ export class GeminiClient {
|
|
|
752
841
|
}
|
|
753
842
|
if (!turn.pendingToolCalls.length && signal && !signal.aborted) {
|
|
754
843
|
// Check if model was switched during the call (likely due to quota error)
|
|
755
|
-
|
|
844
|
+
// @plan PLAN-20251027-STATELESS5.P10
|
|
845
|
+
// @requirement REQ-STAT5-003.1
|
|
846
|
+
const currentModel = this.runtimeState.model;
|
|
756
847
|
if (currentModel !== initialModel) {
|
|
757
848
|
// Model was switched (likely due to quota error fallback)
|
|
758
849
|
// Don't continue with recursive call to prevent unwanted Flash execution
|
|
@@ -768,6 +859,7 @@ export class GeminiClient {
|
|
|
768
859
|
const modelToUse = model;
|
|
769
860
|
try {
|
|
770
861
|
const userMemory = this.config.getUserMemory();
|
|
862
|
+
// Provider name removed from prompt call signature
|
|
771
863
|
const systemInstruction = await getCoreSystemPromptAsync(userMemory, modelToUse, this.getEnabledToolNamesForPrompt());
|
|
772
864
|
const requestConfig = {
|
|
773
865
|
abortSignal,
|
|
@@ -846,6 +938,7 @@ export class GeminiClient {
|
|
|
846
938
|
};
|
|
847
939
|
try {
|
|
848
940
|
const userMemory = this.config.getUserMemory();
|
|
941
|
+
// Provider name removed from prompt call signature
|
|
849
942
|
const systemInstruction = await getCoreSystemPromptAsync(userMemory, modelToUse, this.getEnabledToolNamesForPrompt());
|
|
850
943
|
const requestConfig = {
|
|
851
944
|
abortSignal,
|
|
@@ -920,7 +1013,9 @@ export class GeminiClient {
|
|
|
920
1013
|
};
|
|
921
1014
|
}
|
|
922
1015
|
// Note: chat variable used later in method
|
|
923
|
-
|
|
1016
|
+
// @plan PLAN-20251027-STATELESS5.P10
|
|
1017
|
+
// @requirement REQ-STAT5-003.1
|
|
1018
|
+
const model = this.runtimeState.model;
|
|
924
1019
|
// Get the ACTUAL token count from the history service, not the curated subset
|
|
925
1020
|
const historyService = this.getChat().getHistoryService();
|
|
926
1021
|
const originalTokenCount = historyService
|
|
@@ -939,7 +1034,9 @@ export class GeminiClient {
|
|
|
939
1034
|
// Don't compress if not forced and we are under the limit.
|
|
940
1035
|
if (!force) {
|
|
941
1036
|
const threshold = contextPercentageThreshold ?? COMPRESSION_TOKEN_THRESHOLD;
|
|
942
|
-
|
|
1037
|
+
const userContextLimit = this.config.getEphemeralSetting('context-limit');
|
|
1038
|
+
if (originalTokenCount <
|
|
1039
|
+
threshold * tokenLimit(model, userContextLimit)) {
|
|
943
1040
|
return {
|
|
944
1041
|
originalTokenCount,
|
|
945
1042
|
newTokenCount: originalTokenCount,
|
|
@@ -1014,10 +1111,13 @@ export class GeminiClient {
|
|
|
1014
1111
|
if (typeof compressedChat.getHistoryService === 'function') {
|
|
1015
1112
|
const historyService = compressedChat.getHistoryService();
|
|
1016
1113
|
if (historyService) {
|
|
1114
|
+
const userContextLimit = this.config.getEphemeralSetting('context-limit');
|
|
1115
|
+
// @plan PLAN-20251027-STATELESS5.P10
|
|
1116
|
+
// @requirement REQ-STAT5-003.1
|
|
1017
1117
|
historyService.emit('tokensUpdated', {
|
|
1018
1118
|
totalTokens: newTokenCount,
|
|
1019
1119
|
addedTokens: newTokenCount - originalTokenCount,
|
|
1020
|
-
tokenLimit: tokenLimit(this.
|
|
1120
|
+
tokenLimit: tokenLimit(this.runtimeState.model, userContextLimit),
|
|
1021
1121
|
});
|
|
1022
1122
|
}
|
|
1023
1123
|
}
|
|
@@ -1028,6 +1128,63 @@ export class GeminiClient {
|
|
|
1028
1128
|
compressionStatus: CompressionStatus.COMPRESSED,
|
|
1029
1129
|
};
|
|
1030
1130
|
}
|
|
1131
|
+
getToolGovernanceEphemerals() {
|
|
1132
|
+
const allowedList = this.readToolList(this.config.getEphemeralSetting('tools.allowed'));
|
|
1133
|
+
const disabledList = this.readToolList(this.config.getEphemeralSetting('tools.disabled') ??
|
|
1134
|
+
this.config.getEphemeralSetting('disabled-tools'));
|
|
1135
|
+
const hasAllowed = allowedList.length > 0;
|
|
1136
|
+
const hasDisabled = disabledList.length > 0;
|
|
1137
|
+
if (!hasAllowed && !hasDisabled) {
|
|
1138
|
+
return undefined;
|
|
1139
|
+
}
|
|
1140
|
+
return {
|
|
1141
|
+
allowed: hasAllowed ? allowedList : undefined,
|
|
1142
|
+
disabled: hasDisabled ? disabledList : undefined,
|
|
1143
|
+
};
|
|
1144
|
+
}
|
|
1145
|
+
readToolList(value) {
|
|
1146
|
+
if (!Array.isArray(value)) {
|
|
1147
|
+
return [];
|
|
1148
|
+
}
|
|
1149
|
+
const filtered = value.filter((entry) => typeof entry === 'string' && entry.trim().length > 0);
|
|
1150
|
+
return filtered.length > 0 ? [...filtered] : [];
|
|
1151
|
+
}
|
|
1152
|
+
buildToolDeclarationsFromView(toolRegistry, view) {
|
|
1153
|
+
if (!toolRegistry) {
|
|
1154
|
+
return [];
|
|
1155
|
+
}
|
|
1156
|
+
const allowedNames = view.listToolNames();
|
|
1157
|
+
if (allowedNames.length === 0) {
|
|
1158
|
+
return [];
|
|
1159
|
+
}
|
|
1160
|
+
const declarations = [];
|
|
1161
|
+
if (typeof toolRegistry.getAllTools === 'function') {
|
|
1162
|
+
const toolsByName = new Map(toolRegistry.getAllTools().map((tool) => [tool.name, tool]));
|
|
1163
|
+
for (const name of allowedNames) {
|
|
1164
|
+
const tool = toolsByName.get(name);
|
|
1165
|
+
if (!tool) {
|
|
1166
|
+
continue;
|
|
1167
|
+
}
|
|
1168
|
+
const schema = tool.schema;
|
|
1169
|
+
if (schema) {
|
|
1170
|
+
declarations.push(schema);
|
|
1171
|
+
}
|
|
1172
|
+
}
|
|
1173
|
+
return declarations;
|
|
1174
|
+
}
|
|
1175
|
+
if (typeof toolRegistry.getFunctionDeclarations === 'function') {
|
|
1176
|
+
const declarationsByName = new Map(toolRegistry
|
|
1177
|
+
.getFunctionDeclarations()
|
|
1178
|
+
.map((decl) => [decl.name, decl]));
|
|
1179
|
+
for (const name of allowedNames) {
|
|
1180
|
+
const declaration = declarationsByName.get(name);
|
|
1181
|
+
if (declaration) {
|
|
1182
|
+
declarations.push(declaration);
|
|
1183
|
+
}
|
|
1184
|
+
}
|
|
1185
|
+
}
|
|
1186
|
+
return declarations;
|
|
1187
|
+
}
|
|
1031
1188
|
getEnabledToolNamesForPrompt() {
|
|
1032
1189
|
const toolRegistry = this.config.getToolRegistry();
|
|
1033
1190
|
if (!toolRegistry ||
|
|
@@ -1040,5 +1197,13 @@ export class GeminiClient {
|
|
|
1040
1197
|
.map((tool) => tool.name)
|
|
1041
1198
|
.filter(Boolean)));
|
|
1042
1199
|
}
|
|
1200
|
+
updateTodoToolAvailabilityFromDeclarations(declarations) {
|
|
1201
|
+
const normalizedNames = new Set(declarations
|
|
1202
|
+
.map((decl) => decl?.name)
|
|
1203
|
+
.filter((name) => typeof name === 'string')
|
|
1204
|
+
.map((name) => name.toLowerCase()));
|
|
1205
|
+
this.todoToolsAvailable =
|
|
1206
|
+
normalizedNames.has('todo_write') && normalizedNames.has('todo_read');
|
|
1207
|
+
}
|
|
1043
1208
|
}
|
|
1044
1209
|
//# sourceMappingURL=client.js.map
|