diff --git a/docs/roadmap/05-delta-types.md b/docs/roadmap/05-delta-types.md new file mode 100644 index 00000000000..920f6c5796c --- /dev/null +++ b/docs/roadmap/05-delta-types.md @@ -0,0 +1,138 @@ +# Decouple from @google/genai Types + +## Branch: `refactor/delta-types` + +## Problem + +67 files import from `@google/genai`. Every provider converts to/from Google's +type system, which means: + +- Google-specific concepts (`safetyRatings`, `promptFeedback`, + `FinishReason.FINISH_REASON_UNSPECIFIED`) leak into non-Google responses as + empty placeholders +- Provider-specific features (Anthropic citations, OpenAI structured outputs, + think blocks) can't be represented without extending Google's types +- Tight coupling to a third-party type system makes upgrades risky — a breaking + change in `@google/genai` ripples through the entire codebase + +## Approach + +Define Delta-native types as the canonical interchange format. Google types +become one translation layer among many, not the canonical truth. + +## Plan + +### Phase 1: Define `packages/core/src/types/delta.ts` + +Core types that map to what Delta actually needs: + +```typescript +// The Delta canonical message format — what flows between providers and the UI +interface DeltaMessage { + role: 'user' | 'assistant' | 'system'; + parts: DeltaPart[]; +} + +type DeltaPart = + | { type: 'text'; text: string } + | { type: 'functionCall'; id: string; name: string; args: Record } + | { type: 'functionResponse'; id: string; name: string; response: unknown } + | { type: 'thinking'; text: string } // reasoning models + | { type: 'image'; mimeType: string; data: string } // vision + | { type: 'citation'; source: string; text: string }; // Anthropic citations etc. + +interface DeltaResponse { + id: string; + model: string; + parts: DeltaPart[]; + finishReason: DeltaFinishReason; + usage?: DeltaUsage; +} + +enum DeltaFinishReason { + STOP = 'stop', + MAX_TOKENS = 'max_tokens', + TOOL_USE = 'tool_use', + ERROR = 'error', + UNSPECIFIED = 'unspecified', +} + +interface DeltaUsage { + inputTokens: number; + outputTokens: number; + totalTokens: number; + cachedTokens?: number; +} + +interface DeltaToolDeclaration { + name: string; + description: string; + parameters: Record; // JSON Schema +} + +interface DeltaGenerateRequest { + messages: DeltaMessage[]; + tools?: DeltaToolDeclaration[]; + systemPrompt?: string; + config?: DeltaGenerateConfig; +} + +interface DeltaGenerateConfig { + maxOutputTokens?: number; + temperature?: number; + topP?: number; + topK?: number; + stopSequences?: string[]; +} +``` + +### Phase 2: Create adapter layer per provider + +``` +packages/core/src/adapters/ + googleAdapter.ts — DeltaMessage ↔ @google/genai types + openaiAdapter.ts — DeltaMessage ↔ OpenAI SDK types + anthropicAdapter.ts — DeltaMessage ↔ Anthropic SDK types +``` + +Each adapter exports `toProviderFormat()` and `fromProviderFormat()`. The +content generators call these instead of doing inline conversion. + +### Phase 3: Migrate ContentGenerator interface + +Change the interface signature from Google types to Delta types: + +```typescript +interface ContentGenerator { + generateContent(request: DeltaGenerateRequest): Promise; + generateContentStream(request: DeltaGenerateRequest): AsyncGenerator; + countTokens(messages: DeltaMessage[]): Promise; +} +``` + +### Phase 4: Migrate consumers (67 files) + +This is the bulk of the work. Grep for all `@google/genai` imports and replace +with Delta types. The Google backend's adapter handles the actual SDK calls. + +**Migration strategy**: do it file-by-file, keeping both type systems working +during the transition via a compatibility shim. Remove the shim once all files +are migrated. + +## Files to create +- `packages/core/src/types/delta.ts` — canonical types +- `packages/core/src/adapters/googleAdapter.ts` +- `packages/core/src/adapters/openaiAdapter.ts` +- `packages/core/src/adapters/anthropicAdapter.ts` +- Tests for each adapter + +## Scope warning + +This is the largest refactor. It touches 67+ files. Should be done after +branches 1-4 are merged to avoid merge hell. + +## Dependencies +- Should merge AFTER `fix/anthropic-provider` (branch 1) — otherwise the + Anthropic adapter would be written against the broken raw-fetch implementation +- Should merge AFTER `feature/schema-normalization` (branch 2) — schema + normalization can be built into the adapter layer cleanly diff --git a/packages/cli/src/nonInteractiveCli.ts b/packages/cli/src/nonInteractiveCli.ts index bccb6dae8be..11097516867 100644 --- a/packages/cli/src/nonInteractiveCli.ts +++ b/packages/cli/src/nonInteractiveCli.ts @@ -4,6 +4,11 @@ * SPDX-License-Identifier: Apache-2.0 */ +import { + Content, + Part, + FunctionCall, +} from '../../core/src/types/delta.js'; import { Config, ToolCallRequestInfo, @@ -15,7 +20,6 @@ import { ToolErrorType, parseAndFormatApiError, } from '@delta-code/delta-code-core'; -import { Content, Part, FunctionCall } from '@google/genai'; import { ConsolePatcher } from './ui/utils/ConsolePatcher.js'; diff --git a/packages/cli/src/ui/commands/types.ts b/packages/cli/src/ui/commands/types.ts index b564d4d3a93..e3fcd648c22 100644 --- a/packages/cli/src/ui/commands/types.ts +++ b/packages/cli/src/ui/commands/types.ts @@ -4,8 +4,11 @@ * SPDX-License-Identifier: Apache-2.0 */ +import { + Content, +} from '../../../../core/src/types/delta.js'; import { type ReactNode } from 'react'; -import { Content } from '@google/genai'; + import { HistoryItemWithoutId } from '../types.js'; import { Config, GitService, Logger } from '@delta-code/delta-code-core'; import { LoadedSettings } from '../../config/settings.js'; diff --git a/packages/cli/src/ui/hooks/atCommandProcessor.ts b/packages/cli/src/ui/hooks/atCommandProcessor.ts index 18a0ee4569e..74c41e133e9 100644 --- a/packages/cli/src/ui/hooks/atCommandProcessor.ts +++ b/packages/cli/src/ui/hooks/atCommandProcessor.ts @@ -4,9 +4,13 @@ * SPDX-License-Identifier: Apache-2.0 */ +import { + PartListUnion, + PartUnion, +} from '../../../../core/src/types/delta.js'; import * as fs from 'fs/promises'; import * as path from 'path'; -import { PartListUnion, PartUnion } from '@google/genai'; + import { AnyToolInvocation, Config, diff --git a/packages/cli/src/ui/hooks/shellCommandProcessor.ts b/packages/cli/src/ui/hooks/shellCommandProcessor.ts index aaef5171df0..a13429ede86 100644 --- a/packages/cli/src/ui/hooks/shellCommandProcessor.ts +++ b/packages/cli/src/ui/hooks/shellCommandProcessor.ts @@ -4,6 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ +import { + PartListUnion, +} from '../../../../core/src/types/delta.js'; import { HistoryItemWithoutId, IndividualToolCallDisplay, @@ -17,7 +20,7 @@ import { ShellExecutionResult, ShellExecutionService, } from '@delta-code/delta-code-core'; -import { type PartListUnion } from '@google/genai'; + import { UseHistoryManagerReturn } from './useHistoryManager.js'; import { SHELL_COMMAND_NAME } from '../constants.js'; import { formatMemoryUsage } from '../utils/formatters.js'; diff --git a/packages/cli/src/ui/hooks/slashCommandProcessor.ts b/packages/cli/src/ui/hooks/slashCommandProcessor.ts index b0015d6db94..2a2100f136c 100644 --- a/packages/cli/src/ui/hooks/slashCommandProcessor.ts +++ b/packages/cli/src/ui/hooks/slashCommandProcessor.ts @@ -4,8 +4,11 @@ * SPDX-License-Identifier: Apache-2.0 */ +import { + PartListUnion, +} from '../../../../core/src/types/delta.js'; import { useCallback, useMemo, useEffect, useState } from 'react'; -import { type PartListUnion } from '@google/genai'; + import process from 'node:process'; import { UseHistoryManagerReturn } from './useHistoryManager.js'; import { useStateAndRef } from './useStateAndRef.js'; diff --git a/packages/cli/src/ui/hooks/useDeltaStream.ts b/packages/cli/src/ui/hooks/useDeltaStream.ts index 460a84c67b3..2e5b129a2f0 100644 --- a/packages/cli/src/ui/hooks/useDeltaStream.ts +++ b/packages/cli/src/ui/hooks/useDeltaStream.ts @@ -4,7 +4,11 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { type Part, type PartListUnion, FinishReason } from '@google/genai'; +import { + Part, + PartListUnion, + FinishReason, +} from '../../../../core/src/types/delta.js'; import { Config, ServerDeltaContentEvent as ContentEvent, diff --git a/packages/cli/src/zed-integration/zedIntegration.ts b/packages/cli/src/zed-integration/zedIntegration.ts index 1dc41d9f757..61f59a55e5f 100644 --- a/packages/cli/src/zed-integration/zedIntegration.ts +++ b/packages/cli/src/zed-integration/zedIntegration.ts @@ -4,9 +4,14 @@ * SPDX-License-Identifier: Apache-2.0 */ +import { + Content, + FunctionCall, + Part, + PartListUnion, +} from '../../../core/src/types/delta.js'; import { ReadableStream, WritableStream } from 'node:stream/web'; -import { Content, FunctionCall, Part, PartListUnion } from '@google/genai'; import { AuthType, clearCachedCredentialFile, diff --git a/packages/core/src/core/client.ts b/packages/core/src/core/client.ts index 5861e9ed18a..ed3c98202cd 100644 --- a/packages/core/src/core/client.ts +++ b/packages/core/src/core/client.ts @@ -13,7 +13,7 @@ import { GenerateContentResponse, FunctionDeclaration, Schema, -} from '@google/genai'; +} from '../types/delta.js'; import { getDirectoryContextString, getEnvironmentContext, diff --git a/packages/core/src/core/coreToolScheduler.ts b/packages/core/src/core/coreToolScheduler.ts index fac06882d58..f92d69c876c 100644 --- a/packages/core/src/core/coreToolScheduler.ts +++ b/packages/core/src/core/coreToolScheduler.ts @@ -4,6 +4,10 @@ * SPDX-License-Identifier: Apache-2.0 */ +import { + Part, + PartListUnion, +} from '../types/delta.js'; import { ToolCallRequestInfo, ToolCallResponseInfo, @@ -23,7 +27,7 @@ import { AnyToolInvocation, } from '../index.js'; import { HookManager } from '../hooks/hookManager.js'; -import { Part, PartListUnion } from '@google/genai'; + import { getResponseTextFromParts } from '../utils/generateContentResponseUtilities.js'; import { isModifiableDeclarativeTool, diff --git a/packages/core/src/core/deltaChat.ts b/packages/core/src/core/deltaChat.ts index f0605d46853..6a75a807c22 100644 --- a/packages/core/src/core/deltaChat.ts +++ b/packages/core/src/core/deltaChat.ts @@ -11,10 +11,12 @@ import { GenerateContentResponse, Content, GenerateContentConfig, - SendMessageParameters, - createUserContent, Part, Tool, +} from '../types/delta.js'; +import { + SendMessageParameters, + createUserContent, } from '@google/genai'; import { retryWithBackoff } from '../utils/retry.js'; import { isFunctionResponse } from '../utils/messageInspectors.js'; diff --git a/packages/core/src/core/deltaRequest.ts b/packages/core/src/core/deltaRequest.ts index a26301f59df..4d44a935be6 100644 --- a/packages/core/src/core/deltaRequest.ts +++ b/packages/core/src/core/deltaRequest.ts @@ -4,7 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { type PartListUnion } from '@google/genai'; +import { + PartListUnion, +} from '../types/delta.js'; import { partToString } from '../utils/partUtils.js'; /** diff --git a/packages/core/src/core/logger.ts b/packages/core/src/core/logger.ts index 71be7d8d179..68c7c1ca977 100644 --- a/packages/core/src/core/logger.ts +++ b/packages/core/src/core/logger.ts @@ -4,9 +4,12 @@ * SPDX-License-Identifier: Apache-2.0 */ +import { + Content, +} from '../types/delta.js'; import path from 'node:path'; import { promises as fs } from 'node:fs'; -import { Content } from '@google/genai'; + import { getProjectTempDir } from '../utils/paths.js'; const LOG_FILE_NAME = 'logs.json'; diff --git a/packages/core/src/core/subagent.ts b/packages/core/src/core/subagent.ts index 3f2b0d3c645..f2c5ca6f848 100644 --- a/packages/core/src/core/subagent.ts +++ b/packages/core/src/core/subagent.ts @@ -4,13 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { reportError } from '../utils/errorReporting.js'; -import { ToolRegistry } from '../tools/tool-registry.js'; -import { Config } from '../config/config.js'; -import { ToolCallRequestInfo } from './turn.js'; -import { executeToolCall } from './nonInteractiveToolExecutor.js'; -import { createContentGenerator } from './contentGenerator.js'; -import { getEnvironmentContext } from '../utils/environmentContext.js'; import { Content, Part, @@ -18,7 +11,15 @@ import { GenerateContentConfig, FunctionDeclaration, Type, -} from '@google/genai'; +} from '../types/delta.js'; +import { reportError } from '../utils/errorReporting.js'; +import { ToolRegistry } from '../tools/tool-registry.js'; +import { Config } from '../config/config.js'; +import { ToolCallRequestInfo } from './turn.js'; +import { executeToolCall } from './nonInteractiveToolExecutor.js'; +import { createContentGenerator } from './contentGenerator.js'; +import { getEnvironmentContext } from '../utils/environmentContext.js'; + import { DeltaChat } from './deltaChat.js'; /** diff --git a/packages/core/src/core/turn.ts b/packages/core/src/core/turn.ts index 23e17a09b63..02d0b89877b 100644 --- a/packages/core/src/core/turn.ts +++ b/packages/core/src/core/turn.ts @@ -10,7 +10,7 @@ import { FunctionCall, FunctionDeclaration, FinishReason, -} from '@google/genai'; +} from '../types/delta.js'; import { ToolCallConfirmationDetails, ToolResult, diff --git a/packages/core/src/telemetry/types.ts b/packages/core/src/telemetry/types.ts index 9bc9f0a0050..ea984cf02db 100644 --- a/packages/core/src/telemetry/types.ts +++ b/packages/core/src/telemetry/types.ts @@ -4,7 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { GenerateContentResponseUsageMetadata } from '@google/genai'; +import { + GenerateContentResponseUsageMetadata, +} from '../types/delta.js'; import { Config } from '../config/config.js'; import { CompletedToolCall } from '../core/coreToolScheduler.js'; import { FileDiff } from '../tools/tools.js'; diff --git a/packages/core/src/test-utils/tools.ts b/packages/core/src/test-utils/tools.ts index da64221262f..0137a7332ee 100644 --- a/packages/core/src/test-utils/tools.ts +++ b/packages/core/src/test-utils/tools.ts @@ -4,6 +4,10 @@ * SPDX-License-Identifier: Apache-2.0 */ +import { + Schema, + Type, +} from '../types/delta.js'; import { vi } from 'vitest'; import { BaseTool, @@ -11,7 +15,6 @@ import { ToolResult, Kind, } from '../tools/tools.js'; -import { Schema, Type } from '@google/genai'; /** * A highly configurable mock tool for testing purposes. diff --git a/packages/core/src/tools/checkpoint.ts b/packages/core/src/tools/checkpoint.ts index 64540ee3ae7..626ffbbf854 100644 --- a/packages/core/src/tools/checkpoint.ts +++ b/packages/core/src/tools/checkpoint.ts @@ -8,13 +8,16 @@ * persistent, semantically-searchable change ledger across sessions. */ +import { + FunctionDeclaration, +} from '../types/delta.js'; import { BaseDeclarativeTool, BaseToolInvocation, Kind, ToolResult, } from './tools.js'; -import { FunctionDeclaration } from '@google/genai'; + import * as fs from 'node:fs/promises'; import * as path from 'node:path'; import { getOpenBrainClient } from '../services/openBrainClient.js'; diff --git a/packages/core/src/tools/diffPreview.ts b/packages/core/src/tools/diffPreview.ts index 789806522bc..993b4e1e06e 100644 --- a/packages/core/src/tools/diffPreview.ts +++ b/packages/core/src/tools/diffPreview.ts @@ -5,13 +5,16 @@ * Uses the `diff` package (already a dependency) to generate unified diffs. */ +import { + FunctionDeclaration, +} from '../types/delta.js'; import { BaseDeclarativeTool, BaseToolInvocation, Kind, ToolResult, } from './tools.js'; -import { FunctionDeclaration } from '@google/genai'; + import * as fs from 'node:fs/promises'; import { createPatch } from 'diff'; diff --git a/packages/core/src/tools/fileSummary.ts b/packages/core/src/tools/fileSummary.ts index 8301f436b81..0c5d67bd92d 100644 --- a/packages/core/src/tools/fileSummary.ts +++ b/packages/core/src/tools/fileSummary.ts @@ -8,13 +8,16 @@ * the shared AST extraction layer for better accuracy. */ +import { + FunctionDeclaration, +} from '../types/delta.js'; import { BaseDeclarativeTool, BaseToolInvocation, Kind, ToolResult, } from './tools.js'; -import { FunctionDeclaration } from '@google/genai'; + import * as fs from 'node:fs/promises'; import * as path from 'node:path'; diff --git a/packages/core/src/tools/lint.ts b/packages/core/src/tools/lint.ts index 9589ee40853..c4e6b7c248f 100644 --- a/packages/core/src/tools/lint.ts +++ b/packages/core/src/tools/lint.ts @@ -2,13 +2,16 @@ * Lint tool — auto-detect and run the project linter with structured output. */ +import { + FunctionDeclaration, +} from '../types/delta.js'; import { BaseDeclarativeTool, BaseToolInvocation, Kind, ToolResult, } from './tools.js'; -import { FunctionDeclaration } from '@google/genai'; + import { execSync } from 'node:child_process'; import { detectProjectCommands } from './diagnostics/projectDetector.js'; import { parseGenericDiagnostics, formatDiagnostics } from './diagnostics/outputParsers.js'; diff --git a/packages/core/src/tools/mcp-client.ts b/packages/core/src/tools/mcp-client.ts index c0cd632289c..88c6b914d0e 100644 --- a/packages/core/src/tools/mcp-client.ts +++ b/packages/core/src/tools/mcp-client.ts @@ -4,6 +4,12 @@ * SPDX-License-Identifier: Apache-2.0 */ +import { + FunctionDeclaration, +} from '../types/delta.js'; +import { + mcpToTool, +} from '@google/genai'; import { Client } from '@modelcontextprotocol/sdk/client/index.js'; import { Transport } from '@modelcontextprotocol/sdk/shared/transport.js'; import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js'; @@ -27,7 +33,6 @@ import { AuthProviderType, MCPServerConfig } from '../config/config.js'; import { GoogleCredentialProvider } from '../mcp/google-auth-provider.js'; import { DiscoveredMCPTool } from './mcp-tool.js'; -import { FunctionDeclaration, mcpToTool } from '@google/genai'; import { ToolRegistry } from './tool-registry.js'; import { PromptRegistry } from '../prompts/prompt-registry.js'; import { MCPOAuthProvider } from '../mcp/oauth-provider.js'; diff --git a/packages/core/src/tools/mcp-tool.ts b/packages/core/src/tools/mcp-tool.ts index fbb104fde92..1fef5011000 100644 --- a/packages/core/src/tools/mcp-tool.ts +++ b/packages/core/src/tools/mcp-tool.ts @@ -4,6 +4,11 @@ * SPDX-License-Identifier: Apache-2.0 */ +import { + CallableTool, + FunctionCall, + Part, +} from '../types/delta.js'; import { BaseDeclarativeTool, BaseToolInvocation, @@ -14,7 +19,6 @@ import { ToolMcpConfirmationDetails, ToolResult, } from './tools.js'; -import { CallableTool, FunctionCall, Part } from '@google/genai'; type ToolParams = Record; diff --git a/packages/core/src/tools/memoryTool.ts b/packages/core/src/tools/memoryTool.ts index 4c2a9e0303e..6d2b2a5dd59 100644 --- a/packages/core/src/tools/memoryTool.ts +++ b/packages/core/src/tools/memoryTool.ts @@ -4,6 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ +import { + FunctionDeclaration, +} from '../types/delta.js'; import { BaseDeclarativeTool, BaseToolInvocation, @@ -12,7 +15,7 @@ import { ToolEditConfirmationDetails, ToolConfirmationOutcome, } from './tools.js'; -import { FunctionDeclaration } from '@google/genai'; + import * as fs from 'fs/promises'; import * as path from 'path'; import { homedir } from 'os'; diff --git a/packages/core/src/tools/multiEdit.ts b/packages/core/src/tools/multiEdit.ts index 4c4ffd95f7a..348f5682738 100644 --- a/packages/core/src/tools/multiEdit.ts +++ b/packages/core/src/tools/multiEdit.ts @@ -6,13 +6,16 @@ * This prevents partial refactors that leave the codebase in a broken state. */ +import { + FunctionDeclaration, +} from '../types/delta.js'; import { BaseDeclarativeTool, BaseToolInvocation, Kind, ToolResult, } from './tools.js'; -import { FunctionDeclaration } from '@google/genai'; + import * as fs from 'node:fs/promises'; interface EditEntry { diff --git a/packages/core/src/tools/read-file.ts b/packages/core/src/tools/read-file.ts index ecc2168d12e..861d3234a79 100644 --- a/packages/core/src/tools/read-file.ts +++ b/packages/core/src/tools/read-file.ts @@ -4,6 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ +import { + PartUnion, +} from '../types/delta.js'; import path from 'path'; import { SchemaValidator } from '../utils/schemaValidator.js'; import { makeRelative, shortenPath } from '../utils/paths.js'; @@ -16,7 +19,7 @@ import { ToolResult, } from './tools.js'; import { ToolErrorType } from './tool-error.js'; -import { PartUnion } from '@google/genai'; + import { processSingleFileContent, getSpecificMimeType, diff --git a/packages/core/src/tools/read-many-files.ts b/packages/core/src/tools/read-many-files.ts index fd960767161..cfb0979e796 100644 --- a/packages/core/src/tools/read-many-files.ts +++ b/packages/core/src/tools/read-many-files.ts @@ -4,6 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ +import { + PartListUnion, +} from '../types/delta.js'; import { BaseDeclarativeTool, BaseToolInvocation, @@ -22,7 +25,7 @@ import { DEFAULT_ENCODING, getSpecificMimeType, } from '../utils/fileUtils.js'; -import { PartListUnion } from '@google/genai'; + import { Config, DEFAULT_FILE_FILTERING_OPTIONS } from '../config/config.js'; import { recordFileOperationMetric, diff --git a/packages/core/src/tools/repoMap.ts b/packages/core/src/tools/repoMap.ts index 588674cefbd..00356227a76 100644 --- a/packages/core/src/tools/repoMap.ts +++ b/packages/core/src/tools/repoMap.ts @@ -10,13 +10,16 @@ * in context or grep speculatively. */ +import { + FunctionDeclaration, +} from '../types/delta.js'; import { BaseDeclarativeTool, BaseToolInvocation, Kind, ToolResult, } from './tools.js'; -import { FunctionDeclaration } from '@google/genai'; + import { RepoIndex } from '../indexing/repoIndex.js'; import { RegexSymbolExtractor } from '../indexing/symbolExtractor.js'; import { Config } from '../config/config.js'; diff --git a/packages/core/src/tools/runTests.ts b/packages/core/src/tools/runTests.ts index 686e5453f73..91865d95bd2 100644 --- a/packages/core/src/tools/runTests.ts +++ b/packages/core/src/tools/runTests.ts @@ -2,13 +2,16 @@ * Test runner tool — auto-detect and run project tests with structured output. */ +import { + FunctionDeclaration, +} from '../types/delta.js'; import { BaseDeclarativeTool, BaseToolInvocation, Kind, ToolResult, } from './tools.js'; -import { FunctionDeclaration } from '@google/genai'; + import { execSync } from 'node:child_process'; import { detectProjectCommands } from './diagnostics/projectDetector.js'; import { parseGenericDiagnostics, formatDiagnostics } from './diagnostics/outputParsers.js'; diff --git a/packages/core/src/tools/think.ts b/packages/core/src/tools/think.ts index c27655e4256..5cbdfab5267 100644 --- a/packages/core/src/tools/think.ts +++ b/packages/core/src/tools/think.ts @@ -9,13 +9,15 @@ * make fewer cascading errors. */ +import { + FunctionDeclaration, +} from '../types/delta.js'; import { BaseDeclarativeTool, BaseToolInvocation, Kind, ToolResult, } from './tools.js'; -import { FunctionDeclaration } from '@google/genai'; interface ThinkParams { reasoning: string; diff --git a/packages/core/src/tools/todoWrite.ts b/packages/core/src/tools/todoWrite.ts index 656d4872dc4..4f02b80c26e 100644 --- a/packages/core/src/tools/todoWrite.ts +++ b/packages/core/src/tools/todoWrite.ts @@ -4,13 +4,16 @@ * SPDX-License-Identifier: Apache-2.0 */ +import { + FunctionDeclaration, +} from '../types/delta.js'; import { BaseDeclarativeTool, BaseToolInvocation, Kind, ToolResult, } from './tools.js'; -import { FunctionDeclaration } from '@google/genai'; + import * as fs from 'fs/promises'; import * as fsSync from 'fs'; import * as path from 'path'; @@ -129,7 +132,6 @@ The assistant used the todo list because: - User: I need to implement these features for my e-commerce site: user registration, product catalog, shopping cart, and checkout flow. Assistant: I'll help implement these features. First, let's add all the features to the todo list. diff --git a/packages/core/src/tools/tool-registry.ts b/packages/core/src/tools/tool-registry.ts index 416ee99e4fc..9126865cce9 100644 --- a/packages/core/src/tools/tool-registry.ts +++ b/packages/core/src/tools/tool-registry.ts @@ -4,7 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { FunctionDeclaration } from '@google/genai'; +import { + FunctionDeclaration, +} from '../types/delta.js'; import { AnyDeclarativeTool, Kind, ToolResult, BaseTool } from './tools.js'; import { Config } from '../config/config.js'; import { spawn } from 'node:child_process'; diff --git a/packages/core/src/tools/tools.ts b/packages/core/src/tools/tools.ts index 55df57e8f90..35027f40f30 100644 --- a/packages/core/src/tools/tools.ts +++ b/packages/core/src/tools/tools.ts @@ -4,7 +4,10 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { FunctionDeclaration, PartListUnion } from '@google/genai'; +import { + FunctionDeclaration, + PartListUnion, +} from '../types/delta.js'; import { ToolErrorType } from './tool-error.js'; import { DiffUpdateResult } from '../ide/ideContext.js'; diff --git a/packages/core/src/types/delta.ts b/packages/core/src/types/delta.ts new file mode 100644 index 00000000000..c233269f9ee --- /dev/null +++ b/packages/core/src/types/delta.ts @@ -0,0 +1,93 @@ +/** + * Delta type barrel — the single point of decoupling from @google/genai. + * + * All files in the codebase import from here instead of directly from the + * @google/genai SDK. This means: + * 1. Only this file depends on @google/genai types + * 2. When we replace the underlying types with native Delta definitions, + * only this file changes — everything else keeps working + * 3. Provider-specific files (content generators, adapters) still import + * directly from the SDK for types that are truly provider-specific + * + * Import convention: + * import { Content, Part, FunctionDeclaration } from '../types/delta.js'; + * // NOT from '@google/genai' + */ + +// --------------------------------------------------------------------------- +// Re-exports — same names, new path. Migration is just import path changes. +// --------------------------------------------------------------------------- + +// Message types +export { + Content, + Part, + type PartListUnion, + type PartUnion, +} from '@google/genai'; + +// Request/Response types +export { + GenerateContentResponse, + GenerateContentParameters, + GenerateContentConfig, + type GenerateContentResponseUsageMetadata, +} from '@google/genai'; + +// Token counting +export { + type CountTokensResponse, + type CountTokensParameters, +} from '@google/genai'; + +// Embedding +export { + type EmbedContentResponse, + type EmbedContentParameters, +} from '@google/genai'; + +// Tool/Function types +export { + FunctionDeclaration, + FunctionCall, + type FunctionResponse, + type Tool, + type CallableTool, + type ToolListUnion, +} from '@google/genai'; + +// Schema types +export { + type Schema, + type SchemaUnion, + Type, +} from '@google/genai'; + +// Enums +export { + FinishReason, +} from '@google/genai'; + +// --------------------------------------------------------------------------- +// Native Delta types — for features not in @google/genai +// --------------------------------------------------------------------------- + +/** Provider-agnostic model capability descriptor. */ +export interface DeltaModelCapabilities { + toolCalling: boolean | null; + vision: boolean | null; + streaming: boolean | null; + contextWindow: number | null; + thinkBlocks: boolean | null; +} + +/** Provider identification for schema normalization, diagnostics, etc. */ +export type DeltaProviderType = + | 'google' + | 'openai' + | 'anthropic' + | 'bedrock' + | 'vertex-ai' + | 'openai-compatible' + | 'ollama' + | 'lmstudio'; diff --git a/packages/core/src/utils/editCorrector.ts b/packages/core/src/utils/editCorrector.ts index f247f6d30b4..3a9be6cbb75 100644 --- a/packages/core/src/utils/editCorrector.ts +++ b/packages/core/src/utils/editCorrector.ts @@ -4,7 +4,10 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { Content, GenerateContentConfig } from '@google/genai'; +import { + Content, + GenerateContentConfig, +} from '../types/delta.js'; import { DeltaClient } from '../core/client.js'; import { EditToolParams, EditTool } from '../tools/edit.js'; import { WriteFileTool } from '../tools/write-file.js'; diff --git a/packages/core/src/utils/environmentContext.ts b/packages/core/src/utils/environmentContext.ts index 9cacf924410..d7cfd36acbe 100644 --- a/packages/core/src/utils/environmentContext.ts +++ b/packages/core/src/utils/environmentContext.ts @@ -4,7 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { Part } from '@google/genai'; +import { + Part, +} from '../types/delta.js'; import { Config } from '../config/config.js'; import { getFolderStructure } from './getFolderStructure.js'; diff --git a/packages/core/src/utils/errorReporting.ts b/packages/core/src/utils/errorReporting.ts index 05fc7400ccc..ce1dfc309d0 100644 --- a/packages/core/src/utils/errorReporting.ts +++ b/packages/core/src/utils/errorReporting.ts @@ -4,10 +4,12 @@ * SPDX-License-Identifier: Apache-2.0 */ +import { + Content, +} from '../types/delta.js'; import fs from 'node:fs/promises'; import os from 'node:os'; import path from 'node:path'; -import { Content } from '@google/genai'; interface ErrorReportData { error: { message: string; stack?: string } | { message: string }; diff --git a/packages/core/src/utils/fileUtils.ts b/packages/core/src/utils/fileUtils.ts index 92186e4f8cd..88ce7ee07af 100644 --- a/packages/core/src/utils/fileUtils.ts +++ b/packages/core/src/utils/fileUtils.ts @@ -4,9 +4,12 @@ * SPDX-License-Identifier: Apache-2.0 */ +import { + PartUnion, +} from '../types/delta.js'; import fs from 'node:fs'; import path from 'node:path'; -import { PartUnion } from '@google/genai'; + import mime from 'mime-types'; // Constants for text file processing diff --git a/packages/core/src/utils/generateContentResponseUtilities.ts b/packages/core/src/utils/generateContentResponseUtilities.ts index c5125753a9b..d4150b649ee 100644 --- a/packages/core/src/utils/generateContentResponseUtilities.ts +++ b/packages/core/src/utils/generateContentResponseUtilities.ts @@ -4,8 +4,11 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { GenerateContentResponse, Part, FunctionCall } from '@google/genai'; - +import { + GenerateContentResponse, + Part, + FunctionCall, +} from '../types/delta.js'; export function getResponseText( response: GenerateContentResponse, ): string | undefined { diff --git a/packages/core/src/utils/messageInspectors.ts b/packages/core/src/utils/messageInspectors.ts index 5ef06d7988a..9ac9af562c9 100644 --- a/packages/core/src/utils/messageInspectors.ts +++ b/packages/core/src/utils/messageInspectors.ts @@ -4,8 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { Content } from '@google/genai'; - +import { + Content, +} from '../types/delta.js'; export function isFunctionResponse(content: Content): boolean { return ( content.role === 'user' && diff --git a/packages/core/src/utils/nextSpeakerChecker.ts b/packages/core/src/utils/nextSpeakerChecker.ts index c5170fa021b..12d513dede2 100644 --- a/packages/core/src/utils/nextSpeakerChecker.ts +++ b/packages/core/src/utils/nextSpeakerChecker.ts @@ -4,7 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { Content } from '@google/genai'; +import { + Content, +} from '../types/delta.js'; import { DeltaClient } from '../core/client.js'; import { DeltaChat } from '../core/deltaChat.js'; import { isFunctionResponse } from './messageInspectors.js'; diff --git a/packages/core/src/utils/partUtils.ts b/packages/core/src/utils/partUtils.ts index c6bf098dc88..af8119118c2 100644 --- a/packages/core/src/utils/partUtils.ts +++ b/packages/core/src/utils/partUtils.ts @@ -4,12 +4,15 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { GenerateContentResponse, PartListUnion, Part } from '@google/genai'; - /** * Converts a PartListUnion into a string. * If verbose is true, includes summary representations of non-text parts. */ +import { + GenerateContentResponse, + PartListUnion, + Part, +} from '../types/delta.js'; export function partToString( value: PartListUnion, options?: { verbose?: boolean }, diff --git a/packages/core/src/utils/summarizer.ts b/packages/core/src/utils/summarizer.ts index f188402e9d2..187b954c5b6 100644 --- a/packages/core/src/utils/summarizer.ts +++ b/packages/core/src/utils/summarizer.ts @@ -4,12 +4,13 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { ToolResult } from '../tools/tools.js'; import { Content, GenerateContentConfig, GenerateContentResponse, -} from '@google/genai'; +} from '../types/delta.js'; +import { ToolResult } from '../tools/tools.js'; + import { DeltaClient } from '../core/client.js'; import { DEFAULT_GEMINI_FLASH_LITE_MODEL } from '../config/models.js'; import { getResponseText, partToString } from './partUtils.js';