docs(v2): align reuse and account lifecycle contracts
This commit is contained in:
@@ -11,11 +11,12 @@
|
||||
|
||||
1. URL + key 自动发现模型
|
||||
2. 模型名归一化与推荐纠错
|
||||
3. provider/model 兼容画像建模
|
||||
4. 宿主资源演化与 provider 绑定
|
||||
5. 后台异步确认与有限重试
|
||||
6. 最终 gateway completion 验证
|
||||
7. run/item 状态持久化与结果页可读
|
||||
3. 跨中转同模型快速匹配与复用
|
||||
4. provider/model 兼容画像建模
|
||||
5. 宿主资源演化与 provider 绑定
|
||||
6. 后台异步确认与有限重试
|
||||
7. 最终 gateway completion 验证
|
||||
8. run/item 状态持久化与结果页可读
|
||||
|
||||
## 2. Canonical Contract
|
||||
|
||||
@@ -173,6 +174,7 @@ type AliasResult struct {
|
||||
|
||||
func NormalizeModelID(raw string) string
|
||||
func CanonicalModelID(raw string) string
|
||||
func CanonicalModelFamily(raw string) string
|
||||
func BuildAliasTable(rawModels []string) map[string]AliasResult
|
||||
func ResolveRequestedModel(requested string, rawModels []string) (resolved string, ok bool)
|
||||
func RecommendModels(requested []string, rawModels []string) []string
|
||||
@@ -183,6 +185,7 @@ func RecommendModels(requested []string, rawModels []string) []string
|
||||
```go
|
||||
func TestNormalizeModelID_MinimaxCanonical(t *testing.T)
|
||||
func TestNormalizeModelID_DeepSeekVendorPrefix(t *testing.T)
|
||||
func TestCanonicalModelFamily_KimiVariantsCollapseToSameFamily(t *testing.T)
|
||||
func TestResolveRequestedModel_UsesNormalizedAlias(t *testing.T)
|
||||
func TestRecommendModels_ReturnsCanonicalCandidates(t *testing.T)
|
||||
```
|
||||
@@ -319,6 +322,44 @@ func TestModelMappingDelta_AddsRawToCanonicalMappings(t *testing.T)
|
||||
func TestModelMappingDelta_SetsRestrictModelsAndBillingSource(t *testing.T)
|
||||
```
|
||||
|
||||
### 5.4 `internal/batch/reuse_policy.go`
|
||||
|
||||
职责:判断已存在 provider/account 是否可直接复用。
|
||||
|
||||
```go
|
||||
type ReuseDecision struct {
|
||||
ReuseProvision bool
|
||||
PatchOnly bool
|
||||
ReplaceAccount bool
|
||||
ReactivateAccount bool
|
||||
MatchedAccountState string
|
||||
AccountResolution string
|
||||
ReusedFromProviderID string
|
||||
ReusedFromAccountID *int64
|
||||
}
|
||||
|
||||
func DecideReuse(existing ExistingProviderSnapshot, incoming IncomingProviderSnapshot) ReuseDecision
|
||||
```
|
||||
|
||||
判断依据:
|
||||
|
||||
- `host_id + provider_id`
|
||||
- `base_url + api_key_fingerprint`
|
||||
- `canonical_model_families`
|
||||
- 现有 `access_status`
|
||||
- 现有 key/account 健康状态
|
||||
|
||||
单测:
|
||||
|
||||
```go
|
||||
func TestDecideReuse_FullyCoveredAndActive_ReusesProvision(t *testing.T)
|
||||
func TestDecideReuse_MissingFamilies_PatchOnly(t *testing.T)
|
||||
func TestDecideReuse_BrokenProvider_RequestsReplacement(t *testing.T)
|
||||
func TestDecideReuse_SameFamilyDifferentAlias_TreatedAsCovered(t *testing.T)
|
||||
func TestDecideReuse_ExistingActiveAccount_MarksDuplicateReused(t *testing.T)
|
||||
func TestDecideReuse_DisabledAccount_RequestsReactivation(t *testing.T)
|
||||
```
|
||||
|
||||
## 6. Stage 3: State Store
|
||||
|
||||
### 6.1 `internal/batch/run_state.go`
|
||||
@@ -351,12 +392,16 @@ type ImportRunItemState struct {
|
||||
ItemID string
|
||||
BaseURL string
|
||||
ProviderID string
|
||||
APIKeyFingerprint string
|
||||
CurrentStage ItemStage
|
||||
ConfirmationStatus ConfirmationStatus
|
||||
AccessStatus AccessStatus
|
||||
MatchedAccountState string
|
||||
AccountResolution string
|
||||
RequestedModels []string
|
||||
RawModels []string
|
||||
NormalizedModels []string
|
||||
CanonicalModelFamilies []string
|
||||
ResolvedSmokeModel *string
|
||||
RecommendedModels []string
|
||||
CapabilityProfileJSON string
|
||||
@@ -373,6 +418,9 @@ type ImportRunItemState struct {
|
||||
LastError *string
|
||||
LegacyBatchID *int64
|
||||
LegacyProviderID *string
|
||||
ProvisionReused bool
|
||||
ReusedFromProviderID *string
|
||||
ReusedFromAccountID *int64
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
}
|
||||
@@ -397,6 +445,7 @@ func TestRunStateStore_CreateAndUpdateRun(t *testing.T)
|
||||
func TestRunStateStore_UpsertItemStoresProjectionFields(t *testing.T)
|
||||
func TestRunStateStore_EventTrailCanBeQueried(t *testing.T)
|
||||
func TestRunStateStore_LeaseFieldsPersist(t *testing.T)
|
||||
func TestRunStateStore_AccountReuseFieldsPersist(t *testing.T)
|
||||
```
|
||||
|
||||
## 7. Stage 4: Batch Service
|
||||
@@ -418,6 +467,7 @@ func (s *BatchImportService) StartRun(ctx context.Context, req BatchImportRunReq
|
||||
职责:
|
||||
|
||||
- 创建 run + item
|
||||
- 先执行 reuse preflight,决定是复用、patch 还是 replace
|
||||
- 先落 probe/provision 结果
|
||||
- 入队 confirm,不在请求线程里承担全部确认责任
|
||||
- CLI/HTTP 只负责“发起”和“可选等待窗口”
|
||||
@@ -428,6 +478,7 @@ func (s *BatchImportService) StartRun(ctx context.Context, req BatchImportRunReq
|
||||
func TestBatchImport_StartRun_PersistsInitialState(t *testing.T)
|
||||
func TestBatchImport_RequestedModelMiss_UsesDiscoveredModel(t *testing.T)
|
||||
func TestBatchImport_ProvisionWritesLegacyLinks(t *testing.T)
|
||||
func TestBatchImport_ExistingActiveProviderAndCoveredFamilies_ReusesProvision(t *testing.T)
|
||||
```
|
||||
|
||||
## 8. Stage 5: Confirmation Worker
|
||||
|
||||
Reference in New Issue
Block a user