Skip to content
Open
2 changes: 1 addition & 1 deletion .agents/base2/base2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export function createBase2(
? 'z-ai/glm-4.6:nitro'
: 'anthropic/claude-sonnet-4.5',
...(isGpt5 && {
reasoningModel: {
reasoningOptions: {
effort: 'high',
},
}),
Expand Down
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# AI API Keys
CLAUDE_CODE_KEY=dummy_claude_code_key
OPEN_ROUTER_API_KEY=dummy_openrouter_key
OPENAI_API_KEY=dummy_openai_key

# Database & Server
DATABASE_URL=postgresql://manicode_user_local:secretpassword_local@localhost:5432/manicode_db_local
Expand Down
11 changes: 10 additions & 1 deletion bun.lock
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@
"name": "@codebuff/internal",
"version": "1.0.0",
"dependencies": {
"@ai-sdk/provider-utils": "3.0.17",
"@codebuff/common": "workspace:*",
"drizzle-orm": "*",
"loops": "^5.0.1",
Expand Down Expand Up @@ -436,7 +437,7 @@

"@ai-sdk/provider": ["@ai-sdk/provider@2.0.0", "", { "dependencies": { "json-schema": "^0.4.0" } }, "sha512-6o7Y2SeO9vFKB8lArHXehNuusnpddKPk7xqL7T2/b+OvXMRIXUO1rR4wcv1hAFUAT9avGZshty3Wlua/XA7TvA=="],

"@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@3.0.2", "", { "dependencies": { "@ai-sdk/provider": "2.0.0", "@standard-schema/spec": "^1.0.0", "eventsource-parser": "^3.0.3", "zod-to-json-schema": "^3.24.1" }, "peerDependencies": { "zod": "^3.25.76 || ^4" } }, "sha512-0a5a6VafkV6+0irdpqnub8WE6qzG2VMsDBpXb9NQIz8c4TG8fI+GSTFIL9sqrLEwXrHdiRj7fwJsrir4jClL0w=="],
"@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@3.0.17", "", { "dependencies": { "@ai-sdk/provider": "2.0.0", "@standard-schema/spec": "^1.0.0", "eventsource-parser": "^3.0.6" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-TR3Gs4I3Tym4Ll+EPdzRdvo/rc8Js6c4nVhFLuvGLX/Y4V9ZcQMa/HTiYsHEgmYrf1zVi6Q145UEZUfleOwOjw=="],

"@alloc/quick-lru": ["@alloc/quick-lru@5.2.0", "", {}, "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw=="],

Expand Down Expand Up @@ -4078,8 +4079,16 @@

"zwitch": ["zwitch@2.0.4", "", {}, "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A=="],

"@ai-sdk/anthropic/@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@3.0.2", "", { "dependencies": { "@ai-sdk/provider": "2.0.0", "@standard-schema/spec": "^1.0.0", "eventsource-parser": "^3.0.3", "zod-to-json-schema": "^3.24.1" }, "peerDependencies": { "zod": "^3.25.76 || ^4" } }, "sha512-0a5a6VafkV6+0irdpqnub8WE6qzG2VMsDBpXb9NQIz8c4TG8fI+GSTFIL9sqrLEwXrHdiRj7fwJsrir4jClL0w=="],

"@ai-sdk/gateway/@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@3.0.0", "", { "dependencies": { "@ai-sdk/provider": "2.0.0", "@standard-schema/spec": "^1.0.0", "eventsource-parser": "^3.0.3", "zod-to-json-schema": "^3.24.1" }, "peerDependencies": { "zod": "^3.25.76 || ^4" } }, "sha512-BoQZtGcBxkeSH1zK+SRYNDtJPIPpacTeiMZqnG4Rv6xXjEwM0FH4MGs9c+PlhyEWmQCzjRM2HAotEydFhD4dYw=="],

"@ai-sdk/google/@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@3.0.2", "", { "dependencies": { "@ai-sdk/provider": "2.0.0", "@standard-schema/spec": "^1.0.0", "eventsource-parser": "^3.0.3", "zod-to-json-schema": "^3.24.1" }, "peerDependencies": { "zod": "^3.25.76 || ^4" } }, "sha512-0a5a6VafkV6+0irdpqnub8WE6qzG2VMsDBpXb9NQIz8c4TG8fI+GSTFIL9sqrLEwXrHdiRj7fwJsrir4jClL0w=="],

"@ai-sdk/google-vertex/@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@3.0.2", "", { "dependencies": { "@ai-sdk/provider": "2.0.0", "@standard-schema/spec": "^1.0.0", "eventsource-parser": "^3.0.3", "zod-to-json-schema": "^3.24.1" }, "peerDependencies": { "zod": "^3.25.76 || ^4" } }, "sha512-0a5a6VafkV6+0irdpqnub8WE6qzG2VMsDBpXb9NQIz8c4TG8fI+GSTFIL9sqrLEwXrHdiRj7fwJsrir4jClL0w=="],

"@ai-sdk/openai/@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@3.0.2", "", { "dependencies": { "@ai-sdk/provider": "2.0.0", "@standard-schema/spec": "^1.0.0", "eventsource-parser": "^3.0.3", "zod-to-json-schema": "^3.24.1" }, "peerDependencies": { "zod": "^3.25.76 || ^4" } }, "sha512-0a5a6VafkV6+0irdpqnub8WE6qzG2VMsDBpXb9NQIz8c4TG8fI+GSTFIL9sqrLEwXrHdiRj7fwJsrir4jClL0w=="],

"@ai-sdk/openai-compatible/@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@3.0.15", "", { "dependencies": { "@ai-sdk/provider": "2.0.0", "@standard-schema/spec": "^1.0.0", "eventsource-parser": "^3.0.6" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-kOc6Pxb7CsRlNt+sLZKL7/VGQUd7ccl3/tIK+Bqf5/QhHR0Qm3qRBMz1IwU1RmjJEZA73x+KB5cUckbDl2WF7Q=="],

"@auth/core/jose": ["jose@6.1.0", "", {}, "sha512-TTQJyoEoKcC1lscpVDCSsVgYzUDg/0Bt3WE//WiTPK6uOCQC2KZS4MpugbMWt/zyjkopgZoXhZuCi00gLudfUA=="],
Expand Down
1 change: 1 addition & 0 deletions packages/internal/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
"bun": "^1.3.0"
},
"dependencies": {
"@ai-sdk/provider-utils": "3.0.17",
"@codebuff/common": "workspace:*",
"drizzle-orm": "*",
"loops": "^5.0.1"
Expand Down
2 changes: 2 additions & 0 deletions packages/internal/src/env-schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export const serverEnvSchema = clientEnvSchema.extend({
// Backend variables
CODEBUFF_API_KEY: z.string().optional(),
OPEN_ROUTER_API_KEY: z.string().min(1),
OPENAI_API_KEY: z.string().min(1),
RELACE_API_KEY: z.string().min(1),
LINKUP_API_KEY: z.string().min(1),
CONTEXT7_API_KEY: z.string().optional(),
Expand Down Expand Up @@ -44,6 +45,7 @@ export const serverProcessEnv: ServerInput = {
// Backend variables
CODEBUFF_API_KEY: process.env.CODEBUFF_API_KEY,
OPEN_ROUTER_API_KEY: process.env.OPEN_ROUTER_API_KEY,
OPENAI_API_KEY: process.env.OPENAI_API_KEY,
RELACE_API_KEY: process.env.RELACE_API_KEY,
LINKUP_API_KEY: process.env.LINKUP_API_KEY,
CONTEXT7_API_KEY: process.env.CONTEXT7_API_KEY,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import {
FetchFunction,
withoutTrailingSlash,
withUserAgentSuffix,
getRuntimeEnvironmentUserAgent,
} from '@ai-sdk/provider-utils';
import {
OpenAICompatibleChatConfig,
Expand Down
5 changes: 4 additions & 1 deletion sdk/src/impl/llm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,15 +63,18 @@ function getProviderOptions(params: {
model: string
runId: string
clientSessionId: string
providerOptions?: Record<string, JSONObject>
}): { codebuff: JSONObject } {
const { model, runId, clientSessionId } = params
const { model, runId, clientSessionId, providerOptions } = params

// Set allow_fallbacks based on whether model is explicitly defined
const isExplicitlyDefined = isExplicitlyDefinedModel(model)

return {
...providerOptions,
// Could either be "codebuff" or "openaiCompatible"
codebuff: {
...providerOptions?.codebuff,
// All values here get appended to the request body
codebuff_metadata: {
run_id: runId,
Expand Down
33 changes: 25 additions & 8 deletions web/src/app/api/v1/chat/completions/_post.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
handleOpenRouterNonStream,
handleOpenRouterStream,
} from '@/llm-api/openrouter'
import { handleOpenAIStream, OPENAI_SUPPORTED_MODELS } from '@/llm-api/openai'
import { extractApiKeyFromHeader } from '@/util/auth'

export async function postChatCompletions(params: {
Expand Down Expand Up @@ -204,14 +205,30 @@ export async function postChatCompletions(params: {
try {
if (bodyStream) {
// Streaming request
const stream = await handleOpenRouterStream({
body,
userId,
agentId,
fetch,
logger,
insertMessageBigquery,
})
const model = (body as any)?.model
const shortModelName =
typeof model === 'string' ? model.split('/')[1] : undefined
const isOpenAIDirectModel =
typeof model === 'string' &&
model.startsWith('openai/') &&
OPENAI_SUPPORTED_MODELS.includes(shortModelName as any)
const stream = await (isOpenAIDirectModel
? handleOpenAIStream({
body,
userId,
agentId,
fetch,
logger,
insertMessageBigquery,
})
: handleOpenRouterStream({
body,
userId,
agentId,
fetch,
logger,
insertMessageBigquery,
}))

trackEvent({
event: AnalyticsEvent.CHAT_COMPLETIONS_STREAM_STARTED,
Expand Down
Loading
Loading