Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitc27eeea

Browse files
kylecarbsjohnstcn
authored andcommitted
And we have chat!
1 parent3d8f390 commitc27eeea

27 files changed

+2902
-305
lines changed

‎cli/server.go‎

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ import (
6161
"github.com/coder/serpent"
6262
"github.com/coder/wgtunnel/tunnelsdk"
6363

64+
"github.com/coder/coder/v2/coderd/ai"
6465
"github.com/coder/coder/v2/coderd/entitlements"
6566
"github.com/coder/coder/v2/coderd/notifications/reports"
6667
"github.com/coder/coder/v2/coderd/runtimeconfig"
@@ -610,6 +611,22 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd.
610611
)
611612
}
612613

614+
aiProviders,err:=ReadAIProvidersFromEnv(os.Environ())
615+
iferr!=nil {
616+
returnxerrors.Errorf("read ai providers from env: %w",err)
617+
}
618+
vals.AI.Value.Providers=append(vals.AI.Value.Providers,aiProviders...)
619+
for_,provider:=rangeaiProviders {
620+
logger.Debug(
621+
ctx,"loaded ai provider",
622+
slog.F("type",provider.Type),
623+
)
624+
}
625+
languageModels,err:=ai.ModelsFromConfig(ctx,vals.AI.Value.Providers)
626+
iferr!=nil {
627+
returnxerrors.Errorf("create language models: %w",err)
628+
}
629+
613630
realIPConfig,err:=httpmw.ParseRealIPConfig(vals.ProxyTrustedHeaders,vals.ProxyTrustedOrigins)
614631
iferr!=nil {
615632
returnxerrors.Errorf("parse real ip config: %w",err)
@@ -640,6 +657,7 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd.
640657
CacheDir:cacheDir,
641658
GoogleTokenValidator:googleTokenValidator,
642659
ExternalAuthConfigs:externalAuthConfigs,
660+
LanguageModels:languageModels,
643661
RealIPConfig:realIPConfig,
644662
SSHKeygenAlgorithm:sshKeygenAlgorithm,
645663
TracerProvider:tracerProvider,
@@ -2666,6 +2684,29 @@ func ReadAIProvidersFromEnv(environ []string) ([]codersdk.AIProviderConfig, erro
26662684
}
26672685
providers[providerNum]=provider
26682686
}
2687+
for_,envVar:=rangeenviron {
2688+
tokens:=strings.SplitN(envVar,"=",2)
2689+
iflen(tokens)!=2 {
2690+
continue
2691+
}
2692+
switchtokens[0] {
2693+
case"OPENAI_API_KEY":
2694+
providers=append(providers, codersdk.AIProviderConfig{
2695+
Type:"openai",
2696+
APIKey:tokens[1],
2697+
})
2698+
case"ANTHROPIC_API_KEY":
2699+
providers=append(providers, codersdk.AIProviderConfig{
2700+
Type:"anthropic",
2701+
APIKey:tokens[1],
2702+
})
2703+
case"GOOGLE_API_KEY":
2704+
providers=append(providers, codersdk.AIProviderConfig{
2705+
Type:"google",
2706+
APIKey:tokens[1],
2707+
})
2708+
}
2709+
}
26692710
returnproviders,nil
26702711
}
26712712

‎coderd/ai/ai.go‎

Lines changed: 133 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,140 @@ package ai
22

33
import (
44
"context"
5+
"fmt"
56

7+
"github.com/anthropics/anthropic-sdk-go"
8+
anthropicoption"github.com/anthropics/anthropic-sdk-go/option"
9+
"github.com/coder/coder/v2/codersdk"
610
"github.com/kylecarbs/aisdk-go"
11+
"github.com/openai/openai-go"
12+
openaioption"github.com/openai/openai-go/option"
13+
"google.golang.org/genai"
714
)
815

9-
typeProviderfunc(ctx context.Context,messages []aisdk.Message) (aisdk.DataStream,error)
16+
typeLanguageModelstruct {
17+
codersdk.LanguageModel
18+
StreamFuncStreamFunc
19+
}
20+
21+
typeStreamOptionsstruct {
22+
Modelstring
23+
Messages []aisdk.Message
24+
Thinkingbool
25+
Tools []aisdk.Tool
26+
}
27+
28+
typeStreamFuncfunc(ctx context.Context,optionsStreamOptions) (aisdk.DataStream,error)
29+
30+
// LanguageModels is a map of language model ID to language model.
31+
typeLanguageModelsmap[string]LanguageModel
32+
33+
funcModelsFromConfig(ctx context.Context,configs []codersdk.AIProviderConfig) (LanguageModels,error) {
34+
models:=make(LanguageModels)
35+
36+
for_,config:=rangeconfigs {
37+
varstreamFuncStreamFunc
38+
39+
switchconfig.Type {
40+
case"openai":
41+
client:=openai.NewClient(openaioption.WithAPIKey(config.APIKey))
42+
streamFunc=func(ctx context.Context,optionsStreamOptions) (aisdk.DataStream,error) {
43+
openaiMessages,err:=aisdk.MessagesToOpenAI(options.Messages)
44+
iferr!=nil {
45+
returnnil,err
46+
}
47+
tools:=aisdk.ToolsToOpenAI(options.Tools)
48+
returnaisdk.OpenAIToDataStream(client.Chat.Completions.NewStreaming(ctx, openai.ChatCompletionNewParams{
49+
Messages:openaiMessages,
50+
Model:options.Model,
51+
Tools:tools,
52+
MaxTokens:openai.Int(8192),
53+
})),nil
54+
}
55+
ifconfig.Models==nil {
56+
models,err:=client.Models.List(ctx)
57+
iferr!=nil {
58+
returnnil,err
59+
}
60+
config.Models=make([]string,len(models.Data))
61+
fori,model:=rangemodels.Data {
62+
config.Models[i]=model.ID
63+
}
64+
}
65+
break
66+
case"anthropic":
67+
client:=anthropic.NewClient(anthropicoption.WithAPIKey(config.APIKey))
68+
streamFunc=func(ctx context.Context,optionsStreamOptions) (aisdk.DataStream,error) {
69+
anthropicMessages,systemMessage,err:=aisdk.MessagesToAnthropic(options.Messages)
70+
iferr!=nil {
71+
returnnil,err
72+
}
73+
returnaisdk.AnthropicToDataStream(client.Messages.NewStreaming(ctx, anthropic.MessageNewParams{
74+
Messages:anthropicMessages,
75+
Model:options.Model,
76+
System:systemMessage,
77+
Tools:aisdk.ToolsToAnthropic(options.Tools),
78+
MaxTokens:8192,
79+
})),nil
80+
}
81+
ifconfig.Models==nil {
82+
models,err:=client.Models.List(ctx, anthropic.ModelListParams{})
83+
iferr!=nil {
84+
returnnil,err
85+
}
86+
config.Models=make([]string,len(models.Data))
87+
fori,model:=rangemodels.Data {
88+
config.Models[i]=model.ID
89+
}
90+
}
91+
break
92+
case"google":
93+
client,err:=genai.NewClient(ctx,&genai.ClientConfig{
94+
APIKey:config.APIKey,
95+
Backend:genai.BackendGeminiAPI,
96+
})
97+
iferr!=nil {
98+
returnnil,err
99+
}
100+
streamFunc=func(ctx context.Context,optionsStreamOptions) (aisdk.DataStream,error) {
101+
googleMessages,err:=aisdk.MessagesToGoogle(options.Messages)
102+
iferr!=nil {
103+
returnnil,err
104+
}
105+
tools,err:=aisdk.ToolsToGoogle(options.Tools)
106+
iferr!=nil {
107+
returnnil,err
108+
}
109+
returnaisdk.GoogleToDataStream(client.Models.GenerateContentStream(ctx,options.Model,googleMessages,&genai.GenerateContentConfig{
110+
Tools:tools,
111+
})),nil
112+
}
113+
ifconfig.Models==nil {
114+
models,err:=client.Models.List(ctx,&genai.ListModelsConfig{})
115+
iferr!=nil {
116+
returnnil,err
117+
}
118+
config.Models=make([]string,len(models.Items))
119+
fori,model:=rangemodels.Items {
120+
config.Models[i]=model.Name
121+
}
122+
}
123+
break
124+
default:
125+
returnnil,fmt.Errorf("unsupported model type: %s",config.Type)
126+
}
127+
128+
for_,model:=rangeconfig.Models {
129+
models[model]=LanguageModel{
130+
LanguageModel: codersdk.LanguageModel{
131+
ID:model,
132+
DisplayName:model,
133+
Provider:config.Type,
134+
},
135+
StreamFunc:streamFunc,
136+
}
137+
}
138+
}
139+
140+
returnmodels,nil
141+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp