8000 Merge pull request #273 from drivecore/feature/xai-baseUrl-overrides · drivecore/mycoder@6a3a392 · GitHub
[go: up one dir, main page]

Skip to content

Commit 6a3a392

Browse files
authored
Merge pull request #273 from drivecore/feature/xai-baseUrl-overrides
Feature/xai base url overrides
2 parents 72f9801 + a898b3f commit 6a3a392

File tree

19 files changed

+262
-164
lines changed

19 files changed

+262
-164
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@ packages/docs/.env.local
1414
packages/docs/.env.development.local
1515
packages/docs/.env.test.local
1616
packages/docs/.env.production.local
17+
mcp.server.setup.json

mycoder.config.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ export default {
1616
//provider: 'ollama',
1717
//model: 'medragondot/Sky-T1-32B-Preview:latest',
1818
//model: 'llama3.2:3b',
19+
//provider: 'xai',
20+
//model: 'grok-2-latest',
1921
maxTokens: 4096,
2022
temperature: 0.7,
2123

packages/agent/CHANGELOG.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
# [mycoder-agent-v1.3.1](https://github.com/drivecore/mycoder/compare/mycoder-agent-v1.3.0...mycoder-agent-v1.3.1) (2025-03-13)
22

3-
43
### Bug Fixes
54

6-
* redo ollama llm provider using ollama sdk ([586fe82](https://github.com/drivecore/mycoder/commit/586fe827d048aa6c13675ba838bd50309b3980e2))
7-
* update Ollama provider to use official npm package API correctly ([738a84a](https://github.com/drivecore/mycoder/commit/738a84aff560076e4ad24129f5dc9bf09d304ffa))
5+
- redo ollama llm provider using ollama sdk ([586fe82](https://github.com/drivecore/mycoder/commit/586fe827d048aa6c13675ba838bd50309b3980e2))
6+
- update Ollama provider to use official npm package API correctly ([738a84a](https://github.com/drivecore/mycoder/commit/738a84aff560076e4ad24129f5dc9bf09d304ffa))
87

98
# [mycoder-agent-v1.3.0](https://github.com/drivecore/mycoder/compare/mycoder-agent-v1.2.0...mycoder-agent-v1.3.0) (2025-03-12)
109

packages/agent/src/core/llm/__tests__/openai.test.ts

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -69,19 +69,6 @@ describe('OpenAIProvider', () => {
6969
expect(provider.model).toBe('gpt-4');
7070
});
7171

72-
it('should throw error if API key is missing', () => {
73-
// Clear environment variable
74-
const originalKey = process.env.OPENAI_API_KEY;
75-
delete process.env.OPENAI_API_KEY;
76-
77-
expect(() => new OpenAIProvider('gpt-4')).toThrow(
78-
'OpenAI API key is required',
79-
);
80-
81-
// Restore environment variable
82-
process.env.OPENAI_API_KEY = originalKey;
83-
});
84-
8572
it('should generate text and handle tool calls', async () => {
8673
const response = await provider.generateText({
8774
messages: [

packages/agent/src/core/llm/provider.ts

Lines changed: 49 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -35,41 +35,67 @@ export interface LLMProvider {
3535
generateText(options: GenerateOptions): Promise<LLMResponse>;
3636
}
3737

38+
export type ProviderConfig = {
39+
keyName?: string;
40+
docsUrl?: string;
41+
baseUrl?: string;
42+
model: string;
43+
factory: (model: string, options: ProviderOptions) => LLMProvider;
44+
};
45+
3846
// Provider factory registry
39-
const providerFactories: Record<
40-
string,
41-
(model: string, options: ProviderOptions) => LLMProvider
42-
> = {
43-
anthropic: (model, options) => new AnthropicProvider(model, options),
44-
openai: (model, options) => new OpenAIProvider(model, options),
45-
ollama: (model, options) => new OllamaProvider(model, options),
47+
export const providerConfig: Record<string, ProviderConfig> = {
48+
anthropic: {
49+
keyName: 'ANTHROPIC_API_KEY',
50+
docsUrl: 'https://mycoder.ai/docs/provider/anthropic',
51+
model: 'claude-3-7-sonnet-20250219',
52+
factory: (model, options) => new AnthropicProvider(model, options),
53+
},
54+
openai: {
55+
keyName: 'OPENAI_API_KEY',
56+
docsUrl: 'https://mycoder.ai/docs/provider/openai',
57+
model: 'gpt-4o-2024-05-13',
58+
factory: (model, options) => new OpenAIProvider(model, options),
59+
},
60+
gpustack: {
61+
docsUrl: 'https://mycoder.ai/docs/provider/local-openai',
62+
model: 'llama3.2',
63+
baseUrl: 'http://localhost:80',
64+
factory: (model, options) => new OpenAIProvider(model, options),
65+
},
66+
ollama: {
67+
docsUrl: 'https://mycoder.ai/docs/provider/ollama',
68+
model: 'llama3.2',
69+
baseUrl: 'http://localhost:11434',
70+
factory: (model, options) => new OllamaProvider(model, options),
71+
},
72+
xai: {
73+
keyName: 'XAI_API_KEY',
74+
docsUrl: 'https://mycoder.ai/docs/provider/xai',
75+
baseUrl: 'https://api.x.ai/v1',
76+
model: 'grok-2-latest',
77+
factory: (model, options) => new OpenAIProvider(model, options),
78+
},
4679
};
4780

4881
/**
4982
* Create a provider instance
5083
*/
5184
export function createProvider(
52-
providerType: string,
53-
model: string,
85+
provider: string,
86+
model?: string,
5487
options: ProviderOptions = {},
5588
): LLMProvider {
56-
const factory = providerFactories[providerType.toLowerCase()];
89+
const config = providerConfig[provider];
5790

58-
if (!factory) {
91+
if (!config) {
5992
throw new Error(
60-
`Provider '${providerType}' not found. Available providers: ${Object.keys(providerFactories).join(', ')}`,
93+
`Provider '${provider}' not found. Available providers: ${Object.keys(providerConfig).join(', ')}`,
6194
);
6295
}
6396

64-
return factory(model, options);
65-
}
66-
67-
/**
68-
* Register a new provider implementation
69-
*/
70-
export function registerProvider(
71-
providerType: string,
72-
factory: (model: string, options: ProviderOptions) => LLMProvider,
73-
): void {
74-
providerFactories[providerType.toLowerCase()] = factory;
97+
return config.factory(model ?? config.model, {
98+
...options,
99+
baseUrl: options.baseUrl ?? config.baseUrl,
100+
});
75101
}

packages/agent/src/core/llm/providers/anthropic.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ export class AnthropicProvider implements LLMProvider {
103103

104104
constructor(model: string, options: AnthropicOptions = {}) {
105105
this.model = model;
106-
this.apiKey = options.apiKey || process.env.ANTHROPIC_API_KEY || '';
106+
this.apiKey = options.apiKey ?? '';
107107
this.baseUrl = options.baseUrl;
108108

109109
if (!this.apiKey) {

packages/agent/src/core/llm/providers/ollama.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,6 @@ export class OllamaProvider implements LLMProvider {
170170
}
171171

172172
return response.message.tool_calls.map((toolCall: OllamaTooCall) => {
173-
//console.log('ollama tool call', toolCall);
174173
return {
175174
id: `tool-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`,
176175
name: toolCall.function?.name,

packages/agent/src/core/llm/providers/openai.ts

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,19 +42,13 @@ export class OpenAIProvider implements LLMProvider {
4242

4343
constructor(model: string, options: OpenAIOptions = {}) {
4444
this.model = model;
45-
this.apiKey = options.apiKey || process.env.OPENAI_API_KEY || '';
45+
this.apiKey = options.apiKey ?? '';
4646
this.baseUrl = options.baseUrl;
47-
this.organization = options.organization || process.env.OPENAI_ORGANIZATION;
48-
49-
if (!this.apiKey) {
50-
throw new Error('OpenAI API key is required');
51-
}
5247

5348
// Initialize OpenAI client
5449
this.client = new OpenAI({
5550
apiKey: this.apiKey,
5651
...(this.baseUrl && { baseURL: this.baseUrl }),
57-
...(this.organization && { organization: this.organization }),
5852
});
5953
}
6054

packages/agent/src/core/toolAgent/config.test.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ import { describe, expect, it } from 'vitest';
22

33
import { createProvider } from '../llm/provider.js';
44

5-
import { getModel } from './config.js';
6-
75
describe('createProvider', () => {
86
it('should return the correct model for anthropic', () => {
97
const model = createProvider('anthropic', 'claude-3-7-sonnet-20250219', {
@@ -27,7 +25,7 @@ describe('createProvider', () => {
2725
});
2826

2927
it('should return the correct model for ollama with custom base URL', () => {
30-
const model = getModel('ollama', 'llama3', {
28+
const model = createProvider('ollama', 'llama3', {
3129
ollamaBaseUrl: 'http://custom-ollama:11434',
3230
});
3331
expect(model).toBeDefined();

packages/agent/src/core/toolAgent/config.ts

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import * as fs from 'fs';
22
import * as os from 'os';
33
import * as path from 'path';
44

5-
import { createProvider, LLMProvider } from '../llm/provider.js';
65
import { ToolContext } from '../types';
76

87
/**
@@ -18,34 +17,6 @@ export type AgentConfig = {
1817
getSystemPrompt: (toolContext: ToolContext) => string;
1918
};
2019

21-
/**
22-
* Get the model instance based on provider and model name
23-
*/
24-
export function getModel(
25-
provider: ModelProvider,
26-
model: string,
27-
options?: { ollamaBaseUrl?: string },
28-
): LLMProvider {
29-
switch (provider) {
30-
case 'anthropic':
31-
return createProvider('anthropic', model);
32-
case 'openai':
33-
return createProvider('openai', model);
34-
case 'ollama':
35-
if (options?.ollamaBaseUrl) {
36-
return createProvider('ollama', model, {
37-
baseUrl: options.ollamaBaseUrl,
38-
});
39-
}
40-
return createProvider('ollama', model);
41-
/*case 'xai':
42-
return createProvider('xai', model);
43-
case 'mistral':
44-
return createProvider('mistral', model);*/
45-
default:
46-
throw new Error(`Unknown model provider: ${provider}`);
47-
}
48-
}
4920
/**
5021
* Default configuration for the tool agent
5122
*/

0 commit comments

Comments
 (0)
0