Skip to content

Commit ac2445c

Browse files
CrazyBoyMclaude
andcommitted
refactor: split provider implementations and add comprehensive CI
Major refactoring of provider architecture and testing infrastructure: Provider Architecture: - Split monolithic provider.ts into modular architecture - Create src/infra/providers/ with separate files per provider - Add shared core utilities (errors, retry, usage, fork, logger) - Improve type safety with dedicated types.ts and utils.ts CI/CD Pipeline: - Add GitHub Actions workflow with 4-stage pipeline - Stage 1: Lint, TypeCheck, Build - Stage 2: Unit tests - Stage 3: Provider E2E tests (Anthropic, OpenAI, Gemini matrix) - Stage 4: Agent integration tests Agent Integration Tests: - Add comprehensive ci-integration.test.ts - Test file operations (create, read, edit, glob) - Test bash commands (system info, ls, env vars) - Test multi-turn context preservation - Test resume/restore functionality - Test error handling (missing files, failed commands) Code Quality: - Remove outdated documentation files (PROGRESS_REPORT, MIGRATION_V2.7, etc.) - Update .env.test.example with proper structure - Improve test assertions for provider flexibility - Register builtin tools for integration tests Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 7d830a7 commit ac2445c

33 files changed

Lines changed: 8876 additions & 4698 deletions

.env.test.example

Lines changed: 32 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,40 @@
11
# Provider test environment variables (integration/e2e)
22
# Copy to .env.test and fill in real credentials.
33

4-
# Legacy generic provider config (kept for compatibility)
5-
KODE_SDK_TEST_PROVIDER_BASE_URL=https://api.openai-next.com/
6-
KODE_SDK_TEST_PROVIDER_API_KEY=replace-with-your-api-key
7-
KODE_SDK_TEST_PROVIDER_MODEL=kimi-k2-turbo-preview
4+
# =============================================================================
5+
# ANTHROPIC (Claude)
6+
# =============================================================================
7+
ANTHROPIC_API_KEY=replace-with-your-anthropic-key
8+
ANTHROPIC_MODEL_ID=claude-sonnet-4-5-20250929
9+
ANTHROPIC_BASE_URL=https://api.openai-next.com
10+
ANTHROPIC_ENABLE_INTERTWINED=0
11+
ANTHROPIC_ENABLE_PDF=0
12+
13+
# Anthropic Thinking model (for extended thinking tests)
14+
ANTHROPIC_THINKING_MODEL_ID=claude-sonnet-4-5-20250929-thinking
815

9-
# OpenAI
16+
# =============================================================================
17+
# OPENAI - Chat Completions API
18+
# =============================================================================
1019
OPENAI_API_KEY=replace-with-your-openai-key
11-
OPENAI_MODEL_ID=gpt-4o
12-
OPENAI_BASE_URL=https://api.openai.com/v1
13-
# OPENAI_OPENAI_API=chat
14-
# OPENAI_ENABLE_PDF=1
15-
# OPENAI_ENABLE_INTERTWINED=1
16-
# OPENAI_PROXY_URL=http://
20+
OPENAI_MODEL_ID=gpt-4.1
21+
OPENAI_BASE_URL=https://api.openai-next.com/v1
22+
OPENAI_API=chat
1723

18-
# Gemini
24+
# =============================================================================
25+
# OPENAI - Responses API (for reasoning models)
26+
# =============================================================================
27+
OPENAI_RESPONSES_API_KEY=replace-with-your-openai-key
28+
OPENAI_RESPONSES_MODEL_ID=gpt-5.2
29+
OPENAI_RESPONSES_BASE_URL=https://api.openai-next.com/v1
30+
OPENAI_RESPONSES_API=responses
31+
OPENAI_RESPONSES_REASONING_EFFORT=medium
32+
33+
# =============================================================================
34+
# GEMINI (Google)
35+
# =============================================================================
1936
GEMINI_API_KEY=replace-with-your-gemini-key
20-
GEMINI_MODEL_ID=gemini-3.0-flash
37+
GEMINI_MODEL_ID=gemini-3-flash-preview
2138
GEMINI_BASE_URL=https://generativelanguage.googleapis.com/v1beta
22-
# GEMINI_ENABLE_PDF=1
23-
# GEMINI_ENABLE_INTERTWINED=1
24-
# GEMINI_PROXY_URL=http://
25-
26-
# Anthropic
27-
ANTHROPIC_API_KEY=replace-with-your-anthropic-key
28-
ANTHROPIC_MODEL_ID=claude-3-5-sonnet-20241022
29-
ANTHROPIC_BASE_URL=https://api.anthropic.com
30-
# ANTHROPIC_ENABLE_PDF=1
31-
# ANTHROPIC_ENABLE_INTERTWINED=1
32-
# ANTHROPIC_EXTRA_HEADERS={"anthropic-beta":"interleaved-thinking-2025-05-14"}
33-
# ANTHROPIC_EXTRA_BODY={"thinking":{"type":"enabled","budget_tokens":1024}}
34-
# ANTHROPIC_PROXY_URL=http://
35-
36-
# GLM (OpenAI-compatible)
37-
GLM_API_KEY=replace-with-your-glm-key
38-
GLM_MODEL_ID=glm-4.5
39-
GLM_BASE_URL=https://api.z.ai/api/paas/v4
40-
# GLM_ENABLE_PDF=1
41-
# GLM_ENABLE_INTERTWINED=1
42-
# GLM_EXTRA_BODY={"thinking":{"type":"enabled","clear_thinking":false}}
43-
44-
# MiniMax (OpenAI-compatible)
45-
MINIMAX_API_KEY=replace-with-your-minimax-key
46-
MINIMAX_MODEL_ID=MiniMax-M2.1
47-
MINIMAX_BASE_URL=https://api.minimax.chat/v1
48-
# MINIMAX_ENABLE_PDF=1
49-
# MINIMAX_ENABLE_INTERTWINED=1
50-
# MINIMAX_EXTRA_BODY={"reasoning_split":true}
39+
GEMINI_ENABLE_INTERTWINED=1
40+
GEMINI_ENABLE_PDF=1

.github/workflows/ci.yml

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
name: CI Tests
2+
3+
on:
4+
push:
5+
branches: [main, develop, 'feature/**', 'refactor/**']
6+
pull_request:
7+
branches: [main, develop]
8+
workflow_dispatch:
9+
10+
env:
11+
NODE_VERSION: '20'
12+
13+
jobs:
14+
# ===========================================================================
15+
# Stage 1: Fast checks (run on every commit)
16+
# ===========================================================================
17+
lint-and-typecheck:
18+
name: Lint & TypeCheck
19+
runs-on: ubuntu-latest
20+
steps:
21+
- uses: actions/checkout@v4
22+
23+
- name: Setup Node.js
24+
uses: actions/setup-node@v4
25+
with:
26+
node-version: ${{ env.NODE_VERSION }}
27+
cache: 'npm'
28+
29+
- name: Install dependencies
30+
run: npm ci
31+
32+
- name: TypeScript check
33+
run: npx tsc --noEmit
34+
35+
- name: Build
36+
run: npm run build
37+
38+
unit-tests:
39+
name: Unit Tests
40+
runs-on: ubuntu-latest
41+
steps:
42+
- uses: actions/checkout@v4
43+
44+
- name: Setup Node.js
45+
uses: actions/setup-node@v4
46+
with:
47+
node-version: ${{ env.NODE_VERSION }}
48+
cache: 'npm'
49+
50+
- name: Install dependencies
51+
run: npm ci
52+
53+
- name: Run unit tests
54+
run: npm run test:unit
55+
56+
# ===========================================================================
57+
# Stage 2: Provider E2E tests (run on every commit)
58+
# ===========================================================================
59+
provider-e2e:
60+
name: Provider E2E
61+
runs-on: ubuntu-latest
62+
needs: [lint-and-typecheck, unit-tests]
63+
timeout-minutes: 20
64+
strategy:
65+
fail-fast: false
66+
matrix:
67+
provider:
68+
- anthropic
69+
- openai
70+
- gemini
71+
72+
steps:
73+
- uses: actions/checkout@v4
74+
75+
- name: Setup Node.js
76+
uses: actions/setup-node@v4
77+
with:
78+
node-version: ${{ env.NODE_VERSION }}
79+
cache: 'npm'
80+
81+
- name: Install dependencies
82+
run: npm ci
83+
84+
- name: Create test environment
85+
run: |
86+
cat > .env.test << 'EOF'
87+
# Anthropic
88+
ANTHROPIC_API_KEY=${{ secrets.ANTHROPIC_API_KEY }}
89+
ANTHROPIC_MODEL_ID=${{ vars.ANTHROPIC_MODEL_ID }}
90+
ANTHROPIC_BASE_URL=${{ vars.ANTHROPIC_BASE_URL }}
91+
ANTHROPIC_ENABLE_INTERTWINED=0
92+
ANTHROPIC_ENABLE_PDF=0
93+
94+
# OpenAI Chat
95+
OPENAI_API_KEY=${{ secrets.OPENAI_API_KEY }}
96+
OPENAI_MODEL_ID=${{ vars.OPENAI_MODEL_ID }}
97+
OPENAI_BASE_URL=${{ vars.OPENAI_BASE_URL }}
98+
OPENAI_API=chat
99+
100+
# OpenAI Responses
101+
OPENAI_RESPONSES_API_KEY=${{ secrets.OPENAI_API_KEY }}
102+
OPENAI_RESPONSES_MODEL_ID=${{ vars.OPENAI_RESPONSES_MODEL_ID }}
103+
OPENAI_RESPONSES_BASE_URL=${{ vars.OPENAI_RESPONSES_BASE_URL }}
104+
OPENAI_RESPONSES_API=responses
105+
OPENAI_RESPONSES_REASONING_EFFORT=medium
106+
107+
# Gemini
108+
GEMINI_API_KEY=${{ secrets.GEMINI_API_KEY }}
109+
GEMINI_MODEL_ID=${{ vars.GEMINI_MODEL_ID }}
110+
GEMINI_BASE_URL=${{ vars.GEMINI_BASE_URL }}
111+
GEMINI_ENABLE_INTERTWINED=1
112+
GEMINI_ENABLE_PDF=1
113+
EOF
114+
115+
- name: Run Anthropic E2E
116+
if: matrix.provider == 'anthropic'
117+
run: npx ts-node tests/e2e/providers/anthropic.test.ts
118+
env:
119+
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
120+
121+
- name: Run OpenAI E2E
122+
if: matrix.provider == 'openai'
123+
run: npx ts-node tests/e2e/providers/openai.test.ts
124+
env:
125+
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
126+
127+
- name: Run Gemini E2E
128+
if: matrix.provider == 'gemini'
129+
run: npx ts-node tests/e2e/providers/gemini.test.ts
130+
env:
131+
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
132+
133+
# ===========================================================================
134+
# Stage 3: Agent Integration tests (comprehensive agent workflow testing)
135+
# ===========================================================================
136+
agent-integration:
137+
name: Agent Integration
138+
runs-on: ubuntu-latest
139+
needs: [provider-e2e]
140+
timeout-minutes: 30
141+
142+
steps:
143+
- uses: actions/checkout@v4
144+
145+
- name: Setup Node.js
146+
uses: actions/setup-node@v4
147+
with:
148+
node-version: ${{ env.NODE_VERSION }}
149+
cache: 'npm'
150+
151+
- name: Install dependencies
152+
run: npm ci
153+
154+
- name: Create test environment
155+
run: |
156+
cat > .env.test << 'EOF'
157+
# Use OpenAI for integration tests (most reliable)
158+
OPENAI_API_KEY=${{ secrets.OPENAI_API_KEY }}
159+
OPENAI_MODEL_ID=${{ vars.OPENAI_MODEL_ID }}
160+
OPENAI_BASE_URL=${{ vars.OPENAI_BASE_URL }}
161+
OPENAI_API=chat
162+
163+
# Anthropic backup
164+
ANTHROPIC_API_KEY=${{ secrets.ANTHROPIC_API_KEY }}
165+
ANTHROPIC_MODEL_ID=${{ vars.ANTHROPIC_MODEL_ID }}
166+
ANTHROPIC_BASE_URL=${{ vars.ANTHROPIC_BASE_URL }}
167+
168+
# Gemini backup
169+
GEMINI_API_KEY=${{ secrets.GEMINI_API_KEY }}
170+
GEMINI_MODEL_ID=${{ vars.GEMINI_MODEL_ID }}
171+
GEMINI_BASE_URL=${{ vars.GEMINI_BASE_URL }}
172+
EOF
173+
174+
- name: Run Agent Integration Tests
175+
run: npx ts-node tests/integration/agent/ci-integration.test.ts
176+
env:
177+
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
178+
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
179+
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
180+
181+
# ===========================================================================
182+
# Summary job
183+
# ===========================================================================
184+
ci-summary:
185+
name: CI Summary
186+
runs-on: ubuntu-latest
187+
needs: [lint-and-typecheck, unit-tests, provider-e2e, agent-integration]
188+
if: always()
189+
steps:
190+
- name: Check results
191+
run: |
192+
echo "=== CI Results ==="
193+
echo "Lint & TypeCheck: ${{ needs.lint-and-typecheck.result }}"
194+
echo "Unit Tests: ${{ needs.unit-tests.result }}"
195+
echo "Provider E2E: ${{ needs.provider-e2e.result }}"
196+
echo "Agent Integration: ${{ needs.agent-integration.result }}"
197+
198+
if [ "${{ needs.lint-and-typecheck.result }}" == "failure" ] || \
199+
[ "${{ needs.unit-tests.result }}" == "failure" ] || \
200+
[ "${{ needs.provider-e2e.result }}" == "failure" ] || \
201+
[ "${{ needs.agent-integration.result }}" == "failure" ]; then
202+
echo "Some tests failed!"
203+
exit 1
204+
fi
205+
echo "All CI checks passed!"

0 commit comments

Comments
 (0)