feat: use AI provider chat APIs (#25415)

This commit is contained in:
Michael Suchacz
2026-05-22 07:53:23 +02:00
committed by GitHub
parent 10efde3e6c
commit 06526a5822
41 changed files with 2195 additions and 1126 deletions
+69 -124
View File
@@ -24,6 +24,47 @@ import (
"github.com/coder/websocket"
)
func createOpenAIProviderForTest(
ctx context.Context,
t testing.TB,
client *codersdk.ExperimentalClient,
apiKey string,
baseURL string,
) codersdk.AIProvider {
t.Helper()
provider, err := client.CreateAIProvider(ctx, codersdk.CreateAIProviderRequest{
Type: codersdk.AIProviderTypeOpenAI,
Name: "openai-" + uuid.NewString(),
DisplayName: "OpenAI",
Enabled: true,
BaseURL: baseURL,
APIKeys: []string{apiKey},
})
require.NoError(t, err)
return provider
}
func createOpenAIModelConfigForTest(
ctx context.Context,
t testing.TB,
client *codersdk.ExperimentalClient,
apiKey string,
baseURL string,
) codersdk.ChatModelConfig {
t.Helper()
provider := createOpenAIProviderForTest(ctx, t, client, apiKey, baseURL)
model, err := client.CreateChatModelConfig(ctx, codersdk.CreateChatModelConfigRequest{
Provider: string(provider.Type),
AIProviderID: &provider.ID,
Model: "gpt-4",
DisplayName: "GPT-4",
ContextLimit: ptr.Ref(int64(1000)),
CompressionThreshold: ptr.Ref(int32(70)),
})
require.NoError(t, err)
return model
}
func TestChatStreamRelay(t *testing.T) {
t.Parallel()
@@ -74,27 +115,11 @@ func TestChatStreamRelay(t *testing.T) {
return chattest.OpenAINonStreamingResponse("ok")
})
//nolint:gocritic // Test uses owner client to configure chat providers.
provider, err := codersdk.NewExperimentalClient(firstClient).CreateChatProvider(ctx, codersdk.CreateChatProviderConfigRequest{
Provider: "openai",
DisplayName: "OpenAI",
APIKey: "test",
BaseURL: openai,
})
require.NoError(t, err)
require.Equal(t, codersdk.ChatProviderConfigSourceDatabase, provider.Source)
model, err := codersdk.NewExperimentalClient(firstClient).CreateChatModelConfig(ctx, codersdk.CreateChatModelConfigRequest{
Provider: provider.Provider,
Model: "gpt-4",
DisplayName: "GPT-4",
ContextLimit: &[]int64{1000}[0],
CompressionThreshold: &[]int32{70}[0],
})
require.NoError(t, err)
expClient := codersdk.NewExperimentalClient(firstClient)
model := createOpenAIModelConfigForTest(ctx, t, expClient, "test", openai)
// Create a chat on the first replica
chat, err := codersdk.NewExperimentalClient(firstClient).CreateChat(ctx, codersdk.CreateChatRequest{
chat, err := expClient.CreateChat(ctx, codersdk.CreateChatRequest{
OrganizationID: firstUser.OrganizationID,
Content: []codersdk.ChatInputPart{{
Type: codersdk.ChatInputPartTypeText,
@@ -264,26 +289,11 @@ func TestChatStreamRelay(t *testing.T) {
return chattest.OpenAINonStreamingResponse("ok")
})
//nolint:gocritic // Test uses owner client to configure chat providers.
provider, err := codersdk.NewExperimentalClient(firstClient).CreateChatProvider(ctx, codersdk.CreateChatProviderConfigRequest{
Provider: "openai",
DisplayName: "OpenAI",
APIKey: "test",
BaseURL: openai,
})
require.NoError(t, err)
model, err := codersdk.NewExperimentalClient(firstClient).CreateChatModelConfig(ctx, codersdk.CreateChatModelConfigRequest{
Provider: provider.Provider,
Model: "gpt-4",
DisplayName: "GPT-4",
ContextLimit: &[]int64{1000}[0],
CompressionThreshold: &[]int32{70}[0],
})
require.NoError(t, err)
expClient := codersdk.NewExperimentalClient(firstClient)
model := createOpenAIModelConfigForTest(ctx, t, expClient, "test", openai)
// Create a chat on the first replica.
chat, err := codersdk.NewExperimentalClient(firstClient).CreateChat(ctx, codersdk.CreateChatRequest{
chat, err := expClient.CreateChat(ctx, codersdk.CreateChatRequest{
OrganizationID: firstUser.OrganizationID,
Content: []codersdk.ChatInputPart{{
Type: codersdk.ChatInputPartTypeText,
@@ -435,25 +445,10 @@ func TestChatStreamRelay(t *testing.T) {
return chattest.OpenAINonStreamingResponse("ok")
})
//nolint:gocritic // Test uses owner client to configure providers.
provider, err := codersdk.NewExperimentalClient(firstClient).CreateChatProvider(ctx, codersdk.CreateChatProviderConfigRequest{
Provider: "openai",
DisplayName: "OpenAI",
APIKey: "test",
BaseURL: openai,
})
require.NoError(t, err)
expClient := codersdk.NewExperimentalClient(firstClient)
model := createOpenAIModelConfigForTest(ctx, t, expClient, "test", openai)
model, err := codersdk.NewExperimentalClient(firstClient).CreateChatModelConfig(ctx, codersdk.CreateChatModelConfigRequest{
Provider: provider.Provider,
Model: "gpt-4",
DisplayName: "GPT-4",
ContextLimit: &[]int64{1000}[0],
CompressionThreshold: &[]int32{70}[0],
})
require.NoError(t, err)
chat, err := codersdk.NewExperimentalClient(firstClient).CreateChat(ctx, codersdk.CreateChatRequest{
chat, err := expClient.CreateChat(ctx, codersdk.CreateChatRequest{
OrganizationID: firstUser.OrganizationID,
Content: []codersdk.ChatInputPart{{
Type: codersdk.ChatInputPartTypeText,
@@ -607,25 +602,10 @@ func TestChatStreamRelay(t *testing.T) {
return chattest.OpenAINonStreamingResponse("ok")
})
//nolint:gocritic // Test uses owner client to configure providers.
provider, err := codersdk.NewExperimentalClient(firstClient).CreateChatProvider(ctx, codersdk.CreateChatProviderConfigRequest{
Provider: "openai",
DisplayName: "OpenAI",
APIKey: "test",
BaseURL: openai,
})
require.NoError(t, err)
expClient := codersdk.NewExperimentalClient(firstClient)
model := createOpenAIModelConfigForTest(ctx, t, expClient, "test", openai)
model, err := codersdk.NewExperimentalClient(firstClient).CreateChatModelConfig(ctx, codersdk.CreateChatModelConfigRequest{
Provider: provider.Provider,
Model: "gpt-4",
DisplayName: "GPT-4",
ContextLimit: &[]int64{1000}[0],
CompressionThreshold: &[]int32{70}[0],
})
require.NoError(t, err)
chat, err := codersdk.NewExperimentalClient(firstClient).CreateChat(ctx, codersdk.CreateChatRequest{
chat, err := expClient.CreateChat(ctx, codersdk.CreateChatRequest{
OrganizationID: firstUser.OrganizationID,
Content: []codersdk.ChatInputPart{{
Type: codersdk.ChatInputPartTypeText,
@@ -754,26 +734,11 @@ func TestChatStreamRelay(t *testing.T) {
return chattest.OpenAINonStreamingResponse("ok")
})
//nolint:gocritic // Test uses owner client to configure chat providers.
provider, err := codersdk.NewExperimentalClient(firstClient).CreateChatProvider(ctx, codersdk.CreateChatProviderConfigRequest{
Provider: "openai",
DisplayName: "OpenAI",
APIKey: "test",
BaseURL: openai,
})
require.NoError(t, err)
model, err := codersdk.NewExperimentalClient(firstClient).CreateChatModelConfig(ctx, codersdk.CreateChatModelConfigRequest{
Provider: provider.Provider,
Model: "gpt-4",
DisplayName: "GPT-4",
ContextLimit: &[]int64{1000}[0],
CompressionThreshold: &[]int32{70}[0],
})
require.NoError(t, err)
expClient := codersdk.NewExperimentalClient(firstClient)
model := createOpenAIModelConfigForTest(ctx, t, expClient, "test", openai)
// Create a chat on the first replica.
chat, err := codersdk.NewExperimentalClient(firstClient).CreateChat(ctx, codersdk.CreateChatRequest{
chat, err := expClient.CreateChat(ctx, codersdk.CreateChatRequest{
OrganizationID: firstUser.OrganizationID,
Content: []codersdk.ChatInputPart{{
Type: codersdk.ChatInputPartTypeText,
@@ -954,17 +919,7 @@ func TestChatModelConfigDefault(t *testing.T) {
client, _ := coderdenttest.New(t, nil)
expClient := codersdk.NewExperimentalClient(client)
//nolint:gocritic // Test uses owner client to configure chat providers.
provider, err := expClient.CreateChatProvider(
ctx,
codersdk.CreateChatProviderConfigRequest{
Provider: "openai",
DisplayName: "OpenAI",
APIKey: "test",
BaseURL: "https://example.com",
},
)
require.NoError(t, err)
provider := createOpenAIProviderForTest(ctx, t, expClient, "test", "https://example.com")
contextLimit := int64(1000)
compressionThreshold := int32(70)
@@ -974,7 +929,8 @@ func TestChatModelConfigDefault(t *testing.T) {
firstModel, err := expClient.CreateChatModelConfig(
ctx,
codersdk.CreateChatModelConfigRequest{
Provider: provider.Provider,
Provider: string(provider.Type),
AIProviderID: &provider.ID,
Model: "gpt-5-a",
DisplayName: "GPT 5 A",
IsDefault: &trueValue,
@@ -988,7 +944,8 @@ func TestChatModelConfigDefault(t *testing.T) {
secondModel, err := expClient.CreateChatModelConfig(
ctx,
codersdk.CreateChatModelConfigRequest{
Provider: provider.Provider,
Provider: string(provider.Type),
AIProviderID: &provider.ID,
Model: "gpt-5-b",
DisplayName: "GPT 5 B",
IsDefault: &trueValue,
@@ -1115,16 +1072,10 @@ func TestCreateChatNonDefaultOrg(t *testing.T) {
})
expClient := codersdk.NewExperimentalClient(client)
// Set up a chat provider and model config.
provider, err := expClient.CreateChatProvider(ctx, codersdk.CreateChatProviderConfigRequest{
Provider: "openai",
DisplayName: "OpenAI",
APIKey: "test-key",
BaseURL: "https://example.com",
})
require.NoError(t, err)
_, err = expClient.CreateChatModelConfig(ctx, codersdk.CreateChatModelConfigRequest{
Provider: provider.Provider,
provider := createOpenAIProviderForTest(ctx, t, expClient, "test-key", "https://example.com")
_, err := expClient.CreateChatModelConfig(ctx, codersdk.CreateChatModelConfigRequest{
Provider: string(provider.Type),
AIProviderID: &provider.ID,
Model: "gpt-4o-mini",
DisplayName: "Test Model",
IsDefault: ptr.Ref(true),
@@ -1191,16 +1142,10 @@ func TestListChats_OrgAdminOnlySeesOwnChats(t *testing.T) {
})
expClient := codersdk.NewExperimentalClient(client)
// Set up a chat provider and model config.
provider, err := expClient.CreateChatProvider(ctx, codersdk.CreateChatProviderConfigRequest{
Provider: "openai",
DisplayName: "OpenAI",
APIKey: "test-key",
BaseURL: "https://example.com",
})
require.NoError(t, err)
_, err = expClient.CreateChatModelConfig(ctx, codersdk.CreateChatModelConfigRequest{
Provider: provider.Provider,
provider := createOpenAIProviderForTest(ctx, t, expClient, "test-key", "https://example.com")
_, err := expClient.CreateChatModelConfig(ctx, codersdk.CreateChatModelConfigRequest{
Provider: string(provider.Type),
AIProviderID: &provider.ID,
Model: "gpt-4o-mini",
DisplayName: "Test Model",
IsDefault: ptr.Ref(true),