Skip to content

Commit 8c78bcd

Browse files
committed
release: prepare v0.1.11
1 parent b3a956f commit 8c78bcd

79 files changed

Lines changed: 10215 additions & 512 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/release.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,13 @@ jobs:
158158
${{ matrix.wails-extra || '' }} \
159159
-ldflags "-X main.Version=${{ github.ref_name }} -X main.ReleaseLabel=${RELEASE_LABEL}"
160160
161+
- name: Sync macOS bundle version metadata
162+
if: runner.os == 'macOS'
163+
shell: bash
164+
run: |
165+
chmod +x scripts/sync-macos-bundle-version.sh
166+
scripts/sync-macos-bundle-version.sh "build/bin/GetTokens.app" "${{ github.ref_name }}"
167+
161168
- name: Reinstall sidecar into macOS app bundle
162169
if: runner.os == 'macOS'
163170
shell: bash

app.go

Lines changed: 277 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ type AccountRecord struct {
105105

106106
type CreateCodexAPIKeyInput struct {
107107
APIKey string `json:"apiKey"`
108+
Label string `json:"label,omitempty"`
108109
BaseURL string `json:"baseUrl"`
109110
Priority int `json:"priority,omitempty"`
110111
Prefix string `json:"prefix,omitempty"`
@@ -118,11 +119,88 @@ type UpdateCodexAPIKeyPriorityInput struct {
118119
Priority int `json:"priority,omitempty"`
119120
}
120121

122+
type UpdateCodexAPIKeyLabelInput struct {
123+
ID string `json:"id"`
124+
Label string `json:"label,omitempty"`
125+
}
126+
127+
type UpdateCodexAPIKeyConfigInput struct {
128+
ID string `json:"id"`
129+
APIKey string `json:"apiKey"`
130+
BaseURL string `json:"baseUrl"`
131+
Prefix string `json:"prefix,omitempty"`
132+
}
133+
121134
type UpdateAccountPriorityInput struct {
122135
ID string `json:"id"`
123136
Priority int `json:"priority,omitempty"`
124137
}
125138

139+
type OpenAICompatibleProvider struct {
140+
Name string `json:"name"`
141+
Priority int `json:"priority,omitempty"`
142+
Disabled bool `json:"disabled,omitempty"`
143+
BaseURL string `json:"baseUrl"`
144+
Prefix string `json:"prefix,omitempty"`
145+
APIKey string `json:"apiKey"`
146+
APIKeys []string `json:"apiKeys,omitempty"`
147+
Models []OpenAICompatibleModel `json:"models,omitempty"`
148+
Headers map[string]string `json:"headers,omitempty"`
149+
KeyCount int `json:"keyCount,omitempty"`
150+
ModelCount int `json:"modelCount,omitempty"`
151+
HasHeaders bool `json:"hasHeaders,omitempty"`
152+
}
153+
154+
type OpenAICompatibleModel struct {
155+
Name string `json:"name"`
156+
Alias string `json:"alias,omitempty"`
157+
}
158+
159+
type CreateOpenAICompatibleProviderInput struct {
160+
Name string `json:"name"`
161+
BaseURL string `json:"baseUrl"`
162+
Prefix string `json:"prefix,omitempty"`
163+
APIKey string `json:"apiKey"`
164+
}
165+
166+
type UpdateOpenAICompatibleProviderInput struct {
167+
CurrentName string `json:"currentName"`
168+
Name string `json:"name"`
169+
BaseURL string `json:"baseUrl"`
170+
Prefix string `json:"prefix,omitempty"`
171+
APIKey string `json:"apiKey"`
172+
APIKeys []string `json:"apiKeys,omitempty"`
173+
Headers map[string]string `json:"headers,omitempty"`
174+
Models []OpenAICompatibleModel `json:"models,omitempty"`
175+
}
176+
177+
type VerifyOpenAICompatibleProviderInput struct {
178+
BaseURL string `json:"baseUrl"`
179+
APIKey string `json:"apiKey"`
180+
Model string `json:"model"`
181+
Headers map[string]string `json:"headers,omitempty"`
182+
}
183+
184+
type FetchOpenAICompatibleProviderModelsInput struct {
185+
BaseURL string `json:"baseUrl"`
186+
APIKey string `json:"apiKey"`
187+
Headers map[string]string `json:"headers,omitempty"`
188+
}
189+
190+
type VerifyOpenAICompatibleProviderResult struct {
191+
Success bool `json:"success"`
192+
StatusCode int `json:"statusCode,omitempty"`
193+
Message string `json:"message,omitempty"`
194+
ResponseBody string `json:"responseBody,omitempty"`
195+
}
196+
197+
type FetchOpenAICompatibleProviderModelsResult struct {
198+
Models []OpenAICompatibleModel `json:"models,omitempty"`
199+
StatusCode int `json:"statusCode,omitempty"`
200+
Message string `json:"message,omitempty"`
201+
ResponseBody string `json:"responseBody,omitempty"`
202+
}
203+
126204
type RelayServiceConfig struct {
127205
APIKeys []string `json:"apiKeys"`
128206
Endpoints []RelayServiceEndpoint `json:"endpoints"`
@@ -158,6 +236,28 @@ type UsageStatisticsResponse struct {
158236
FailedRequests int64 `json:"failedRequests,omitempty"`
159237
}
160238

239+
type LocalProjectedUsageDetail struct {
240+
Timestamp string `json:"timestamp"`
241+
Provider string `json:"provider"`
242+
SourceKind string `json:"sourceKind"`
243+
Model string `json:"model,omitempty"`
244+
InputTokens int64 `json:"inputTokens"`
245+
CachedInputTokens int64 `json:"cachedInputTokens"`
246+
OutputTokens int64 `json:"outputTokens"`
247+
RequestCount int64 `json:"requestCount"`
248+
}
249+
250+
type LocalProjectedUsageResponse struct {
251+
Provider string `json:"provider"`
252+
SourceKind string `json:"sourceKind"`
253+
ScannedFiles int `json:"scannedFiles"`
254+
CacheHitFiles int `json:"cacheHitFiles,omitempty"`
255+
DeltaAppendFiles int `json:"deltaAppendFiles,omitempty"`
256+
FullRebuildFiles int `json:"fullRebuildFiles,omitempty"`
257+
FileMissingFiles int `json:"fileMissingFiles,omitempty"`
258+
Details []LocalProjectedUsageDetail `json:"details"`
259+
}
260+
161261
func NewApp() *App {
162262
return &App{
163263
core: wailsapp.New(Version, ReleaseLabel, GitHubRepo),
@@ -236,6 +336,10 @@ func (a *App) SetAuthFileStatus(name string, disabled bool) error {
236336
return a.core.SetAuthFileStatus(name, disabled)
237337
}
238338

339+
func (a *App) SetAccountDisabled(id string, disabled bool) error {
340+
return a.core.SetAccountDisabled(id, disabled)
341+
}
342+
239343
func (a *App) DeleteAuthFiles(names []string) error {
240344
return a.core.DeleteAuthFiles(names)
241345
}
@@ -289,6 +393,22 @@ func (a *App) GetUsageStatistics() (*UsageStatisticsResponse, error) {
289393
}, nil
290394
}
291395

396+
func (a *App) GetCodexLocalUsage() (*LocalProjectedUsageResponse, error) {
397+
result, err := a.core.GetCodexLocalUsage()
398+
if err != nil {
399+
return nil, err
400+
}
401+
return mapLocalProjectedUsageResponse(result), nil
402+
}
403+
404+
func (a *App) RebuildCodexLocalUsage() (*LocalProjectedUsageResponse, error) {
405+
result, err := a.core.RebuildCodexLocalUsage()
406+
if err != nil {
407+
return nil, err
408+
}
409+
return mapLocalProjectedUsageResponse(result), nil
410+
}
411+
292412
func (a *App) StartCodexOAuth() (*OAuthStartResult, error) {
293413
result, err := a.core.StartCodexOAuth()
294414
if err != nil {
@@ -354,6 +474,32 @@ func (a *App) ListAccounts() ([]AccountRecord, error) {
354474
return records, nil
355475
}
356476

477+
func (a *App) ListOpenAICompatibleProviders() ([]OpenAICompatibleProvider, error) {
478+
result, err := a.core.ListOpenAICompatibleProviders()
479+
if err != nil {
480+
return nil, err
481+
}
482+
483+
providers := make([]OpenAICompatibleProvider, 0, len(result))
484+
for _, item := range result {
485+
providers = append(providers, OpenAICompatibleProvider{
486+
Name: item.Name,
487+
Priority: item.Priority,
488+
Disabled: item.Disabled,
489+
BaseURL: item.BaseURL,
490+
Prefix: item.Prefix,
491+
APIKey: item.APIKey,
492+
APIKeys: append([]string(nil), item.APIKeys...),
493+
Models: mapOpenAICompatibleModels(item.Models),
494+
Headers: item.Headers,
495+
KeyCount: item.KeyCount,
496+
ModelCount: item.ModelCount,
497+
HasHeaders: item.HasHeaders,
498+
})
499+
}
500+
return providers, nil
501+
}
502+
357503
func (a *App) GetRelayServiceConfig() (*RelayServiceConfig, error) {
358504
result, err := a.core.GetRelayServiceConfig()
359505
if err != nil {
@@ -444,6 +590,7 @@ func (a *App) ApplyRelayServiceConfigToLocal(apiKey string, baseURL string) (*Re
444590
func (a *App) CreateCodexAPIKey(input CreateCodexAPIKeyInput) error {
445591
return a.core.CreateCodexAPIKey(wailsapp.CreateCodexAPIKeyInput{
446592
APIKey: input.APIKey,
593+
Label: input.Label,
447594
BaseURL: input.BaseURL,
448595
Priority: input.Priority,
449596
Prefix: input.Prefix,
@@ -453,6 +600,83 @@ func (a *App) CreateCodexAPIKey(input CreateCodexAPIKeyInput) error {
453600
})
454601
}
455602

603+
func (a *App) UpdateCodexAPIKeyLabel(input UpdateCodexAPIKeyLabelInput) error {
604+
return a.core.UpdateCodexAPIKeyLabel(wailsapp.UpdateCodexAPIKeyLabelInput{
605+
ID: input.ID,
606+
Label: input.Label,
607+
})
608+
}
609+
610+
func (a *App) UpdateCodexAPIKeyConfig(input UpdateCodexAPIKeyConfigInput) error {
611+
return a.core.UpdateCodexAPIKeyConfig(wailsapp.UpdateCodexAPIKeyConfigInput{
612+
ID: input.ID,
613+
APIKey: input.APIKey,
614+
BaseURL: input.BaseURL,
615+
Prefix: input.Prefix,
616+
})
617+
}
618+
619+
func (a *App) CreateOpenAICompatibleProvider(input CreateOpenAICompatibleProviderInput) error {
620+
return a.core.CreateOpenAICompatibleProvider(wailsapp.CreateOpenAICompatibleProviderInput{
621+
Name: input.Name,
622+
BaseURL: input.BaseURL,
623+
Prefix: input.Prefix,
624+
APIKey: input.APIKey,
625+
})
626+
}
627+
628+
func (a *App) DeleteOpenAICompatibleProvider(name string) error {
629+
return a.core.DeleteOpenAICompatibleProvider(name)
630+
}
631+
632+
func (a *App) UpdateOpenAICompatibleProvider(input UpdateOpenAICompatibleProviderInput) error {
633+
return a.core.UpdateOpenAICompatibleProvider(wailsapp.UpdateOpenAICompatibleProviderInput{
634+
CurrentName: input.CurrentName,
635+
Name: input.Name,
636+
BaseURL: input.BaseURL,
637+
Prefix: input.Prefix,
638+
APIKey: input.APIKey,
639+
APIKeys: append([]string(nil), input.APIKeys...),
640+
Headers: input.Headers,
641+
Models: mapOpenAICompatibleModelsToWails(input.Models),
642+
})
643+
}
644+
645+
func (a *App) VerifyOpenAICompatibleProvider(input VerifyOpenAICompatibleProviderInput) (*VerifyOpenAICompatibleProviderResult, error) {
646+
result, err := a.core.VerifyOpenAICompatibleProvider(wailsapp.VerifyOpenAICompatibleProviderInput{
647+
BaseURL: input.BaseURL,
648+
APIKey: input.APIKey,
649+
Model: input.Model,
650+
Headers: input.Headers,
651+
})
652+
if err != nil {
653+
return nil, err
654+
}
655+
return &VerifyOpenAICompatibleProviderResult{
656+
Success: result.Success,
657+
StatusCode: result.StatusCode,
658+
Message: result.Message,
659+
ResponseBody: result.ResponseBody,
660+
}, nil
661+
}
662+
663+
func (a *App) FetchOpenAICompatibleProviderModels(input FetchOpenAICompatibleProviderModelsInput) (*FetchOpenAICompatibleProviderModelsResult, error) {
664+
result, err := a.core.FetchOpenAICompatibleProviderModels(wailsapp.FetchOpenAICompatibleProviderModelsInput{
665+
BaseURL: input.BaseURL,
666+
APIKey: input.APIKey,
667+
Headers: input.Headers,
668+
})
669+
if err != nil {
670+
return nil, err
671+
}
672+
return &FetchOpenAICompatibleProviderModelsResult{
673+
Models: mapOpenAICompatibleModels(result.Models),
674+
StatusCode: result.StatusCode,
675+
Message: result.Message,
676+
ResponseBody: result.ResponseBody,
677+
}, nil
678+
}
679+
456680
func (a *App) DeleteCodexAPIKey(id string) error {
457681
return a.core.DeleteCodexAPIKey(id)
458682
}
@@ -480,6 +704,59 @@ func mapAccountRecord(record accountsdomain.AccountRecord) AccountRecord {
480704
}
481705
}
482706

707+
func mapLocalProjectedUsageResponse(result *wailsapp.LocalProjectedUsageResponse) *LocalProjectedUsageResponse {
708+
if result == nil {
709+
return &LocalProjectedUsageResponse{}
710+
}
711+
712+
details := make([]LocalProjectedUsageDetail, 0, len(result.Details))
713+
for _, detail := range result.Details {
714+
details = append(details, LocalProjectedUsageDetail{
715+
Timestamp: detail.Timestamp,
716+
Provider: detail.Provider,
717+
SourceKind: detail.SourceKind,
718+
Model: detail.Model,
719+
InputTokens: detail.InputTokens,
720+
CachedInputTokens: detail.CachedInputTokens,
721+
OutputTokens: detail.OutputTokens,
722+
RequestCount: detail.RequestCount,
723+
})
724+
}
725+
726+
return &LocalProjectedUsageResponse{
727+
Provider: result.Provider,
728+
SourceKind: result.SourceKind,
729+
ScannedFiles: result.ScannedFiles,
730+
CacheHitFiles: result.CacheHitFiles,
731+
DeltaAppendFiles: result.DeltaAppendFiles,
732+
FullRebuildFiles: result.FullRebuildFiles,
733+
FileMissingFiles: result.FileMissingFiles,
734+
Details: details,
735+
}
736+
}
737+
738+
func mapOpenAICompatibleModels(items []wailsapp.OpenAICompatibleModel) []OpenAICompatibleModel {
739+
models := make([]OpenAICompatibleModel, 0, len(items))
740+
for _, item := range items {
741+
models = append(models, OpenAICompatibleModel{
742+
Name: item.Name,
743+
Alias: item.Alias,
744+
})
745+
}
746+
return models
747+
}
748+
749+
func mapOpenAICompatibleModelsToWails(items []OpenAICompatibleModel) []wailsapp.OpenAICompatibleModel {
750+
models := make([]wailsapp.OpenAICompatibleModel, 0, len(items))
751+
for _, item := range items {
752+
models = append(models, wailsapp.OpenAICompatibleModel{
753+
Name: item.Name,
754+
Alias: item.Alias,
755+
})
756+
}
757+
return models
758+
}
759+
483760
func mapRelayServiceEndpoints(items []wailsapp.RelayServiceEndpoint) []RelayServiceEndpoint {
484761
endpoints := make([]RelayServiceEndpoint, 0, len(items))
485762
for _, item := range items {

docs-linhay/references/CLIProxyAPI

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 0 additions & 1 deletion
This file was deleted.

frontend/package-lock.json

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

frontend/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@
88
"build": "vite build",
99
"preview": "vite preview",
1010
"typecheck": "tsc --noEmit",
11-
"test:unit": "node --test src/utils/version.test.mjs src/utils/pagePersistence.test.mjs src/features/settings/settingsRelease.test.mjs src/features/accounts/tests/accountConfig.test.mjs src/features/accounts/tests/accountFilters.test.mjs src/features/accounts/tests/accountSelectors.test.mjs src/features/accounts/tests/accountSelection.test.mjs src/features/accounts/tests/accountTransfer.test.mjs src/features/accounts/tests/accountPresentation.test.mjs src/features/accounts/tests/accountOAuth.test.mjs src/features/accounts/tests/accountCardInteractions.test.mjs src/features/accounts/tests/accountRotation.test.mjs src/features/accounts/tests/accountUsage.test.mjs src/components/biz/accountDetailClipboard.test.mjs"
11+
"test:unit": "node --test src/utils/version.test.mjs src/utils/pagePersistence.test.mjs src/features/settings/settingsRelease.test.mjs src/features/accounts/tests/accountConfig.test.mjs src/features/accounts/tests/accountFilters.test.mjs src/features/accounts/tests/accountSelectors.test.mjs src/features/accounts/tests/accountSelection.test.mjs src/features/accounts/tests/accountTransfer.test.mjs src/features/accounts/tests/accountPresentation.test.mjs src/features/accounts/tests/accountOAuth.test.mjs src/features/accounts/tests/accountCardInteractions.test.mjs src/features/accounts/tests/accountHealthMeta.test.mjs src/features/accounts/tests/accountRotation.test.mjs src/features/accounts/tests/accountUsage.test.mjs src/features/accounts/tests/usageDesk.test.mjs src/features/accounts/tests/openAICompatible.test.mjs src/components/biz/accountDetailClipboard.test.mjs"
1212
},
1313
"dependencies": {
14+
"lucide-react": "^1.11.0",
1415
"react": "^18.3.1",
1516
"react-dom": "^18.3.1"
1617
},

0 commit comments

Comments
 (0)