Cohere Local Dev Loop
Overview
Set up a fast, reproducible local development workflow with Cohere API v2 mocking, vitest testing, and hot reload.
Prerequisites
- Completed
cohere-install-auth setup
- Node.js 18+ with npm/pnpm
- TypeScript project with
tsx or ts-node
Instructions
Step 1: Project Structure
my-cohere-project/
├── src/
│ ├── cohere/
│ │ ├── client.ts # CohereClientV2 wrapper
│ │ ├── chat.ts # Chat completions
│ │ ├── embed.ts # Embedding operations
│ │ └── rerank.ts # Reranking operations
│ └── index.ts
├── tests/
│ ├── chat.test.ts
│ ├── embed.test.ts
│ └── fixtures/
│ └── responses.ts # Mock API responses
├── .env.local # Local secrets (git-ignored)
├── .env.example # Template for team
└── package.json
Step 2: Package Setup
{
"scripts": {
"dev": "tsx watch src/index.ts",
"test": "vitest",
"test:watch": "vitest --watch",
"test:integration": "COHERE_INTEGRATION=1 vitest --run"
},
"dependencies": {
"cohere-ai": "^7.0.0"
},
"devDependencies": {
"tsx": "^4.0.0",
"vitest": "^2.0.0",
"typescript": "^5.5.0"
}
}
Step 3: Client Wrapper
import { CohereClientV2 } from 'cohere-ai';
let instance: CohereClientV2 | null = null;
export function getCohere(): CohereClientV2 {
if (!instance) {
instance = new CohereClientV2({
token: process.env.CO_API_KEY,
});
}
return instance;
}
export function resetClient(): void {
instance = null;
}
Step 4: Mock Fixtures
export const mockChatResponse = {
id: 'test-chat-id',
message: {
role: 'assistant' as const,
content: [{ type: 'text' as const, text: 'Mocked response' }],
},
finishReason: 'COMPLETE' as const,
usage: { billedUnits: { inputTokens: 10, outputTokens: 5 } },
};
export const mockEmbedResponse = {
id: 'test-embed-id',
embeddings: {
float: [[0.1, 0.2, 0.3, 0.4]],
},
meta: { billedUnits: { inputTokens: 4 } },
};
export const mockRerankResponse = {
id: 'test-rerank-id',
results: [
{ index: 0, relevanceScore: 0.95 },
{ index: 2, relevanceScore: },
],
: { : { : } },
};
Step 5: Test with Mocks
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { mockChatResponse } from './fixtures/responses';
vi.mock('cohere-ai', () => ({
CohereClientV2: vi.fn().mockImplementation(() => ({
chat: vi.fn().mockResolvedValue(mockChatResponse),
chatStream: vi.fn().mockReturnValue({
[Symbol.asyncIterator]: async function* () {
yield { type: 'content-delta', delta: { message: { content: { text: 'Hi' } } } };
},
}),
embed: vi.fn().mockResolvedValue({ embeddings: { float: [[0.1, 0.2]] } }),
rerank: vi.fn().mockResolvedValue({
results: [{ index: 0, relevanceScore: 0.9 }],
}),
})),
}));
describe('Cohere Chat', () => {
(, () => {
{ } = ();
cohere = ();
result = cohere.({
: ,
: [{ : , : }],
});
(result.?.?.[]?.).();
(result.).();
});
});
Step 6: Integration Tests (Optional, Hits Real API)
import { describe, it, expect } from 'vitest';
import { CohereClientV2 } from 'cohere-ai';
const shouldRun = process.env.COHERE_INTEGRATION === '1';
describe.skipIf(!shouldRun)('Cohere Integration', () => {
const cohere = new CohereClientV2();
it('chat endpoint responds', async () => {
const res = await cohere.chat({
model: 'command-r7b-12-2024',
messages: [{ role: 'user', content: 'Say OK' }],
maxTokens: 5,
});
expect(res.message?.content?.[0]?.text).toBeTruthy();
}, 15_000);
it('embed endpoint responds', async () => {
const res = await cohere.embed({
model: 'embed-v4.0',
texts: [],
: ,
: [],
});
(res..[].).();
}, );
});
Environment Management
CO_API_KEY=your-trial-key-here
CO_API_KEY=actual-key
.env.local
.env.*.local
Output
- Working dev environment with hot reload via
tsx watch
- Unit tests with mocked Cohere responses (no API calls)
- Optional integration tests gated by
COHERE_INTEGRATION=1
- Mock fixtures matching real API v2 response shapes
Error Handling
| Error | Cause | Solution |
|---|
vi.mock not working | Wrong import order | Mock before importing modules |
CO_API_KEY undefined | .env not loaded | Use dotenv/config or tsx env support |
| Integration test timeout | Slow network | Increase timeout to 15s+ |
| Type mismatch on mock | API shape changed | Update fixtures to match SDK types |
Resources
Next Steps
See cohere-sdk-patterns for production-ready code patterns.