feat: Add comprehensive documentation and update README with Bun installation
- Add CLAUDE.md with development guidelines and architecture overview - Add AGENTS.md for Claude Code compatibility with subagent system details - Update README.md and README.zh-CN.md with recommended Bun installation method - Remove bundledDependencies from package.json to fix npm publish hard link issues - Add .npmignore for proper package distribution - Remove obsolete CONTEXT.md and next_todo.md files - Update .gitignore to include AGENTS.md and CLAUDE.md in version control Key documentation improvements: - Complete development workflow commands and build system details - Multi-model architecture explanation with 3-layer design - Agent system with 5-tier priority configuration loading - Tool architecture patterns and service layer documentation - Critical implementation details like async tool descriptions - Development patterns for adding tools, commands, models, and agents Installation improvements: - Bun installation now recommended as fastest method - Fallback to npm for compatibility - Clear step-by-step installation instructions in both languages
This commit is contained in:
parent
7abf61b804
commit
994579fadc
4
.gitignore
vendored
4
.gitignore
vendored
@ -9,7 +9,6 @@ yarn-debug.log*
|
||||
yarn-error.log*
|
||||
lerna-debug.log*
|
||||
.pnpm-debug.log*
|
||||
AGENTS.md
|
||||
|
||||
# Caches
|
||||
|
||||
@ -189,6 +188,3 @@ pnpm-lock.yaml
|
||||
cli.mjs
|
||||
cli.mjs.map
|
||||
source-maps/
|
||||
|
||||
# Claude project instructions
|
||||
CLAUDE.md
|
||||
8
.npmignore
Normal file
8
.npmignore
Normal file
@ -0,0 +1,8 @@
|
||||
node_modules/
|
||||
*.log
|
||||
.DS_Store
|
||||
.git
|
||||
.vscode
|
||||
coverage/
|
||||
build/
|
||||
dist/
|
||||
207
AGENTS.md
Normal file
207
AGENTS.md
Normal file
@ -0,0 +1,207 @@
|
||||
# AGENTS.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Development Commands
|
||||
|
||||
### Essential Development Workflow
|
||||
```bash
|
||||
# Install dependencies
|
||||
bun install
|
||||
|
||||
# Run in development mode (hot reload with verbose output)
|
||||
bun run dev
|
||||
|
||||
# Build the CLI wrapper for distribution
|
||||
bun run build
|
||||
|
||||
# Clean build artifacts
|
||||
bun run clean
|
||||
|
||||
# Run tests
|
||||
bun test
|
||||
|
||||
# Check types
|
||||
bun run typecheck
|
||||
|
||||
# Format code
|
||||
bun run format
|
||||
bun run format:check
|
||||
```
|
||||
|
||||
### Build System Details
|
||||
- **Primary Build Tool**: Bun (required for development)
|
||||
- **Distribution**: Smart CLI wrapper (`cli.js`) that prefers Bun but falls back to Node.js with tsx loader
|
||||
- **Entry Point**: `src/entrypoints/cli.tsx`
|
||||
- **Build Output**: `cli.js` (executable wrapper) and `.npmrc` (npm configuration)
|
||||
|
||||
### Publishing
|
||||
```bash
|
||||
# Publish to npm (requires build first)
|
||||
npm publish
|
||||
# Or with bundled dependency check skip:
|
||||
SKIP_BUNDLED_CHECK=true npm publish
|
||||
```
|
||||
|
||||
## High-Level Architecture
|
||||
|
||||
### Core System Design
|
||||
Kode implements a **three-layer parallel architecture** inspired by Claude Code:
|
||||
|
||||
1. **User Interaction Layer** (`src/screens/REPL.tsx`)
|
||||
- Interactive terminal interface using Ink (React for CLI)
|
||||
- Command parsing and user input handling
|
||||
- Real-time UI updates and syntax highlighting
|
||||
|
||||
2. **Orchestration Layer** (`src/tools/TaskTool/`)
|
||||
- Dynamic agent system for task delegation
|
||||
- Multi-model collaboration and switching
|
||||
- Context management and conversation continuity
|
||||
|
||||
3. **Tool Execution Layer** (`src/tools/`)
|
||||
- Specialized tools for different capabilities (File I/O, Bash, Grep, etc.)
|
||||
- Permission system for secure tool access
|
||||
- MCP (Model Context Protocol) integration
|
||||
|
||||
### Multi-Model Architecture
|
||||
**Key Innovation**: Unlike single-model systems, Kode supports unlimited AI models with intelligent collaboration:
|
||||
|
||||
- **ModelManager** (`src/utils/model.ts`): Unified model configuration and switching
|
||||
- **Model Profiles**: Each model has independent API endpoints, authentication, and capabilities
|
||||
- **Model Pointers**: Default models for different purposes (main, task, reasoning, quick)
|
||||
- **Dynamic Switching**: Runtime model changes without session restart
|
||||
|
||||
### Agent System (`src/utils/agentLoader.ts`)
|
||||
**Dynamic Agent Configuration Loading** with 5-tier priority system:
|
||||
1. Built-in (code-embedded)
|
||||
2. `~/.claude/agents/` (Claude user)
|
||||
3. `~/.kode/agents/` (Kode user)
|
||||
4. `./.claude/agents/` (Claude project)
|
||||
5. `./.kode/agents/` (Kode project)
|
||||
|
||||
Agents are defined as markdown files with YAML frontmatter:
|
||||
```markdown
|
||||
---
|
||||
name: agent-name
|
||||
description: "When to use this agent"
|
||||
tools: ["FileRead", "Bash"] # or "*" for all tools
|
||||
model: model-name # optional
|
||||
---
|
||||
|
||||
System prompt content here...
|
||||
```
|
||||
|
||||
### Tool Architecture
|
||||
Each tool follows a consistent pattern in `src/tools/[ToolName]/`:
|
||||
- `[ToolName].tsx`: Main tool implementation with React UI
|
||||
- `prompt.ts`: Tool-specific system prompts
|
||||
- Tool schema using Zod for validation
|
||||
- Permission-aware execution
|
||||
|
||||
### Service Layer
|
||||
- **Claude Service** (`src/services/claude.ts`): Primary AI model interface
|
||||
- **OpenAI Service** (`src/services/openai.ts`): OpenAI-compatible models
|
||||
- **Model Adapter Factory** (`src/services/modelAdapterFactory.ts`): Unified model interface
|
||||
- **MCP Client** (`src/services/mcpClient.ts`): Model Context Protocol for tool extensions
|
||||
|
||||
### Configuration System (`src/utils/config.ts`)
|
||||
**Hierarchical Configuration** supporting:
|
||||
- Global config (`~/.kode.json`)
|
||||
- Project config (`./.kode.json`)
|
||||
- Environment variables
|
||||
- CLI parameter overrides
|
||||
- Multi-model profile management
|
||||
|
||||
### Context Management
|
||||
- **Message Context Manager** (`src/utils/messageContextManager.ts`): Intelligent context window handling
|
||||
- **Memory Tools** (`src/tools/MemoryReadTool/`, `src/tools/MemoryWriteTool/`): Persistent memory across sessions
|
||||
- **Project Context** (`src/context.ts`): Codebase understanding and file relationships
|
||||
|
||||
### Permission System (`src/permissions.ts`)
|
||||
**Security-First Tool Access**:
|
||||
- Granular permission requests for each tool use
|
||||
- User approval required for file modifications and command execution
|
||||
- Tool capability filtering based on agent configuration
|
||||
- Secure file path validation and sandboxing
|
||||
|
||||
## Important Implementation Details
|
||||
|
||||
### Async Tool Descriptions
|
||||
**Critical**: Tool descriptions are async functions that must be awaited:
|
||||
```typescript
|
||||
// INCORRECT
|
||||
const description = tool.description
|
||||
|
||||
// CORRECT
|
||||
const description = typeof tool.description === 'function'
|
||||
? await tool.description()
|
||||
: tool.description
|
||||
```
|
||||
|
||||
### Agent Loading Performance
|
||||
- **Memoization**: LRU cache to avoid repeated file I/O
|
||||
- **Hot Reload**: File system watchers for real-time agent updates
|
||||
- **Parallel Loading**: All agent directories scanned concurrently
|
||||
|
||||
### UI Framework Integration
|
||||
- **Ink**: React-based terminal UI framework
|
||||
- **Component Structure**: Follows React patterns with hooks and context
|
||||
- **Terminal Handling**: Custom input handling for complex interactions
|
||||
|
||||
### Error Handling Strategy
|
||||
- **Graceful Degradation**: System continues with built-in agents if loading fails
|
||||
- **User-Friendly Errors**: Clear error messages with suggested fixes
|
||||
- **Debug Logging**: Comprehensive logging system (`src/utils/debugLogger.ts`)
|
||||
|
||||
### TypeScript Integration
|
||||
- **Strict Types**: Full TypeScript coverage with strict mode
|
||||
- **Zod Schemas**: Runtime validation for all external data
|
||||
- **Tool Typing**: Consistent `Tool` interface for all tools
|
||||
|
||||
## Key Files for Understanding the System
|
||||
|
||||
### Core Entry Points
|
||||
- `src/entrypoints/cli.tsx`: Main CLI application entry
|
||||
- `src/screens/REPL.tsx`: Interactive terminal interface
|
||||
|
||||
### Tool System
|
||||
- `src/tools.ts`: Tool registry and exports
|
||||
- `src/Tool.ts`: Base tool interface definition
|
||||
- `src/tools/TaskTool/TaskTool.tsx`: Agent orchestration tool
|
||||
|
||||
### Configuration & Model Management
|
||||
- `src/utils/config.ts`: Configuration management
|
||||
- `src/utils/model.ts`: Model manager and switching logic
|
||||
- `src/utils/agentLoader.ts`: Dynamic agent configuration loading
|
||||
|
||||
### Services & Integrations
|
||||
- `src/services/claude.ts`: Main AI service integration
|
||||
- `src/services/mcpClient.ts`: MCP tool integration
|
||||
- `src/utils/messageContextManager.ts`: Context window management
|
||||
|
||||
## Development Patterns
|
||||
|
||||
### Adding New Tools
|
||||
1. Create directory in `src/tools/[ToolName]/`
|
||||
2. Implement `[ToolName].tsx` following existing patterns
|
||||
3. Add `prompt.ts` for tool-specific prompts
|
||||
4. Register in `src/tools.ts`
|
||||
5. Update tool permissions in agent configurations
|
||||
|
||||
### Adding New Commands
|
||||
1. Create command file in `src/commands/[command].tsx`
|
||||
2. Implement command logic with Ink UI components
|
||||
3. Register in `src/commands.ts`
|
||||
4. Add command to help system
|
||||
|
||||
### Model Integration
|
||||
1. Add model profile to `src/constants/models.ts`
|
||||
2. Implement adapter if needed in `src/services/adapters/`
|
||||
3. Update model capabilities in `src/constants/modelCapabilities.ts`
|
||||
4. Test with existing tool suite
|
||||
|
||||
### Agent Development
|
||||
1. Create `.md` file with proper YAML frontmatter
|
||||
2. Place in appropriate directory based on scope
|
||||
3. Test with `/agents` command
|
||||
4. Verify tool permissions work correctly
|
||||
207
CLAUDE.md
Normal file
207
CLAUDE.md
Normal file
@ -0,0 +1,207 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Development Commands
|
||||
|
||||
### Essential Development Workflow
|
||||
```bash
|
||||
# Install dependencies
|
||||
bun install
|
||||
|
||||
# Run in development mode (hot reload with verbose output)
|
||||
bun run dev
|
||||
|
||||
# Build the CLI wrapper for distribution
|
||||
bun run build
|
||||
|
||||
# Clean build artifacts
|
||||
bun run clean
|
||||
|
||||
# Run tests
|
||||
bun test
|
||||
|
||||
# Check types
|
||||
bun run typecheck
|
||||
|
||||
# Format code
|
||||
bun run format
|
||||
bun run format:check
|
||||
```
|
||||
|
||||
### Build System Details
|
||||
- **Primary Build Tool**: Bun (required for development)
|
||||
- **Distribution**: Smart CLI wrapper (`cli.js`) that prefers Bun but falls back to Node.js with tsx loader
|
||||
- **Entry Point**: `src/entrypoints/cli.tsx`
|
||||
- **Build Output**: `cli.js` (executable wrapper) and `.npmrc` (npm configuration)
|
||||
|
||||
### Publishing
|
||||
```bash
|
||||
# Publish to npm (requires build first)
|
||||
npm publish
|
||||
# Or with bundled dependency check skip:
|
||||
SKIP_BUNDLED_CHECK=true npm publish
|
||||
```
|
||||
|
||||
## High-Level Architecture
|
||||
|
||||
### Core System Design
|
||||
Kode implements a **three-layer parallel architecture** inspired by Claude Code:
|
||||
|
||||
1. **User Interaction Layer** (`src/screens/REPL.tsx`)
|
||||
- Interactive terminal interface using Ink (React for CLI)
|
||||
- Command parsing and user input handling
|
||||
- Real-time UI updates and syntax highlighting
|
||||
|
||||
2. **Orchestration Layer** (`src/tools/TaskTool/`)
|
||||
- Dynamic agent system for task delegation
|
||||
- Multi-model collaboration and switching
|
||||
- Context management and conversation continuity
|
||||
|
||||
3. **Tool Execution Layer** (`src/tools/`)
|
||||
- Specialized tools for different capabilities (File I/O, Bash, Grep, etc.)
|
||||
- Permission system for secure tool access
|
||||
- MCP (Model Context Protocol) integration
|
||||
|
||||
### Multi-Model Architecture
|
||||
**Key Innovation**: Unlike single-model systems, Kode supports unlimited AI models with intelligent collaboration:
|
||||
|
||||
- **ModelManager** (`src/utils/model.ts`): Unified model configuration and switching
|
||||
- **Model Profiles**: Each model has independent API endpoints, authentication, and capabilities
|
||||
- **Model Pointers**: Default models for different purposes (main, task, reasoning, quick)
|
||||
- **Dynamic Switching**: Runtime model changes without session restart
|
||||
|
||||
### Agent System (`src/utils/agentLoader.ts`)
|
||||
**Dynamic Agent Configuration Loading** with 5-tier priority system:
|
||||
1. Built-in (code-embedded)
|
||||
2. `~/.claude/agents/` (Claude user)
|
||||
3. `~/.kode/agents/` (Kode user)
|
||||
4. `./.claude/agents/` (Claude project)
|
||||
5. `./.kode/agents/` (Kode project)
|
||||
|
||||
Agents are defined as markdown files with YAML frontmatter:
|
||||
```markdown
|
||||
---
|
||||
name: agent-name
|
||||
description: "When to use this agent"
|
||||
tools: ["FileRead", "Bash"] # or "*" for all tools
|
||||
model: model-name # optional
|
||||
---
|
||||
|
||||
System prompt content here...
|
||||
```
|
||||
|
||||
### Tool Architecture
|
||||
Each tool follows a consistent pattern in `src/tools/[ToolName]/`:
|
||||
- `[ToolName].tsx`: Main tool implementation with React UI
|
||||
- `prompt.ts`: Tool-specific system prompts
|
||||
- Tool schema using Zod for validation
|
||||
- Permission-aware execution
|
||||
|
||||
### Service Layer
|
||||
- **Claude Service** (`src/services/claude.ts`): Primary AI model interface
|
||||
- **OpenAI Service** (`src/services/openai.ts`): OpenAI-compatible models
|
||||
- **Model Adapter Factory** (`src/services/modelAdapterFactory.ts`): Unified model interface
|
||||
- **MCP Client** (`src/services/mcpClient.ts`): Model Context Protocol for tool extensions
|
||||
|
||||
### Configuration System (`src/utils/config.ts`)
|
||||
**Hierarchical Configuration** supporting:
|
||||
- Global config (`~/.kode.json`)
|
||||
- Project config (`./.kode.json`)
|
||||
- Environment variables
|
||||
- CLI parameter overrides
|
||||
- Multi-model profile management
|
||||
|
||||
### Context Management
|
||||
- **Message Context Manager** (`src/utils/messageContextManager.ts`): Intelligent context window handling
|
||||
- **Memory Tools** (`src/tools/MemoryReadTool/`, `src/tools/MemoryWriteTool/`): Persistent memory across sessions
|
||||
- **Project Context** (`src/context.ts`): Codebase understanding and file relationships
|
||||
|
||||
### Permission System (`src/permissions.ts`)
|
||||
**Security-First Tool Access**:
|
||||
- Granular permission requests for each tool use
|
||||
- User approval required for file modifications and command execution
|
||||
- Tool capability filtering based on agent configuration
|
||||
- Secure file path validation and sandboxing
|
||||
|
||||
## Important Implementation Details
|
||||
|
||||
### Async Tool Descriptions
|
||||
**Critical**: Tool descriptions are async functions that must be awaited:
|
||||
```typescript
|
||||
// INCORRECT
|
||||
const description = tool.description
|
||||
|
||||
// CORRECT
|
||||
const description = typeof tool.description === 'function'
|
||||
? await tool.description()
|
||||
: tool.description
|
||||
```
|
||||
|
||||
### Agent Loading Performance
|
||||
- **Memoization**: LRU cache to avoid repeated file I/O
|
||||
- **Hot Reload**: File system watchers for real-time agent updates
|
||||
- **Parallel Loading**: All agent directories scanned concurrently
|
||||
|
||||
### UI Framework Integration
|
||||
- **Ink**: React-based terminal UI framework
|
||||
- **Component Structure**: Follows React patterns with hooks and context
|
||||
- **Terminal Handling**: Custom input handling for complex interactions
|
||||
|
||||
### Error Handling Strategy
|
||||
- **Graceful Degradation**: System continues with built-in agents if loading fails
|
||||
- **User-Friendly Errors**: Clear error messages with suggested fixes
|
||||
- **Debug Logging**: Comprehensive logging system (`src/utils/debugLogger.ts`)
|
||||
|
||||
### TypeScript Integration
|
||||
- **Strict Types**: Full TypeScript coverage with strict mode
|
||||
- **Zod Schemas**: Runtime validation for all external data
|
||||
- **Tool Typing**: Consistent `Tool` interface for all tools
|
||||
|
||||
## Key Files for Understanding the System
|
||||
|
||||
### Core Entry Points
|
||||
- `src/entrypoints/cli.tsx`: Main CLI application entry
|
||||
- `src/screens/REPL.tsx`: Interactive terminal interface
|
||||
|
||||
### Tool System
|
||||
- `src/tools.ts`: Tool registry and exports
|
||||
- `src/Tool.ts`: Base tool interface definition
|
||||
- `src/tools/TaskTool/TaskTool.tsx`: Agent orchestration tool
|
||||
|
||||
### Configuration & Model Management
|
||||
- `src/utils/config.ts`: Configuration management
|
||||
- `src/utils/model.ts`: Model manager and switching logic
|
||||
- `src/utils/agentLoader.ts`: Dynamic agent configuration loading
|
||||
|
||||
### Services & Integrations
|
||||
- `src/services/claude.ts`: Main AI service integration
|
||||
- `src/services/mcpClient.ts`: MCP tool integration
|
||||
- `src/utils/messageContextManager.ts`: Context window management
|
||||
|
||||
## Development Patterns
|
||||
|
||||
### Adding New Tools
|
||||
1. Create directory in `src/tools/[ToolName]/`
|
||||
2. Implement `[ToolName].tsx` following existing patterns
|
||||
3. Add `prompt.ts` for tool-specific prompts
|
||||
4. Register in `src/tools.ts`
|
||||
5. Update tool permissions in agent configurations
|
||||
|
||||
### Adding New Commands
|
||||
1. Create command file in `src/commands/[command].tsx`
|
||||
2. Implement command logic with Ink UI components
|
||||
3. Register in `src/commands.ts`
|
||||
4. Add command to help system
|
||||
|
||||
### Model Integration
|
||||
1. Add model profile to `src/constants/models.ts`
|
||||
2. Implement adapter if needed in `src/services/adapters/`
|
||||
3. Update model capabilities in `src/constants/modelCapabilities.ts`
|
||||
4. Test with existing tool suite
|
||||
|
||||
### Agent Development
|
||||
1. Create `.md` file with proper YAML frontmatter
|
||||
2. Place in appropriate directory based on scope
|
||||
3. Test with `/agents` command
|
||||
4. Verify tool permissions work correctly
|
||||
316
CONTEXT.md
316
CONTEXT.md
@ -1,316 +0,0 @@
|
||||
# Kode Subagent Implementation - Project Context
|
||||
|
||||
## Project Overview
|
||||
|
||||
### Mission
|
||||
Implement a complete subagent system for Kode that achieves **100% alignment** with Claude Code's Task tool functionality, enabling dynamic agent configuration loading from markdown files with YAML frontmatter.
|
||||
|
||||
### Core Architecture
|
||||
Based on Claude Code's three-layer parallel architecture:
|
||||
1. **User Interaction Layer** - REPL interface and commands
|
||||
2. **Task Tool Layer** - Dynamic agent orchestration
|
||||
3. **Tool Layer** - Individual tools (FileRead, Bash, etc.)
|
||||
|
||||
## Implementation Summary
|
||||
|
||||
### Key Components Implemented
|
||||
|
||||
#### 1. Dynamic Agent Loader (`src/utils/agentLoader.ts`)
|
||||
- **Purpose**: Load agent configurations from markdown files with YAML frontmatter
|
||||
- **Five-tier Priority System**: Built-in < ~/.claude < ~/.kode < ./.claude < ./.kode
|
||||
- **Features**:
|
||||
- Memoized loading for performance
|
||||
- Hot reload with file system watching
|
||||
- Tool permission filtering
|
||||
- Model override capabilities
|
||||
|
||||
#### 2. TaskTool Integration (`src/tools/TaskTool/TaskTool.tsx`)
|
||||
- **Purpose**: Modified TaskTool to use dynamic agent configurations
|
||||
- **Key Changes**:
|
||||
- Removed hardcoded `SUBAGENT_CONFIGS`
|
||||
- Added dynamic `subagent_type` parameter validation
|
||||
- Integrated with agent loader for real-time agent discovery
|
||||
- Support for async tool description generation
|
||||
|
||||
#### 3. Agent Management UI (`src/commands/agents.tsx`)
|
||||
- **Purpose**: Interactive `/agents` command for agent CRUD operations
|
||||
- **Features**:
|
||||
- List all available agents with location indicators
|
||||
- Create new agents with step-by-step wizard
|
||||
- View agent details and system prompts
|
||||
- Delete custom agents (preserves built-ins)
|
||||
- Support for saving to all 4 directory locations
|
||||
|
||||
#### 4. Claude Service Fix (`src/services/claude.ts`)
|
||||
- **Critical Fix**: Modified tool description processing to support async functions
|
||||
- **Problem**: `tool.description` was used directly instead of `await tool.description()`
|
||||
- **Solution**: Added async handling with function type checking
|
||||
|
||||
### Agent Configuration Format
|
||||
|
||||
```markdown
|
||||
---
|
||||
name: agent-name
|
||||
description: "When to use this agent description"
|
||||
tools: ["ToolName1", "ToolName2"] # or "*" for all tools
|
||||
model: model-name # optional
|
||||
---
|
||||
|
||||
System prompt content here...
|
||||
Multi-line prompts supported.
|
||||
```
|
||||
|
||||
### Directory Structure & Priority
|
||||
|
||||
```
|
||||
Priority Order (later overrides earlier):
|
||||
1. Built-in (code-embedded)
|
||||
2. ~/.claude/agents/ (Claude user)
|
||||
3. ~/.kode/agents/ (Kode user)
|
||||
4. ./.claude/agents/ (Claude project)
|
||||
5. ./.kode/agents/ (Kode project)
|
||||
```
|
||||
|
||||
### Available Built-in Agents
|
||||
|
||||
```typescript
|
||||
// User-level agents (in ~/.kode/agents/)
|
||||
- general-purpose: Multi-step tasks, research, complex questions
|
||||
- search-specialist: File/code pattern finding (tools: Grep, Glob, FileRead, LS)
|
||||
- code-writer: Implementation, debugging (tools: FileRead, FileWrite, FileEdit, MultiEdit, Bash)
|
||||
- reviewer: Code quality analysis (tools: FileRead, Grep, Glob)
|
||||
- architect: System design decisions (tools: FileRead, FileWrite, Grep, Glob)
|
||||
|
||||
// Project-level agents (in ./.kode/agents/)
|
||||
- test-writer: Test suite creation (tools: FileRead, FileWrite, FileEdit, Bash, Grep)
|
||||
- docs-writer: Technical documentation (tools: FileRead, FileWrite, FileEdit, Grep, Glob)
|
||||
```
|
||||
|
||||
## Critical Technical Details
|
||||
|
||||
### 1. Async Description Pattern
|
||||
```typescript
|
||||
// WRONG (old pattern)
|
||||
const toolSchemas = tools.map(tool => ({
|
||||
description: tool.description, // Function reference
|
||||
}))
|
||||
|
||||
// CORRECT (fixed pattern)
|
||||
const toolSchemas = await Promise.all(
|
||||
tools.map(async tool => ({
|
||||
description: typeof tool.description === 'function'
|
||||
? await tool.description()
|
||||
: tool.description,
|
||||
}))
|
||||
)
|
||||
```
|
||||
|
||||
### 2. Agent Loading Flow
|
||||
```typescript
|
||||
1. scanAgentDirectory() -> Parse .md files with gray-matter
|
||||
2. loadAllAgents() -> Parallel scanning of all 4 directories
|
||||
3. Priority override -> Map-based deduplication by agentType
|
||||
4. Memoization -> LRU cache for performance
|
||||
5. Hot reload -> FSWatcher on all directories
|
||||
```
|
||||
|
||||
### 3. Tool Permission Filtering
|
||||
```typescript
|
||||
// In TaskTool.tsx
|
||||
if (toolFilter && toolFilter !== '*') {
|
||||
if (Array.isArray(toolFilter)) {
|
||||
tools = tools.filter(tool => toolFilter.includes(tool.name))
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4. Model Override Logic
|
||||
```typescript
|
||||
// Priority: CLI model param > agent config > default
|
||||
let effectiveModel = model || 'task' // CLI param
|
||||
if (!model && agentConfig.model) {
|
||||
effectiveModel = agentConfig.model // Agent config
|
||||
}
|
||||
```
|
||||
|
||||
## Standard Operating Procedures
|
||||
|
||||
### SOP 1: Adding New Built-in Agent
|
||||
1. Create `.md` file in appropriate directory
|
||||
2. Use proper YAML frontmatter format
|
||||
3. Test with `getActiveAgents()` function
|
||||
4. Verify priority system works correctly
|
||||
5. Update documentation if needed
|
||||
|
||||
### SOP 2: Debugging Agent Loading Issues
|
||||
```bash
|
||||
# 1. Test agent loader directly
|
||||
bun -e "import {getActiveAgents} from './src/utils/agentLoader'; console.log(await getActiveAgents())"
|
||||
|
||||
# 2. Clear cache and reload
|
||||
bun -e "import {clearAgentCache} from './src/utils/agentLoader'; clearAgentCache()"
|
||||
|
||||
# 3. Check TaskTool description generation
|
||||
bun -e "import {TaskTool} from './src/tools/TaskTool/TaskTool'; console.log(await TaskTool.description())"
|
||||
|
||||
# 4. Verify directory structure
|
||||
ls -la ~/.claude/agents/ ~/.kode/agents/ ./.claude/agents/ ./.kode/agents/
|
||||
```
|
||||
|
||||
### SOP 3: Testing Subagent System
|
||||
```typescript
|
||||
// Comprehensive test pattern
|
||||
async function testSubagentSystem() {
|
||||
// 1. Clear cache
|
||||
clearAgentCache()
|
||||
|
||||
// 2. Load agents
|
||||
const agents = await getActiveAgents()
|
||||
|
||||
// 3. Verify count and types
|
||||
const types = await getAvailableAgentTypes()
|
||||
|
||||
// 4. Test TaskTool integration
|
||||
const description = await TaskTool.description()
|
||||
|
||||
// 5. Verify priority system
|
||||
const duplicates = findDuplicateAgentTypes(agents)
|
||||
|
||||
return { agents, types, description, duplicates }
|
||||
}
|
||||
```
|
||||
|
||||
### SOP 4: Agent Management Best Practices
|
||||
1. **Agent Naming**: Use kebab-case (`search-specialist`, not `SearchSpecialist`)
|
||||
2. **Tool Selection**: Be specific about tool permissions for security
|
||||
3. **Model Selection**: Only specify if different from default
|
||||
4. **Description**: Clear, concise "when to use" guidance
|
||||
5. **System Prompt**: Focus on capabilities and constraints
|
||||
|
||||
## Key Learnings & Insights
|
||||
|
||||
### 1. Claude Code Alignment Requirements
|
||||
- **100% format compatibility**: YAML frontmatter + markdown body
|
||||
- **Directory structure**: Support both `.claude` and `.kode` directories
|
||||
- **Priority system**: Complex 5-tier hierarchy with proper override logic
|
||||
- **Hot reload**: Real-time configuration updates without restart
|
||||
- **Tool permissions**: Security through capability restriction
|
||||
|
||||
### 2. Performance Considerations
|
||||
- **Memoization**: Critical for avoiding repeated file I/O
|
||||
- **Parallel loading**: All directories scanned concurrently
|
||||
- **Caching strategy**: LRU cache with manual invalidation
|
||||
- **File watching**: Efficient hot reload with minimal overhead
|
||||
|
||||
### 3. Error Handling Patterns
|
||||
```typescript
|
||||
// Graceful degradation pattern
|
||||
try {
|
||||
const agents = await loadAllAgents()
|
||||
return { activeAgents: agents.activeAgents, allAgents: agents.allAgents }
|
||||
} catch (error) {
|
||||
console.error('Failed to load agents, falling back to built-in:', error)
|
||||
return {
|
||||
activeAgents: [BUILTIN_GENERAL_PURPOSE],
|
||||
allAgents: [BUILTIN_GENERAL_PURPOSE]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4. TypeScript Integration Points
|
||||
```typescript
|
||||
export interface AgentConfig {
|
||||
agentType: string // Matches subagent_type parameter
|
||||
whenToUse: string // User-facing description
|
||||
tools: string[] | '*' // Tool permission filtering
|
||||
systemPrompt: string // Injected into task prompt
|
||||
location: 'built-in' | 'user' | 'project'
|
||||
color?: string // Optional UI theming
|
||||
model?: string // Optional model override
|
||||
}
|
||||
```
|
||||
|
||||
## Common Issues & Solutions
|
||||
|
||||
### Issue 1: "Agent type 'X' not found"
|
||||
**Cause**: Agent not loaded or wrong agentType in frontmatter
|
||||
**Solution**:
|
||||
1. Check file exists in expected directory
|
||||
2. Verify `name:` field in YAML frontmatter
|
||||
3. Clear cache with `clearAgentCache()`
|
||||
4. Check file permissions
|
||||
|
||||
### Issue 2: Tool description not showing subagent types
|
||||
**Cause**: Async description function not being awaited
|
||||
**Solution**: Ensure Claude service uses `await tool.description()` pattern
|
||||
|
||||
### Issue 3: Priority system not working
|
||||
**Cause**: Map iteration order or incorrect directory scanning
|
||||
**Solution**: Verify loading order matches priority specification
|
||||
|
||||
### Issue 4: Hot reload not triggering
|
||||
**Cause**: File watcher not set up or wrong directory
|
||||
**Solution**: Check `startAgentWatcher()` covers all 4 directories
|
||||
|
||||
## Future Enhancement Opportunities
|
||||
|
||||
### 1. Advanced Agent Features
|
||||
- **Agent inheritance**: Base agents with specialized variants
|
||||
- **Conditional logic**: Dynamic tool selection based on context
|
||||
- **Agent composition**: Chaining agents for complex workflows
|
||||
- **Performance metrics**: Track agent usage and effectiveness
|
||||
|
||||
### 2. UI/UX Improvements
|
||||
- **Visual agent editor**: Rich text editing for system prompts
|
||||
- **Agent marketplace**: Share and discover community agents
|
||||
- **Configuration validation**: Real-time feedback on agent configs
|
||||
- **Usage analytics**: Show which agents are most effective
|
||||
|
||||
### 3. Integration Enhancements
|
||||
- **IDE integration**: VS Code extension for agent management
|
||||
- **API endpoints**: REST API for external agent management
|
||||
- **Version control**: Git integration for agent configuration history
|
||||
- **Cloud sync**: Cross-device agent synchronization
|
||||
|
||||
## Testing & Validation
|
||||
|
||||
### Test Coverage Areas
|
||||
1. **Agent Loading**: All directory combinations and priority scenarios
|
||||
2. **Tool Filtering**: Security boundary enforcement
|
||||
3. **Model Override**: CLI param vs agent config vs default
|
||||
4. **Hot Reload**: File change detection and cache invalidation
|
||||
5. **Error Handling**: Graceful degradation and recovery
|
||||
6. **TaskTool Integration**: Dynamic description generation
|
||||
7. **UI Components**: Agent management command workflows
|
||||
|
||||
### Validation Checklist
|
||||
- [ ] All 5 priority levels load correctly
|
||||
- [ ] Duplicate agent names resolve to highest priority
|
||||
- [ ] Tool permissions filter correctly
|
||||
- [ ] Model overrides work in correct precedence
|
||||
- [ ] Hot reload detects changes in all directories
|
||||
- [ ] TaskTool description includes all available agents
|
||||
- [ ] `/agents` command CRUD operations work
|
||||
- [ ] Error states handled gracefully
|
||||
- [ ] TypeScript types are correct and complete
|
||||
- [ ] Documentation is accurate and comprehensive
|
||||
|
||||
## Project Metrics & Success Criteria
|
||||
|
||||
### Quantitative Metrics
|
||||
- **Agent Load Performance**: < 100ms for typical configurations
|
||||
- **Hot Reload Latency**: < 500ms from file change to cache update
|
||||
- **Memory Usage**: < 50MB additional overhead for agent system
|
||||
- **Test Coverage**: > 90% for core agent functionality
|
||||
- **TypeScript Compliance**: 0 type errors in agent-related code
|
||||
|
||||
### Qualitative Success Criteria
|
||||
- **100% Claude Code compatibility**: All agent formats work identically
|
||||
- **Seamless user experience**: No learning curve for existing Claude Code users
|
||||
- **Robust error handling**: System degrades gracefully under all failure modes
|
||||
- **Maintainable architecture**: Code is clean, documented, and extensible
|
||||
- **Performance excellence**: No noticeable impact on Kode startup or operation
|
||||
|
||||
---
|
||||
|
||||
*This document serves as the single source of truth for the Kode subagent implementation project. All team members should refer to this context when working on agent-related features or debugging issues.*
|
||||
14
README.md
14
README.md
@ -64,6 +64,20 @@ Our state-of-the-art completion system provides unparalleled coding assistance:
|
||||
|
||||
## Installation
|
||||
|
||||
### Recommended: Using Bun (Fastest)
|
||||
|
||||
First install Bun if you haven't already:
|
||||
```bash
|
||||
curl -fsSL https://bun.sh/install | bash
|
||||
```
|
||||
|
||||
Then install Kode:
|
||||
```bash
|
||||
bun add -g @shareai-lab/kode
|
||||
```
|
||||
|
||||
### Alternative: Using npm
|
||||
|
||||
```bash
|
||||
npm install -g @shareai-lab/kode
|
||||
```
|
||||
|
||||
@ -21,6 +21,20 @@ Kode 是一个强大的 AI 助手,运行在你的终端中。它能理解你
|
||||
|
||||
## 安装
|
||||
|
||||
### 推荐方式:使用 Bun(最快)
|
||||
|
||||
首先安装 Bun(如果尚未安装):
|
||||
```bash
|
||||
curl -fsSL https://bun.sh/install | bash
|
||||
```
|
||||
|
||||
然后安装 Kode:
|
||||
```bash
|
||||
bun add -g @shareai-lab/kode
|
||||
```
|
||||
|
||||
### 备选方式:使用 npm
|
||||
|
||||
```bash
|
||||
npm install -g @shareai-lab/kode
|
||||
```
|
||||
|
||||
893
next_todo.md
893
next_todo.md
@ -1,893 +0,0 @@
|
||||
# Kode系统 Responses API 支持重构施工文档
|
||||
|
||||
## 📋 项目概述
|
||||
|
||||
### 目标
|
||||
将Kode系统从硬编码的GPT-5检测升级为基于能力声明的模型系统,支持所有Responses API类模型(GPT-5、GPT-6、GLM-5等)。
|
||||
|
||||
### 核心原则
|
||||
1. **零破坏性**: 100%保留现有功能
|
||||
2. **渐进式**: 可随时回滚
|
||||
3. **可扩展**: 新模型只需配置
|
||||
4. **优雅性**: 消除硬编码,统一处理流程
|
||||
|
||||
## 🏗️ 系统架构概览
|
||||
|
||||
### 当前架构(问题)
|
||||
```
|
||||
用户输入 → REPL → query.ts → queryLLM
|
||||
↓
|
||||
[硬编码检测]
|
||||
if (isGPT5Model()) {...}
|
||||
if (isGPT4Model()) {...}
|
||||
↓
|
||||
不同的API调用路径
|
||||
```
|
||||
|
||||
### 目标架构(解决方案)
|
||||
```
|
||||
用户输入 → REPL → query.ts → queryLLM
|
||||
↓
|
||||
[能力声明系统]
|
||||
ModelCapabilities查询
|
||||
↓
|
||||
[统一适配器]
|
||||
ResponsesAPIAdapter / ChatCompletionsAdapter
|
||||
↓
|
||||
统一的API调用
|
||||
```
|
||||
|
||||
## 📁 文件结构规划
|
||||
|
||||
```
|
||||
src/
|
||||
├── types/
|
||||
│ └── modelCapabilities.ts # 新建:能力类型定义
|
||||
├── constants/
|
||||
│ └── modelCapabilities.ts # 新建:模型能力注册表
|
||||
├── services/
|
||||
│ ├── adapters/ # 新建目录:适配器
|
||||
│ │ ├── base.ts # 新建:基础适配器类
|
||||
│ │ ├── responsesAPI.ts # 新建:Responses API适配器
|
||||
│ │ └── chatCompletions.ts # 新建:Chat Completions适配器
|
||||
│ ├── modelAdapterFactory.ts # 新建:适配器工厂
|
||||
│ ├── claude.ts # 修改:使用新系统
|
||||
│ └── openai.ts # 修改:清理硬编码
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Phase 1: 基础设施建设(第1-2天)
|
||||
|
||||
### 目标
|
||||
创建能力声明系统的基础架构,不影响现有代码运行。
|
||||
|
||||
### Step 1.1: 创建模型能力类型定义
|
||||
|
||||
**文件**: `src/types/modelCapabilities.ts` (新建)
|
||||
|
||||
**任务**: 定义模型能力接口
|
||||
|
||||
```typescript
|
||||
// 完整代码 - 直接复制粘贴
|
||||
export interface ModelCapabilities {
|
||||
// API架构类型
|
||||
apiArchitecture: {
|
||||
primary: 'chat_completions' | 'responses_api'
|
||||
fallback?: 'chat_completions' // Responses API模型可降级
|
||||
}
|
||||
|
||||
// 参数映射
|
||||
parameters: {
|
||||
maxTokensField: 'max_tokens' | 'max_completion_tokens'
|
||||
supportsReasoningEffort: boolean
|
||||
supportsVerbosity: boolean
|
||||
temperatureMode: 'flexible' | 'fixed_one' | 'restricted'
|
||||
}
|
||||
|
||||
// 工具调用能力
|
||||
toolCalling: {
|
||||
mode: 'none' | 'function_calling' | 'custom_tools'
|
||||
supportsFreeform: boolean
|
||||
supportsAllowedTools: boolean
|
||||
supportsParallelCalls: boolean
|
||||
}
|
||||
|
||||
// 状态管理
|
||||
stateManagement: {
|
||||
supportsResponseId: boolean
|
||||
supportsConversationChaining: boolean
|
||||
supportsPreviousResponseId: boolean
|
||||
}
|
||||
|
||||
// 流式支持
|
||||
streaming: {
|
||||
supported: boolean
|
||||
includesUsage: boolean
|
||||
}
|
||||
}
|
||||
|
||||
// 统一的请求参数
|
||||
export interface UnifiedRequestParams {
|
||||
messages: any[]
|
||||
systemPrompt: string[]
|
||||
tools?: any[]
|
||||
maxTokens: number
|
||||
stream?: boolean
|
||||
previousResponseId?: string
|
||||
reasoningEffort?: 'minimal' | 'low' | 'medium' | 'high'
|
||||
verbosity?: 'low' | 'medium' | 'high'
|
||||
temperature?: number
|
||||
}
|
||||
|
||||
// 统一的响应格式
|
||||
export interface UnifiedResponse {
|
||||
id: string
|
||||
content: string
|
||||
toolCalls?: any[]
|
||||
usage: {
|
||||
promptTokens: number
|
||||
completionTokens: number
|
||||
reasoningTokens?: number
|
||||
}
|
||||
responseId?: string // 用于Responses API状态管理
|
||||
}
|
||||
```
|
||||
|
||||
### Step 1.2: 创建模型能力注册表
|
||||
|
||||
**文件**: `src/constants/modelCapabilities.ts` (新建)
|
||||
|
||||
**任务**: 为所有模型定义能力
|
||||
|
||||
```typescript
|
||||
import { ModelCapabilities } from '../types/modelCapabilities'
|
||||
|
||||
// GPT-5的标准能力定义
|
||||
const GPT5_CAPABILITIES: ModelCapabilities = {
|
||||
apiArchitecture: {
|
||||
primary: 'responses_api',
|
||||
fallback: 'chat_completions'
|
||||
},
|
||||
parameters: {
|
||||
maxTokensField: 'max_completion_tokens',
|
||||
supportsReasoningEffort: true,
|
||||
supportsVerbosity: true,
|
||||
temperatureMode: 'fixed_one'
|
||||
},
|
||||
toolCalling: {
|
||||
mode: 'custom_tools',
|
||||
supportsFreeform: true,
|
||||
supportsAllowedTools: true,
|
||||
supportsParallelCalls: true
|
||||
},
|
||||
stateManagement: {
|
||||
supportsResponseId: true,
|
||||
supportsConversationChaining: true,
|
||||
supportsPreviousResponseId: true
|
||||
},
|
||||
streaming: {
|
||||
supported: false, // Responses API暂不支持流式
|
||||
includesUsage: true
|
||||
}
|
||||
}
|
||||
|
||||
// Chat Completions的标准能力定义
|
||||
const CHAT_COMPLETIONS_CAPABILITIES: ModelCapabilities = {
|
||||
apiArchitecture: {
|
||||
primary: 'chat_completions'
|
||||
},
|
||||
parameters: {
|
||||
maxTokensField: 'max_tokens',
|
||||
supportsReasoningEffort: false,
|
||||
supportsVerbosity: false,
|
||||
temperatureMode: 'flexible'
|
||||
},
|
||||
toolCalling: {
|
||||
mode: 'function_calling',
|
||||
supportsFreeform: false,
|
||||
supportsAllowedTools: false,
|
||||
supportsParallelCalls: true
|
||||
},
|
||||
stateManagement: {
|
||||
supportsResponseId: false,
|
||||
supportsConversationChaining: false,
|
||||
supportsPreviousResponseId: false
|
||||
},
|
||||
streaming: {
|
||||
supported: true,
|
||||
includesUsage: true
|
||||
}
|
||||
}
|
||||
|
||||
// 完整的模型能力映射表
|
||||
export const MODEL_CAPABILITIES_REGISTRY: Record<string, ModelCapabilities> = {
|
||||
// GPT-5系列
|
||||
'gpt-5': GPT5_CAPABILITIES,
|
||||
'gpt-5-mini': GPT5_CAPABILITIES,
|
||||
'gpt-5-nano': GPT5_CAPABILITIES,
|
||||
'gpt-5-chat-latest': GPT5_CAPABILITIES,
|
||||
|
||||
// GPT-4系列
|
||||
'gpt-4o': CHAT_COMPLETIONS_CAPABILITIES,
|
||||
'gpt-4o-mini': CHAT_COMPLETIONS_CAPABILITIES,
|
||||
'gpt-4-turbo': CHAT_COMPLETIONS_CAPABILITIES,
|
||||
'gpt-4': CHAT_COMPLETIONS_CAPABILITIES,
|
||||
|
||||
// Claude系列(通过转换层支持)
|
||||
'claude-3-5-sonnet-20241022': CHAT_COMPLETIONS_CAPABILITIES,
|
||||
'claude-3-5-haiku-20241022': CHAT_COMPLETIONS_CAPABILITIES,
|
||||
'claude-3-opus-20240229': CHAT_COMPLETIONS_CAPABILITIES,
|
||||
|
||||
// O1系列(特殊的推理模型)
|
||||
'o1': {
|
||||
...CHAT_COMPLETIONS_CAPABILITIES,
|
||||
parameters: {
|
||||
...CHAT_COMPLETIONS_CAPABILITIES.parameters,
|
||||
maxTokensField: 'max_completion_tokens',
|
||||
temperatureMode: 'fixed_one'
|
||||
}
|
||||
},
|
||||
'o1-mini': {
|
||||
...CHAT_COMPLETIONS_CAPABILITIES,
|
||||
parameters: {
|
||||
...CHAT_COMPLETIONS_CAPABILITIES.parameters,
|
||||
maxTokensField: 'max_completion_tokens',
|
||||
temperatureMode: 'fixed_one'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 智能推断未注册模型的能力
|
||||
export function inferModelCapabilities(modelName: string): ModelCapabilities | null {
|
||||
if (!modelName) return null
|
||||
|
||||
const lowerName = modelName.toLowerCase()
|
||||
|
||||
// GPT-5系列
|
||||
if (lowerName.includes('gpt-5') || lowerName.includes('gpt5')) {
|
||||
return GPT5_CAPABILITIES
|
||||
}
|
||||
|
||||
// GPT-6系列(预留)
|
||||
if (lowerName.includes('gpt-6') || lowerName.includes('gpt6')) {
|
||||
return {
|
||||
...GPT5_CAPABILITIES,
|
||||
streaming: { supported: true, includesUsage: true }
|
||||
}
|
||||
}
|
||||
|
||||
// GLM系列
|
||||
if (lowerName.includes('glm-5') || lowerName.includes('glm5')) {
|
||||
return {
|
||||
...GPT5_CAPABILITIES,
|
||||
toolCalling: {
|
||||
...GPT5_CAPABILITIES.toolCalling,
|
||||
supportsAllowedTools: false // GLM可能不支持
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// O1系列
|
||||
if (lowerName.startsWith('o1') || lowerName.includes('o1-')) {
|
||||
return {
|
||||
...CHAT_COMPLETIONS_CAPABILITIES,
|
||||
parameters: {
|
||||
...CHAT_COMPLETIONS_CAPABILITIES.parameters,
|
||||
maxTokensField: 'max_completion_tokens',
|
||||
temperatureMode: 'fixed_one'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 默认返回null,让系统使用默认行为
|
||||
return null
|
||||
}
|
||||
|
||||
// 获取模型能力(带缓存)
|
||||
const capabilityCache = new Map<string, ModelCapabilities>()
|
||||
|
||||
export function getModelCapabilities(modelName: string): ModelCapabilities {
|
||||
// 检查缓存
|
||||
if (capabilityCache.has(modelName)) {
|
||||
return capabilityCache.get(modelName)!
|
||||
}
|
||||
|
||||
// 查找注册表
|
||||
if (MODEL_CAPABILITIES_REGISTRY[modelName]) {
|
||||
const capabilities = MODEL_CAPABILITIES_REGISTRY[modelName]
|
||||
capabilityCache.set(modelName, capabilities)
|
||||
return capabilities
|
||||
}
|
||||
|
||||
// 尝试推断
|
||||
const inferred = inferModelCapabilities(modelName)
|
||||
if (inferred) {
|
||||
capabilityCache.set(modelName, inferred)
|
||||
return inferred
|
||||
}
|
||||
|
||||
// 默认为Chat Completions
|
||||
const defaultCapabilities = CHAT_COMPLETIONS_CAPABILITIES
|
||||
capabilityCache.set(modelName, defaultCapabilities)
|
||||
return defaultCapabilities
|
||||
}
|
||||
```
|
||||
|
||||
### Step 1.3: 创建基础适配器类
|
||||
|
||||
**文件**: `src/services/adapters/base.ts` (新建)
|
||||
|
||||
**任务**: 创建adapters目录和基础类
|
||||
|
||||
```typescript
|
||||
import { ModelCapabilities, UnifiedRequestParams, UnifiedResponse } from '../../types/modelCapabilities'
|
||||
import { ModelProfile } from '../../utils/config'
|
||||
import { Tool } from '../../Tool'
|
||||
|
||||
export abstract class ModelAPIAdapter {
|
||||
constructor(
|
||||
protected capabilities: ModelCapabilities,
|
||||
protected modelProfile: ModelProfile
|
||||
) {}
|
||||
|
||||
// 子类必须实现的方法
|
||||
abstract createRequest(params: UnifiedRequestParams): any
|
||||
abstract parseResponse(response: any): UnifiedResponse
|
||||
abstract buildTools(tools: Tool[]): any
|
||||
|
||||
// 共享的工具方法
|
||||
protected getMaxTokensParam(): string {
|
||||
return this.capabilities.parameters.maxTokensField
|
||||
}
|
||||
|
||||
protected getTemperature(): number {
|
||||
if (this.capabilities.parameters.temperatureMode === 'fixed_one') {
|
||||
return 1
|
||||
}
|
||||
if (this.capabilities.parameters.temperatureMode === 'restricted') {
|
||||
return Math.min(1, this.modelProfile.temperature || 0.7)
|
||||
}
|
||||
return this.modelProfile.temperature || 0.7
|
||||
}
|
||||
|
||||
protected shouldIncludeReasoningEffort(): boolean {
|
||||
return this.capabilities.parameters.supportsReasoningEffort
|
||||
}
|
||||
|
||||
protected shouldIncludeVerbosity(): boolean {
|
||||
return this.capabilities.parameters.supportsVerbosity
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Step 1.4: 创建Responses API适配器
|
||||
|
||||
**文件**: `src/services/adapters/responsesAPI.ts` (新建)
|
||||
|
||||
**任务**: 实现Responses API适配器
|
||||
|
||||
```typescript
|
||||
import { ModelAPIAdapter } from './base'
|
||||
import { UnifiedRequestParams, UnifiedResponse } from '../../types/modelCapabilities'
|
||||
import { Tool } from '../../Tool'
|
||||
import { zodToJsonSchema } from '../../utils/zodToJsonSchema'
|
||||
|
||||
export class ResponsesAPIAdapter extends ModelAPIAdapter {
|
||||
createRequest(params: UnifiedRequestParams): any {
|
||||
const { messages, systemPrompt, tools, maxTokens } = params
|
||||
|
||||
// 分离系统消息和用户消息
|
||||
const systemMessages = messages.filter(m => m.role === 'system')
|
||||
const nonSystemMessages = messages.filter(m => m.role !== 'system')
|
||||
|
||||
// 构建基础请求
|
||||
const request: any = {
|
||||
model: this.modelProfile.modelName,
|
||||
input: this.convertMessagesToInput(nonSystemMessages),
|
||||
instructions: this.buildInstructions(systemPrompt, systemMessages)
|
||||
}
|
||||
|
||||
// 添加token限制
|
||||
request[this.getMaxTokensParam()] = maxTokens
|
||||
|
||||
// 添加温度(GPT-5只支持1)
|
||||
if (this.getTemperature() === 1) {
|
||||
request.temperature = 1
|
||||
}
|
||||
|
||||
// 添加推理控制
|
||||
if (this.shouldIncludeReasoningEffort()) {
|
||||
request.reasoning = {
|
||||
effort: params.reasoningEffort || this.modelProfile.reasoningEffort || 'medium'
|
||||
}
|
||||
}
|
||||
|
||||
// 添加详细度控制
|
||||
if (this.shouldIncludeVerbosity()) {
|
||||
request.text = {
|
||||
verbosity: params.verbosity || 'high' // 编码任务默认高详细度
|
||||
}
|
||||
}
|
||||
|
||||
// 添加工具
|
||||
if (tools && tools.length > 0) {
|
||||
request.tools = this.buildTools(tools)
|
||||
|
||||
// 处理allowed_tools
|
||||
if (params.allowedTools && this.capabilities.toolCalling.supportsAllowedTools) {
|
||||
request.tool_choice = {
|
||||
type: 'allowed_tools',
|
||||
mode: 'auto',
|
||||
tools: params.allowedTools
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 添加状态管理
|
||||
if (params.previousResponseId && this.capabilities.stateManagement.supportsPreviousResponseId) {
|
||||
request.previous_response_id = params.previousResponseId
|
||||
}
|
||||
|
||||
return request
|
||||
}
|
||||
|
||||
buildTools(tools: Tool[]): any[] {
|
||||
// 如果不支持freeform,使用传统格式
|
||||
if (!this.capabilities.toolCalling.supportsFreeform) {
|
||||
return tools.map(tool => ({
|
||||
type: 'function',
|
||||
function: {
|
||||
name: tool.name,
|
||||
description: tool.description || '',
|
||||
parameters: tool.inputJSONSchema || zodToJsonSchema(tool.inputSchema)
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
// Custom tools格式(GPT-5特性)
|
||||
return tools.map(tool => {
|
||||
const hasSchema = tool.inputJSONSchema || tool.inputSchema
|
||||
const isCustom = !hasSchema || tool.freeformInput
|
||||
|
||||
if (isCustom) {
|
||||
// Custom tool格式
|
||||
return {
|
||||
type: 'custom',
|
||||
name: tool.name,
|
||||
description: tool.description || ''
|
||||
}
|
||||
} else {
|
||||
// 传统function格式
|
||||
return {
|
||||
type: 'function',
|
||||
function: {
|
||||
name: tool.name,
|
||||
description: tool.description || '',
|
||||
parameters: tool.inputJSONSchema || zodToJsonSchema(tool.inputSchema)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
parseResponse(response: any): UnifiedResponse {
|
||||
// 处理基础文本输出
|
||||
let content = response.output_text || ''
|
||||
|
||||
// 处理结构化输出
|
||||
if (response.output && Array.isArray(response.output)) {
|
||||
const messageItems = response.output.filter(item => item.type === 'message')
|
||||
if (messageItems.length > 0) {
|
||||
content = messageItems
|
||||
.map(item => {
|
||||
if (item.content && Array.isArray(item.content)) {
|
||||
return item.content
|
||||
.filter(c => c.type === 'text')
|
||||
.map(c => c.text)
|
||||
.join('\n')
|
||||
}
|
||||
return item.content || ''
|
||||
})
|
||||
.filter(Boolean)
|
||||
.join('\n\n')
|
||||
}
|
||||
}
|
||||
|
||||
// 解析工具调用
|
||||
const toolCalls = this.parseToolCalls(response)
|
||||
|
||||
// 构建统一响应
|
||||
return {
|
||||
id: response.id || `resp_${Date.now()}`,
|
||||
content,
|
||||
toolCalls,
|
||||
usage: {
|
||||
promptTokens: response.usage?.input_tokens || 0,
|
||||
completionTokens: response.usage?.output_tokens || 0,
|
||||
reasoningTokens: response.usage?.output_tokens_details?.reasoning_tokens
|
||||
},
|
||||
responseId: response.id // 保存用于状态管理
|
||||
}
|
||||
}
|
||||
|
||||
private convertMessagesToInput(messages: any[]): any {
|
||||
// 将消息转换为Responses API的input格式
|
||||
// 可能需要根据实际API规范调整
|
||||
return messages
|
||||
}
|
||||
|
||||
private buildInstructions(systemPrompt: string[], systemMessages: any[]): string {
|
||||
const systemContent = systemMessages.map(m => m.content).join('\n\n')
|
||||
const promptContent = systemPrompt.join('\n\n')
|
||||
return [systemContent, promptContent].filter(Boolean).join('\n\n')
|
||||
}
|
||||
|
||||
private parseToolCalls(response: any): any[] {
|
||||
if (!response.output || !Array.isArray(response.output)) {
|
||||
return []
|
||||
}
|
||||
|
||||
return response.output
|
||||
.filter(item => item.type === 'tool_call')
|
||||
.map(item => ({
|
||||
id: item.id || `tool_${Date.now()}`,
|
||||
type: 'tool_call',
|
||||
name: item.name,
|
||||
arguments: item.arguments // 可能是文本或JSON
|
||||
}))
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Step 1.5: 创建Chat Completions适配器
|
||||
|
||||
**文件**: `src/services/adapters/chatCompletions.ts` (新建)
|
||||
|
||||
**任务**: 实现Chat Completions适配器
|
||||
|
||||
```typescript
|
||||
import { ModelAPIAdapter } from './base'
|
||||
import { UnifiedRequestParams, UnifiedResponse } from '../../types/modelCapabilities'
|
||||
import { Tool } from '../../Tool'
|
||||
import { zodToJsonSchema } from '../../utils/zodToJsonSchema'
|
||||
|
||||
export class ChatCompletionsAdapter extends ModelAPIAdapter {
|
||||
createRequest(params: UnifiedRequestParams): any {
|
||||
const { messages, systemPrompt, tools, maxTokens, stream } = params
|
||||
|
||||
// 构建完整消息列表(包含系统提示)
|
||||
const fullMessages = this.buildMessages(systemPrompt, messages)
|
||||
|
||||
// 构建请求
|
||||
const request: any = {
|
||||
model: this.modelProfile.modelName,
|
||||
messages: fullMessages,
|
||||
[this.getMaxTokensParam()]: maxTokens,
|
||||
temperature: this.getTemperature()
|
||||
}
|
||||
|
||||
// 添加工具
|
||||
if (tools && tools.length > 0) {
|
||||
request.tools = this.buildTools(tools)
|
||||
request.tool_choice = 'auto'
|
||||
}
|
||||
|
||||
// 添加流式选项
|
||||
if (stream) {
|
||||
request.stream = true
|
||||
request.stream_options = {
|
||||
include_usage: true
|
||||
}
|
||||
}
|
||||
|
||||
// O1模型的特殊处理
|
||||
if (this.modelProfile.modelName.startsWith('o1')) {
|
||||
delete request.temperature // O1不支持temperature
|
||||
delete request.stream // O1不支持流式
|
||||
delete request.stream_options
|
||||
}
|
||||
|
||||
return request
|
||||
}
|
||||
|
||||
buildTools(tools: Tool[]): any[] {
|
||||
// Chat Completions只支持传统的function calling
|
||||
return tools.map(tool => ({
|
||||
type: 'function',
|
||||
function: {
|
||||
name: tool.name,
|
||||
description: tool.description || '',
|
||||
parameters: tool.inputJSONSchema || zodToJsonSchema(tool.inputSchema)
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
parseResponse(response: any): UnifiedResponse {
|
||||
const choice = response.choices?.[0]
|
||||
|
||||
return {
|
||||
id: response.id || `chatcmpl_${Date.now()}`,
|
||||
content: choice?.message?.content || '',
|
||||
toolCalls: choice?.message?.tool_calls || [],
|
||||
usage: {
|
||||
promptTokens: response.usage?.prompt_tokens || 0,
|
||||
completionTokens: response.usage?.completion_tokens || 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private buildMessages(systemPrompt: string[], messages: any[]): any[] {
|
||||
// 合并系统提示和消息
|
||||
const systemMessages = systemPrompt.map(prompt => ({
|
||||
role: 'system',
|
||||
content: prompt
|
||||
}))
|
||||
|
||||
return [...systemMessages, ...messages]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Step 1.6: 创建适配器工厂
|
||||
|
||||
**文件**: `src/services/modelAdapterFactory.ts` (新建)
|
||||
|
||||
**任务**: 创建工厂类来选择合适的适配器
|
||||
|
||||
```typescript
|
||||
import { ModelAPIAdapter } from './adapters/base'
|
||||
import { ResponsesAPIAdapter } from './adapters/responsesAPI'
|
||||
import { ChatCompletionsAdapter } from './adapters/chatCompletions'
|
||||
import { getModelCapabilities } from '../constants/modelCapabilities'
|
||||
import { ModelProfile, getGlobalConfig } from '../utils/config'
|
||||
import { ModelCapabilities } from '../types/modelCapabilities'
|
||||
|
||||
export class ModelAdapterFactory {
|
||||
/**
|
||||
* 根据模型配置创建合适的适配器
|
||||
*/
|
||||
static createAdapter(modelProfile: ModelProfile): ModelAPIAdapter {
|
||||
const capabilities = getModelCapabilities(modelProfile.modelName)
|
||||
|
||||
// 决定使用哪种API
|
||||
const apiType = this.determineAPIType(modelProfile, capabilities)
|
||||
|
||||
// 创建对应的适配器
|
||||
switch (apiType) {
|
||||
case 'responses_api':
|
||||
return new ResponsesAPIAdapter(capabilities, modelProfile)
|
||||
case 'chat_completions':
|
||||
default:
|
||||
return new ChatCompletionsAdapter(capabilities, modelProfile)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 决定应该使用哪种API
|
||||
*/
|
||||
private static determineAPIType(
|
||||
modelProfile: ModelProfile,
|
||||
capabilities: ModelCapabilities
|
||||
): 'responses_api' | 'chat_completions' {
|
||||
// 如果模型不支持Responses API,直接使用Chat Completions
|
||||
if (capabilities.apiArchitecture.primary !== 'responses_api') {
|
||||
return 'chat_completions'
|
||||
}
|
||||
|
||||
// 检查是否是官方OpenAI端点
|
||||
const isOfficialOpenAI = !modelProfile.baseURL ||
|
||||
modelProfile.baseURL.includes('api.openai.com')
|
||||
|
||||
// 非官方端点使用Chat Completions(即使模型支持Responses API)
|
||||
if (!isOfficialOpenAI) {
|
||||
// 如果有fallback选项,使用fallback
|
||||
if (capabilities.apiArchitecture.fallback === 'chat_completions') {
|
||||
return 'chat_completions'
|
||||
}
|
||||
// 否则使用primary(可能会失败,但让它尝试)
|
||||
return capabilities.apiArchitecture.primary
|
||||
}
|
||||
|
||||
// 检查是否需要流式(Responses API暂不支持)
|
||||
const config = getGlobalConfig()
|
||||
if (config.stream && !capabilities.streaming.supported) {
|
||||
// 需要流式但Responses API不支持,降级到Chat Completions
|
||||
if (capabilities.apiArchitecture.fallback === 'chat_completions') {
|
||||
return 'chat_completions'
|
||||
}
|
||||
}
|
||||
|
||||
// 使用主要API类型
|
||||
return capabilities.apiArchitecture.primary
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查模型是否应该使用Responses API
|
||||
*/
|
||||
static shouldUseResponsesAPI(modelProfile: ModelProfile): boolean {
|
||||
const capabilities = getModelCapabilities(modelProfile.modelName)
|
||||
const apiType = this.determineAPIType(modelProfile, capabilities)
|
||||
return apiType === 'responses_api'
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔄 Phase 2: 集成与测试(第3-4天)
|
||||
|
||||
### 目标
|
||||
将新系统集成到现有代码中,与旧系统并行运行。
|
||||
|
||||
### Step 2.1: 修改claude.ts使用新系统
|
||||
|
||||
**文件**: `src/services/claude.ts` (修改)
|
||||
|
||||
**任务**: 在queryLLMWithProfile中添加新的适配器路径
|
||||
|
||||
**找到函数**: `queryLLMWithProfile` (约第1182行)
|
||||
|
||||
**修改内容**:
|
||||
|
||||
```typescript
|
||||
// 在函数开头添加功能开关
|
||||
const USE_NEW_ADAPTER_SYSTEM = process.env.USE_NEW_ADAPTERS !== 'false'
|
||||
|
||||
// 在获取modelProfile后添加新路径
|
||||
if (USE_NEW_ADAPTER_SYSTEM) {
|
||||
// 🚀 新的适配器系统
|
||||
const adapter = ModelAdapterFactory.createAdapter(modelProfile)
|
||||
|
||||
// 构建统一请求参数
|
||||
const unifiedParams: UnifiedRequestParams = {
|
||||
messages: openaiMessages, // 使用已转换的OpenAI格式消息
|
||||
systemPrompt: openaiSystem.map(s => s.content),
|
||||
tools: toolSchemas,
|
||||
maxTokens: getMaxTokensFromProfile(modelProfile),
|
||||
stream: config.stream,
|
||||
reasoningEffort: modelProfile.reasoningEffort,
|
||||
temperature: isGPT5Model(model) ? 1 : MAIN_QUERY_TEMPERATURE
|
||||
}
|
||||
|
||||
// 创建请求
|
||||
const request = adapter.createRequest(unifiedParams)
|
||||
|
||||
// 判断使用哪个API端点
|
||||
if (ModelAdapterFactory.shouldUseResponsesAPI(modelProfile)) {
|
||||
// 调用Responses API(复用现有的callGPT5ResponsesAPI)
|
||||
const response = await callGPT5ResponsesAPI(modelProfile, request, signal)
|
||||
return adapter.parseResponse(response)
|
||||
} else {
|
||||
// 调用Chat Completions(复用现有逻辑)
|
||||
// ... 现有的Chat Completions调用代码
|
||||
}
|
||||
} else {
|
||||
// 保留原有逻辑完全不变
|
||||
// ... 现有的所有代码
|
||||
}
|
||||
```
|
||||
|
||||
### Step 2.2: 添加测试脚本
|
||||
|
||||
**文件**: `src/test/testAdapters.ts` (新建)
|
||||
|
||||
**任务**: 创建测试脚本验证新系统
|
||||
|
||||
```typescript
|
||||
import { ModelAdapterFactory } from '../services/modelAdapterFactory'
|
||||
import { getGlobalConfig } from '../utils/config'
|
||||
|
||||
// 测试不同模型的适配器选择
|
||||
const testModels = [
|
||||
{ modelName: 'gpt-5', provider: 'openai' },
|
||||
{ modelName: 'gpt-4o', provider: 'openai' },
|
||||
{ modelName: 'claude-3-5-sonnet-20241022', provider: 'anthropic' },
|
||||
{ modelName: 'o1', provider: 'openai' },
|
||||
{ modelName: 'glm-5', provider: 'custom' }
|
||||
]
|
||||
|
||||
testModels.forEach(model => {
|
||||
console.log(`Testing ${model.modelName}:`)
|
||||
const adapter = ModelAdapterFactory.createAdapter(model as any)
|
||||
console.log(` Adapter type: ${adapter.constructor.name}`)
|
||||
console.log(` Should use Responses API: ${ModelAdapterFactory.shouldUseResponsesAPI(model as any)}`)
|
||||
})
|
||||
```
|
||||
|
||||
### Step 2.3: 清理硬编码(可选,Phase 3再做)
|
||||
|
||||
**文件**: `src/services/openai.ts` (修改)
|
||||
|
||||
**任务**: 标记需要移除的硬编码部分(先不删除)
|
||||
|
||||
```typescript
|
||||
// 在isGPT5Model函数上添加注释
|
||||
/**
|
||||
* @deprecated 将被ModelCapabilities系统替代
|
||||
*/
|
||||
function isGPT5Model(modelName: string): boolean {
|
||||
return modelName.startsWith('gpt-5')
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Phase 3: 优化与清理(第5-6天)
|
||||
|
||||
### 目标
|
||||
移除旧代码,完全切换到新系统。
|
||||
|
||||
### Step 3.1: 移除功能开关
|
||||
|
||||
**文件**: `src/services/claude.ts`
|
||||
|
||||
**任务**: 移除USE_NEW_ADAPTER_SYSTEM检查,默认使用新系统
|
||||
|
||||
### Step 3.2: 清理硬编码函数
|
||||
|
||||
**文件列表**:
|
||||
- `src/services/openai.ts` - 移除isGPT5Model函数
|
||||
- `src/services/claude.ts` - 移除isGPT5Model函数
|
||||
- `src/services/openai.ts` - 移除MODEL_FEATURES常量
|
||||
|
||||
### Step 3.3: 更新文档
|
||||
|
||||
**文件**: `README.md`
|
||||
|
||||
**任务**: 添加新模型支持说明
|
||||
|
||||
```markdown
|
||||
## 支持的模型
|
||||
|
||||
本系统通过能力声明系统支持以下API类型:
|
||||
- Chat Completions API: GPT-4, Claude等传统模型
|
||||
- Responses API: GPT-5, GPT-6, GLM-5等新一代模型
|
||||
|
||||
添加新模型只需在 `src/constants/modelCapabilities.ts` 中配置即可。
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ✅ 验证清单
|
||||
|
||||
### Phase 1完成标准
|
||||
- [ ] 所有新文件创建完成
|
||||
- [ ] 代码可以编译通过
|
||||
- [ ] 现有功能完全不受影响
|
||||
|
||||
### Phase 2完成标准
|
||||
- [ ] 新旧系统可以通过环境变量切换
|
||||
- [ ] GPT-5可以正常使用
|
||||
- [ ] 所有现有模型功能正常
|
||||
|
||||
### Phase 3完成标准
|
||||
- [ ] 完全使用新系统
|
||||
- [ ] 代码更简洁清晰
|
||||
- [ ] 新模型可通过配置添加
|
||||
|
||||
---
|
||||
|
||||
## 🎯 关键注意事项
|
||||
|
||||
1. **不要删除任何现有功能代码**,直到Phase 3
|
||||
2. **始终保持向后兼容**
|
||||
3. **每个Phase结束后都要测试**
|
||||
4. **如果出现问题可以立即回滚**
|
||||
|
||||
## 📝 外包程序员执行指南
|
||||
|
||||
1. **严格按照Phase顺序执行**,不要跳步
|
||||
2. **复制粘贴提供的代码**,不要自己修改
|
||||
3. **遇到问题立即停止并报告**
|
||||
4. **每完成一个Step都要git commit**,方便回滚
|
||||
|
||||
---
|
||||
|
||||
此文档设计为"无脑执行"级别,外包程序员只需要:
|
||||
1. 创建指定的文件
|
||||
2. 复制粘贴提供的代码
|
||||
3. 在指定位置修改代码
|
||||
4. 运行测试验证
|
||||
|
||||
整个过程不需要理解业务逻辑,只需要机械执行即可。
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@shareai-lab/kode",
|
||||
"version": "1.0.71",
|
||||
"version": "1.0.73",
|
||||
"bin": {
|
||||
"kode": "cli.js",
|
||||
"kwa": "cli.js",
|
||||
@ -112,8 +112,5 @@
|
||||
"shareai",
|
||||
"terminal",
|
||||
"command-line"
|
||||
],
|
||||
"bundledDependencies": [
|
||||
"tsx"
|
||||
]
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user