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
11 changes: 9 additions & 2 deletions llm/ai-sdk/provider/stripe-language-model-v3.ts
Original file line number Diff line number Diff line change
Expand Up @@ -185,15 +185,22 @@ export class StripeLanguageModelV3 implements LanguageModelV3 {

const model = modelId.substring('anthropic/'.length);

// Check both dash-form (claude-3-7-sonnet) and dot-form (claude-3.7-sonnet)
// since normalizeModelId converts version dashes to dots
if (
model.includes('sonnet-4') ||
model.includes('claude-3-7-sonnet') ||
model.includes('haiku-4-5')
model.includes('claude-3.7-sonnet') ||
model.includes('haiku-4-5') ||
model.includes('haiku-4.5')
) {
return 64000;
} else if (model.includes('opus-4')) {
return 32000;
} else if (model.includes('claude-3-5-haiku')) {
} else if (
model.includes('claude-3-5-haiku') ||
model.includes('claude-3.5-haiku')
) {
return 8192;
} else {
return 4096;
Expand Down
20 changes: 13 additions & 7 deletions llm/ai-sdk/provider/stripe-language-model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,19 +208,25 @@ export class StripeLanguageModel implements LanguageModelV2 {
const model = modelId.substring('anthropic/'.length);

// Claude Sonnet 4 models (including variants like sonnet-4-1) and 3.7 Sonnet
if (model.includes('sonnet-4') ||
model.includes('claude-3-7-sonnet') ||
model.includes('haiku-4-5')) {
// Check both dash-form (claude-3-7-sonnet) and dot-form (claude-3.7-sonnet)
// since normalizeModelId converts version dashes to dots
if (model.includes('sonnet-4') ||
model.includes('claude-3-7-sonnet') ||
model.includes('claude-3.7-sonnet') ||
model.includes('haiku-4-5') ||
model.includes('haiku-4.5')) {
return 64000; // 64K tokens
}
}
// Claude Opus 4 models (including variants like opus-4-1)
else if (model.includes('opus-4')) {
return 32000; // 32K tokens
}
}
// Claude 3.5 Haiku
else if (model.includes('claude-3-5-haiku')) {
// Check both dash-form (claude-3-5-haiku) and dot-form (claude-3.5-haiku)
else if (model.includes('claude-3-5-haiku') ||
model.includes('claude-3.5-haiku')) {
return 8192; // 8K tokens
}
}
// Default fallback for other Anthropic models
else {
return 4096;
Expand Down
58 changes: 58 additions & 0 deletions llm/ai-sdk/provider/tests/stripe-language-model-v3.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,64 @@ describe('StripeLanguageModelV3', () => {
expect(args.max_tokens).toBeUndefined();
});

it('should apply correct defaults for normalized (dot-form) model IDs', () => {
const testCases = [
{modelId: 'anthropic/claude-3.7-sonnet', expected: 64000},
{modelId: 'anthropic/claude-3.5-haiku', expected: 8192},
{modelId: 'anthropic/claude-haiku-4.5', expected: 64000},
{modelId: 'anthropic/claude-opus-4', expected: 32000},
{modelId: 'anthropic/claude-sonnet-4', expected: 64000},
];

testCases.forEach(({modelId, expected}) => {
const m = new StripeLanguageModelV3(
modelId,
{customerId: 'cus_test'},
{
provider: 'stripe',
baseURL: 'https://llm.stripe.com',
headers: () => ({}),
}
);

const options: LanguageModelV3CallOptions = {
prompt: [],
};

// @ts-expect-error - Accessing private method for testing
const {args} = m.getArgs(options);
expect(args.max_tokens).toBe(expected);
});
});

it('should apply correct defaults for dash-form model IDs (pre-normalization)', () => {
const testCases = [
{modelId: 'anthropic/claude-3-7-sonnet', expected: 64000},
{modelId: 'anthropic/claude-3-5-haiku', expected: 8192},
{modelId: 'anthropic/claude-haiku-4-5', expected: 64000},
];

testCases.forEach(({modelId, expected}) => {
const m = new StripeLanguageModelV3(
modelId,
{customerId: 'cus_test'},
{
provider: 'stripe',
baseURL: 'https://llm.stripe.com',
headers: () => ({}),
}
);

const options: LanguageModelV3CallOptions = {
prompt: [],
};

// @ts-expect-error - Accessing private method for testing
const {args} = m.getArgs(options);
expect(args.max_tokens).toBe(expected);
});
});

it('should allow user-provided maxOutputTokens to override default', () => {
const sonnetModel = new StripeLanguageModelV3(
'anthropic/claude-sonnet-4',
Expand Down
59 changes: 59 additions & 0 deletions llm/ai-sdk/provider/tests/stripe-language-model.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,65 @@ describe('StripeLanguageModel', () => {
expect(args.max_tokens).toBeUndefined();
});

it('should apply correct defaults for normalized (dot-form) model IDs', () => {
// These are the IDs that normalizeModelId produces
const testCases = [
{modelId: 'anthropic/claude-3.7-sonnet', expected: 64000},
{modelId: 'anthropic/claude-3.5-haiku', expected: 8192},
{modelId: 'anthropic/claude-haiku-4.5', expected: 64000},
{modelId: 'anthropic/claude-opus-4', expected: 32000},
{modelId: 'anthropic/claude-sonnet-4', expected: 64000},
];

testCases.forEach(({modelId, expected}) => {
const m = new StripeLanguageModel(
modelId,
{customerId: 'cus_test'},
{
provider: 'stripe',
baseURL: 'https://llm.stripe.com',
headers: () => ({}),
}
);

const options: LanguageModelV2CallOptions = {
prompt: [],
};

// @ts-expect-error - Accessing private method for testing
const {args} = m.getArgs(options);
expect(args.max_tokens).toBe(expected);
});
});

it('should apply correct defaults for dash-form model IDs (pre-normalization)', () => {
const testCases = [
{modelId: 'anthropic/claude-3-7-sonnet', expected: 64000},
{modelId: 'anthropic/claude-3-5-haiku', expected: 8192},
{modelId: 'anthropic/claude-haiku-4-5', expected: 64000},
];

testCases.forEach(({modelId, expected}) => {
const m = new StripeLanguageModel(
modelId,
{customerId: 'cus_test'},
{
provider: 'stripe',
baseURL: 'https://llm.stripe.com',
headers: () => ({}),
}
);

const options: LanguageModelV2CallOptions = {
prompt: [],
};

// @ts-expect-error - Accessing private method for testing
const {args} = m.getArgs(options);
expect(args.max_tokens).toBe(expected);
});
});

it('should allow user-provided maxOutputTokens to override default', () => {
const sonnetModel = new StripeLanguageModel(
'anthropic/claude-sonnet-4',
Expand Down
Loading