Skip to content
Open
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
42 changes: 42 additions & 0 deletions src/providers/oracle/chatComplete.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { OracleChatCompleteConfig } from './chatComplete';

const buildChatRequest = (model: string, params: any = {}) => {
const cfg = (OracleChatCompleteConfig.model as any[])[0];
return cfg.transform(
{ model, messages: [{ role: 'user', content: 'hi' }], ...params },
{ oracleCompartmentId: 'ocid1.compartment.oc1..test' }
);
};

describe('Oracle chat — GPT-5 maxCompletionTokens routing', () => {
it('routes maxTokens → maxCompletionTokens for openai.gpt-5', () => {
const req = buildChatRequest('openai.gpt-5', { max_tokens: 200 });
expect(req.maxTokens).toBeUndefined();
expect(req.maxCompletionTokens).toBe(200);
});

it('routes maxTokens → maxCompletionTokens for gpt-5 variants (e.g. gpt-5-mini)', () => {
const req = buildChatRequest('openai.gpt-5-mini', { max_tokens: 64 });
expect(req.maxTokens).toBeUndefined();
expect(req.maxCompletionTokens).toBe(64);
});

it('keeps maxTokens for non-GPT-5 models (gpt-4o)', () => {
const req = buildChatRequest('openai.gpt-4o', { max_tokens: 128 });
expect(req.maxTokens).toBe(128);
expect(req.maxCompletionTokens).toBeUndefined();
});

it('keeps maxTokens for Llama / Cohere / Grok / Gemini', () => {
for (const model of [
'meta.llama-3.3-70b-instruct',
'cohere.command-r-plus-08-2024',
'xai.grok-3-mini',
'google.gemini-2.5-flash',
]) {
const req = buildChatRequest(model, { max_tokens: 50 });
expect(req.maxTokens).toBe(50);
expect(req.maxCompletionTokens).toBeUndefined();
}
});
});
21 changes: 20 additions & 1 deletion src/providers/oracle/chatComplete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,37 @@ import {
} from './types/GenericChatResponse';
import { openAIToOracleRoleMap, oracleToOpenAIRoleMap } from './utils';

/**
* GPT-5+ models on OCI reject `maxTokens` and require `maxCompletionTokens`
* instead. Match the family inline so we can route the parameter correctly
* without dragging in a separate model-config module.
*/
const GPT5_FAMILY_PATTERN = /^openai\.gpt-5/i;

const usesMaxCompletionTokens = (model: string): boolean =>
GPT5_FAMILY_PATTERN.test(model);

// transforms from openai format to oracle format for chat completions request
export const OracleChatCompleteConfig: ProviderConfig = {
model: [
{
param: 'chatRequest',
required: true,
transform: (params: Params, providerOptions: Options) => {
return transformUsingProviderConfig(
const chatRequest = transformUsingProviderConfig(
OracleChatDetailsConfig,
params,
providerOptions
);

if (usesMaxCompletionTokens(params.model || '')) {
if ('maxTokens' in chatRequest) {
(chatRequest as any).maxCompletionTokens = chatRequest.maxTokens;
delete chatRequest.maxTokens;
}
}

return chatRequest;
},
},
{
Expand Down