Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
138 changes: 138 additions & 0 deletions docs/roadmap/05-delta-types.md
Original file line number Diff line number Diff line change
@@ -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<string, unknown> }
| { 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<string, unknown>; // 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<DeltaResponse>;
generateContentStream(request: DeltaGenerateRequest): AsyncGenerator<DeltaResponse>;
countTokens(messages: DeltaMessage[]): Promise<number>;
}
```

### 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
6 changes: 5 additions & 1 deletion packages/cli/src/nonInteractiveCli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@
* SPDX-License-Identifier: Apache-2.0
*/

import {
Content,
Part,
FunctionCall,
} from '../../core/src/types/delta.js';
import {
Config,
ToolCallRequestInfo,
Expand All @@ -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';

Expand Down
5 changes: 4 additions & 1 deletion packages/cli/src/ui/commands/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down
6 changes: 5 additions & 1 deletion packages/cli/src/ui/hooks/atCommandProcessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
5 changes: 4 additions & 1 deletion packages/cli/src/ui/hooks/shellCommandProcessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
* SPDX-License-Identifier: Apache-2.0
*/

import {
PartListUnion,
} from '../../../../core/src/types/delta.js';
import {
HistoryItemWithoutId,
IndividualToolCallDisplay,
Expand All @@ -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';
Expand Down
5 changes: 4 additions & 1 deletion packages/cli/src/ui/hooks/slashCommandProcessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down
6 changes: 5 additions & 1 deletion packages/cli/src/ui/hooks/useDeltaStream.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
7 changes: 6 additions & 1 deletion packages/cli/src/zed-integration/zedIntegration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/core/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
GenerateContentResponse,
FunctionDeclaration,
Schema,
} from '@google/genai';
} from '../types/delta.js';
import {
getDirectoryContextString,
getEnvironmentContext,
Expand Down
6 changes: 5 additions & 1 deletion packages/core/src/core/coreToolScheduler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
* SPDX-License-Identifier: Apache-2.0
*/

import {
Part,
PartListUnion,
} from '../types/delta.js';
import {
ToolCallRequestInfo,
ToolCallResponseInfo,
Expand All @@ -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,
Expand Down
6 changes: 4 additions & 2 deletions packages/core/src/core/deltaChat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down
4 changes: 3 additions & 1 deletion packages/core/src/core/deltaRequest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';

/**
Expand Down
5 changes: 4 additions & 1 deletion packages/core/src/core/logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down
17 changes: 9 additions & 8 deletions packages/core/src/core/subagent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,22 @@
* 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,
FunctionCall,
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';

/**
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/core/turn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
FunctionCall,
FunctionDeclaration,
FinishReason,
} from '@google/genai';
} from '../types/delta.js';
import {
ToolCallConfirmationDetails,
ToolResult,
Expand Down
4 changes: 3 additions & 1 deletion packages/core/src/telemetry/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down
5 changes: 4 additions & 1 deletion packages/core/src/test-utils/tools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,17 @@
* SPDX-License-Identifier: Apache-2.0
*/

import {
Schema,
Type,
} from '../types/delta.js';
import { vi } from 'vitest';
import {
BaseTool,
ToolCallConfirmationDetails,
ToolResult,
Kind,
} from '../tools/tools.js';
import { Schema, Type } from '@google/genai';

/**
* A highly configurable mock tool for testing purposes.
Expand Down
Loading
Loading