Skip to content

Commit 3c29a0a

Browse files
authored
Merge pull request #211 from APIParkLab/feature/1.5-local-model
This pull request includes several changes aimed at improving error handling, adding new functionalities, and refactoring existing code. The changes primarily focus on the AI provider and controller modules. Error Handling Improvements: Added checks to ensure the client is initialized before performing operations in multiple functions (PullModel, StopPull, CancelPipeline, RemoveModel, ModelsInstalled) in ai-provider/local/executor.go. [1] [2] [3] [4] New Functionalities: Introduced OllamaConfig and OllamaConfigUpdate methods to the ILocalModelController interface and implemented them in controller/ai-local/iml.go. These methods allow for getting and updating the Ollama configuration. [1] [2] Added functionality to automatically subscribe all applications to new services in the Create method of controller/service/iml.go. Refactoring: Refactored the initialization of the Ollama client by replacing the static address with a ResetOllamaAddress function in ai-provider/local/local.go. Removed unused code and imports, such as the newAIUpstream function and upstream_dto import in controller/service/iml.go. [1] [2] Codebase Simplification: Simplified the OnInit method in controller/system/iml.go by consolidating the creation of default entities and adding subscription logic. [1] [2] [3] Additional Changes: Added new imports and modules to support the new functionalities and refactoring efforts. [1] [2] [3]
2 parents 06aa17d + 6eaa946 commit 3c29a0a

File tree

23 files changed

+487
-141
lines changed

23 files changed

+487
-141
lines changed

ai-provider/local/executor.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,9 @@ func (e *AsyncExecutor) DistributeToModelPipelines(model string, msg PullMessage
210210
type PullCallback func(msg PullMessage) error
211211

212212
func PullModel(model string, id string, fn PullCallback) (*Pipeline, error) {
213+
if client == nil {
214+
return nil, fmt.Errorf("client not initialized")
215+
}
213216
mp, has := taskExecutor.GetModelPipeline(model)
214217
if !has {
215218
mp = newModelPipeline(taskExecutor.ctx, 100)
@@ -279,6 +282,9 @@ func PullModel(model string, id string, fn PullCallback) (*Pipeline, error) {
279282
}
280283

281284
func StopPull(model string) {
285+
if client == nil {
286+
return
287+
}
282288
taskExecutor.CloseModelPipeline(model)
283289
}
284290

@@ -287,6 +293,9 @@ func CancelPipeline(model string, id string) {
287293
}
288294

289295
func RemoveModel(model string) error {
296+
if client == nil {
297+
return fmt.Errorf("client not initialized")
298+
}
290299
taskExecutor.CloseModelPipeline(model)
291300
err := client.Delete(context.Background(), &api.DeleteRequest{Model: model})
292301
if err != nil {
@@ -298,6 +307,9 @@ func RemoveModel(model string) error {
298307
}
299308

300309
func ModelsInstalled() ([]Model, error) {
310+
if client == nil {
311+
return nil, fmt.Errorf("client not initialized")
312+
}
301313
result, err := client.List(context.Background())
302314
if err != nil {
303315
return nil, err

ai-provider/local/local.go

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,18 @@ import (
44
"net/http"
55
"net/url"
66

7-
"github.com/eolinker/eosc/env"
87
"github.com/ollama/ollama/api"
98
)
109

1110
var (
12-
ollamaAddress = "http://127.0.0.1:11434"
13-
EnvOllamaAddress = "OLLAMA_ADDRESS"
14-
client *api.Client
11+
client *api.Client
1512
)
1613

17-
func init() {
18-
address, has := env.GetEnv(EnvOllamaAddress)
19-
if !has {
20-
address = ollamaAddress
21-
}
14+
func ResetOllamaAddress(address string) error {
2215
u, err := url.Parse(address)
2316
if err != nil {
24-
u, err = url.Parse(ollamaAddress)
25-
if err != nil {
26-
panic(err)
27-
}
17+
return err
2818
}
2919
client = api.NewClient(u, http.DefaultClient)
20+
return nil
3021
}

ai-provider/local/ollama.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package ai_provider_local
22

33
var (
4-
OllamaBase = "http://apipark-ollama:11434"
54
OllamaConfig = "{\n \"mirostat\": 0,\n \"mirostat_eta\": 0.1,\n \"mirostat_tau\": 5.0,\n \"num_ctx\": 4096,\n \"repeat_last_n\":64,\n \"repeat_penalty\": 1.1,\n \"temperature\": 0.7,\n \"seed\": 42,\n \"num_predict\": 42,\n \"top_k\": 40,\n \"top_p\": 0.9,\n \"min_p\": 0.5\n}\n"
65
OllamaSvg = `<?xml version="1.0" standalone="no"?>
76
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"

controller/ai-local/controller.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ type ILocalModelController interface {
1818
Update(ctx *gin.Context, model string, input *ai_local_dto.Update) error
1919
State(ctx *gin.Context, model string) (*ai_local_dto.DeployState, *ai_local_dto.ModelInfo, error)
2020
SimpleList(ctx *gin.Context) ([]*ai_local_dto.SimpleItem, error)
21+
OllamaConfig(ctx *gin.Context) (*ai_local_dto.OllamaConfig, error)
22+
OllamaConfigUpdate(ctx *gin.Context, input *ai_local_dto.OllamaConfig) error
2123
}
2224

2325
func init() {

controller/ai-local/iml.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,15 @@ import (
77
"io"
88
"math"
99
"net/http"
10+
"net/url"
1011
"strings"
12+
"time"
13+
14+
ai_balance "github.com/APIParkLab/APIPark/module/ai-balance"
15+
16+
"github.com/APIParkLab/APIPark/module/system"
17+
system_dto "github.com/APIParkLab/APIPark/module/system/dto"
18+
ollama_api "github.com/ollama/ollama/api"
1119

1220
"github.com/APIParkLab/APIPark/module/subscribe"
1321
subscribe_dto "github.com/APIParkLab/APIPark/module/subscribe/dto"
@@ -47,13 +55,54 @@ type imlLocalModelController struct {
4755
serviceModule service.IServiceModule `autowired:""`
4856
catalogueModule catalogue.ICatalogueModule `autowired:""`
4957
aiAPIModule ai_api.IAPIModule `autowired:""`
58+
aiBalanceModule ai_balance.IBalanceModule `autowired:""`
5059
appModule service.IAppModule `autowired:""`
5160
routerModule router.IRouterModule `autowired:""`
5261
subscribeModule subscribe.ISubscribeModule `autowired:""`
5362
docModule service.IServiceDocModule `autowired:""`
63+
settingModule system.ISettingModule `autowired:""`
5464
transaction store.ITransaction `autowired:""`
5565
}
5666

67+
func (i *imlLocalModelController) OllamaConfig(ctx *gin.Context) (*ai_local_dto.OllamaConfig, error) {
68+
cfg := i.settingModule.Get(ctx)
69+
return &ai_local_dto.OllamaConfig{
70+
Address: cfg.OllamaAddress,
71+
}, nil
72+
}
73+
74+
var (
75+
client = &http.Client{
76+
Timeout: 2 * time.Second,
77+
}
78+
)
79+
80+
func (i *imlLocalModelController) OllamaConfigUpdate(ctx *gin.Context, input *ai_local_dto.OllamaConfig) error {
81+
u, err := url.Parse(input.Address)
82+
if err != nil {
83+
return nil
84+
}
85+
ollamaClient := ollama_api.NewClient(u, client)
86+
_, err = ollamaClient.Version(ctx)
87+
if err != nil {
88+
return err
89+
}
90+
return i.transaction.Transaction(ctx, func(ctx context.Context) error {
91+
err = i.module.SyncLocalModels(ctx, input.Address)
92+
if err != nil {
93+
return err
94+
}
95+
err = i.aiBalanceModule.SyncLocalBalances(ctx, input.Address)
96+
if err != nil {
97+
return err
98+
}
99+
100+
return i.settingModule.Set(ctx, &system_dto.InputSetting{
101+
OllamaAddress: &input.Address,
102+
})
103+
})
104+
}
105+
57106
func (i *imlLocalModelController) SimpleList(ctx *gin.Context) ([]*ai_local_dto.SimpleItem, error) {
58107
return i.module.SimpleList(ctx)
59108
}
@@ -209,6 +258,7 @@ func (i *imlLocalModelController) initAILocalService(ctx context.Context, model
209258
ApprovalType: "auto",
210259
Kind: "ai",
211260
Provider: &providerId,
261+
Model: &model,
212262
})
213263
if err != nil {
214264
return err

controller/service/iml.go

Lines changed: 43 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,6 @@ import (
3232

3333
api_doc "github.com/APIParkLab/APIPark/module/api-doc"
3434

35-
upstream_dto "github.com/APIParkLab/APIPark/module/upstream/dto"
36-
3735
"github.com/eolinker/eosc/log"
3836

3937
application_authorization "github.com/APIParkLab/APIPark/module/application-authorization"
@@ -94,7 +92,10 @@ func (i *imlServiceController) QuickCreateAIService(ctx *gin.Context, input *ser
9492
if err != nil {
9593
return err
9694
}
97-
95+
p, err := i.providerModule.Provider(ctx, input.Provider)
96+
if err != nil {
97+
return err
98+
}
9899
id := uuid.NewString()
99100
prefix := fmt.Sprintf("/%s", id[:8])
100101
catalogueInfo, err := i.catalogueModule.DefaultCatalogue(ctx)
@@ -111,6 +112,7 @@ func (i *imlServiceController) QuickCreateAIService(ctx *gin.Context, input *ser
111112
Catalogue: catalogueInfo.Id,
112113
ApprovalType: "auto",
113114
Provider: &input.Provider,
115+
Model: &p.DefaultLLM,
114116
Kind: "ai",
115117
})
116118
return err
@@ -294,25 +296,18 @@ func (i *imlServiceController) editAIService(ctx *gin.Context, id string, input
294296
if input.Provider == nil {
295297
return nil, fmt.Errorf("provider is required")
296298
}
297-
p, has := model_runtime.GetProvider(*input.Provider)
298-
if !has {
299-
return nil, fmt.Errorf("provider not found")
299+
if *input.Provider != "ollama" {
300+
_, has := model_runtime.GetProvider(*input.Provider)
301+
if !has {
302+
return nil, fmt.Errorf("provider not found")
303+
}
300304
}
301-
info, err := i.module.Get(ctx, id)
302-
if err != nil {
303305

304-
}
305-
err = i.transaction.Transaction(ctx, func(txCtx context.Context) error {
306-
info, err = i.module.Edit(ctx, id, input)
307-
if err != nil {
308-
return err
309-
}
310-
_, err = i.upstreamModule.Save(ctx, id, newAIUpstream(id, *input.Provider, p.URI()))
311-
return err
312-
})
306+
info, err := i.module.Edit(ctx, id, input)
313307
if err != nil {
314308
return nil, err
315309
}
310+
//_, err = i.upstreamModule.Save(ctx, id, newAIUpstream(id, *input.Provider, p.URI()))
316311

317312
return info, nil
318313
}
@@ -482,13 +477,13 @@ func (i *imlServiceController) Create(ctx *gin.Context, teamID string, input *se
482477
}
483478
var err error
484479
var info *service_dto.Service
485-
err = i.transaction.Transaction(ctx, func(txCtx context.Context) error {
486-
info, err = i.module.Create(txCtx, teamID, input)
480+
err = i.transaction.Transaction(ctx, func(ctx context.Context) error {
481+
info, err = i.module.Create(ctx, teamID, input)
487482
if err != nil {
488483
return err
489484
}
490485
path := fmt.Sprintf("/%s/", strings.Trim(input.Prefix, "/"))
491-
_, err = i.routerModule.Create(txCtx, info.Id, &router_dto.Create{
486+
_, err = i.routerModule.Create(ctx, info.Id, &router_dto.Create{
492487
Id: uuid.New().String(),
493488
Name: "",
494489
Path: path + "*",
@@ -504,6 +499,15 @@ func (i *imlServiceController) Create(ctx *gin.Context, teamID string, input *se
504499
},
505500
Disable: false,
506501
})
502+
apps, err := i.appModule.Search(ctx, teamID, "")
503+
if err != nil {
504+
return err
505+
}
506+
for _, app := range apps {
507+
i.subscribeModule.AddSubscriber(ctx, info.Id, &subscribe_dto.AddSubscriber{
508+
Application: app.Id,
509+
})
510+
}
507511
return err
508512
})
509513
return info, err
@@ -590,22 +594,22 @@ func (i *imlAppController) DeleteApp(ctx *gin.Context, appId string) error {
590594
return i.module.DeleteApp(ctx, appId)
591595
}
592596

593-
func newAIUpstream(id string, provider string, uri model_runtime.IProviderURI) *upstream_dto.Upstream {
594-
return &upstream_dto.Upstream{
595-
Type: "http",
596-
Balance: "round-robin",
597-
Timeout: 300000,
598-
Retry: 0,
599-
Remark: fmt.Sprintf("auto create by ai service %s,provider is %s", id, provider),
600-
LimitPeerSecond: 0,
601-
ProxyHeaders: nil,
602-
Scheme: uri.Scheme(),
603-
PassHost: "node",
604-
Nodes: []*upstream_dto.NodeConfig{
605-
{
606-
Address: uri.Host(),
607-
Weight: 100,
608-
},
609-
},
610-
}
611-
}
597+
//func newAIUpstream(id string, provider string, uri model_runtime.IProviderURI) *upstream_dto.Upstream {
598+
// return &upstream_dto.Upstream{
599+
// Type: "http",
600+
// Balance: "round-robin",
601+
// Timeout: 300000,
602+
// Retry: 0,
603+
// Remark: fmt.Sprintf("auto create by ai service %s,provider is %s", id, provider),
604+
// LimitPeerSecond: 0,
605+
// ProxyHeaders: nil,
606+
// Scheme: uri.Scheme(),
607+
// PassHost: "node",
608+
// Nodes: []*upstream_dto.NodeConfig{
609+
// {
610+
// Address: uri.Host(),
611+
// Weight: 100,
612+
// },
613+
// },
614+
// }
615+
//}

0 commit comments

Comments
 (0)