Files
wehub-resource-sync e9a2f726c9
CI / test (3.11) (push) Has been cancelled
CI / test (3.12) (push) Has been cancelled
CI / test (3.13) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:29:51 +08:00

192 lines
7.3 KiB
Swift

// PR 8 (+ PR 14 advanced/experimental expansion) — GET /admin/api/models
// response + per-model settings shape, plus the patch body for
// PUT /admin/api/models/{id}/settings.
//
// All fields the HTML admin modal renders are now exposed here so the
// Swift Advanced tab can reach feature parity. Experimental flags
// (TurboQuant KV, IndexCache, SpecPrefill, DFlash, native MTP) decode
// alongside compatibility readouts (`dflash_compatible`,
// `mtp_compatible`, etc.) sourced from the server so the UI can disable
// switches the runtime won't accept.
import Foundation
struct ListModelsResponse: Codable, Sendable {
let models: [ModelDTO]
}
struct ModelDTO: Codable, Equatable, Sendable, Identifiable {
let id: String
let displayName: String?
let modelPath: String?
let loaded: Bool
let isLoading: Bool
let estimatedSize: Int64
let estimatedSizeFormatted: String?
let pinned: Bool?
let isDefault: Bool?
let isFavorite: Bool?
let engineType: String?
let modelType: String?
/// Lower-level config-derived model class (e.g. `deepseek_v32`,
/// `glm_moe_dsa`). Used to gate the IndexCache row to DSA models.
let configModelType: String?
/// Server-side default for `enable_thinking` derived from the model
/// (chat template, config). UI shows it as the inherited value when
/// `enable_thinking` is unset and offers a one-click reset to it.
let thinkingDefault: Bool?
/// True when the model is structurally compatible with DFlash (block
/// diffusion speculative decoding). The toggle stays disabled when false.
let dflashCompatible: Bool?
/// Human-readable explanation when `dflashCompatible` is false. Surfaced
/// as a tooltip on the disabled DFlash toggle.
let dflashCompatibilityReason: String?
/// True when the global paged-SSD cache directory is configured. The
/// DFlash SSD-cache sub-toggle stays disabled when false.
let dflashSsdCacheAvailable: Bool?
/// True when the model is structurally compatible with native MTP.
let mtpCompatible: Bool?
let mtpCompatibilityReason: String?
let settings: ModelSettingsDTO?
}
struct ModelSettingsDTO: Codable, Equatable, Sendable {
let modelAlias: String?
let modelTypeOverride: String?
let maxContextWindow: Int?
let maxTokens: Int?
let temperature: Double?
let topP: Double?
let topK: Int?
let minP: Double?
let presencePenalty: Double?
let repetitionPenalty: Double?
let forceSampling: Bool?
let maxToolResultTokens: Int?
let enableThinking: Bool?
let thinkingBudgetEnabled: Bool?
let thinkingBudgetTokens: Int?
let reasoningParser: String?
let ttlSeconds: Int?
let isPinned: Bool?
let isDefault: Bool?
let isFavorite: Bool?
let displayName: String?
let activeProfileName: String?
// Security
let trustRemoteCode: Bool?
// Chat-template kwargs (free-form dict + a sibling list of keys the
// user wants to *force* — those go to `forced_ct_kwargs` server-side
// and override the request's `chat_template_kwargs`).
let chatTemplateKwargs: [String: AnyCodable]?
let forcedCtKwargs: [String]?
// Experimental: TurboQuant KV cache
let turboquantKvEnabled: Bool?
let turboquantKvBits: Double?
// Experimental: IndexCache (DSA models only)
let indexCacheFreq: Int?
// Experimental: SpecPrefill
let specprefillEnabled: Bool?
let specprefillDraftModel: String?
let specprefillKeepPct: Double?
let specprefillThreshold: Int?
// Experimental: DFlash (block diffusion speculative decoding)
let dflashEnabled: Bool?
let dflashDraftModel: String?
let dflashDraftQuantEnabled: Bool?
let dflashDraftQuantWeightBits: Int?
let dflashDraftQuantActivationBits: Int?
let dflashDraftQuantGroupSize: Int?
let dflashMaxCtx: Int?
let dflashInMemoryCache: Bool?
let dflashInMemoryCacheMaxEntries: Int?
/// Stored in bytes server-side; the editor row exposes a GiB-scaled
/// view via `DflashByteSize.gibToBytes` / `bytesToGib`.
let dflashInMemoryCacheMaxBytes: Int64?
let dflashSsdCache: Bool?
let dflashSsdCacheMaxBytes: Int64?
let dflashDraftWindowSize: Int?
let dflashDraftSinkSize: Int?
let dflashVerifyMode: String?
// Experimental: native MTP (mlx-lm PR 990 / PR 15 monkey-patch)
let mtpEnabled: Bool?
// Experimental: VLM MTP (mlx-vlm assistant-drafter speculative decoding)
let vlmMtpEnabled: Bool?
let vlmMtpDraftModel: String?
let vlmMtpDraftBlockSize: Int?
}
/// Patch body for PUT /admin/api/models/{id}/settings. Flat snake-cased
/// keys (Encoder converts via `.convertToSnakeCase`). `nil` fields are
/// omitted by `encodeIfPresent` so the server merges instead of resetting.
struct ModelSettingsPatch: Encodable, Equatable, Sendable {
var modelAlias: String? = nil
var modelTypeOverride: String? = nil
var maxContextWindow: Int? = nil
var maxTokens: Int? = nil
var temperature: Double? = nil
var topP: Double? = nil
var topK: Int? = nil
var minP: Double? = nil
var presencePenalty: Double? = nil
var repetitionPenalty: Double? = nil
var ttlSeconds: Int? = nil
var enableThinking: Bool? = nil
var thinkingBudgetEnabled: Bool? = nil
var thinkingBudgetTokens: Int? = nil
var maxToolResultTokens: Int? = nil
var forceSampling: Bool? = nil
var isPinned: Bool? = nil
var isFavorite: Bool? = nil
// Security
var trustRemoteCode: Bool? = nil
var reasoningParser: String? = nil
// Chat-template kwargs
var chatTemplateKwargs: [String: AnyCodable]? = nil
var forcedCtKwargs: [String]? = nil
// Experimental: TurboQuant KV
var turboquantKvEnabled: Bool? = nil
var turboquantKvBits: Double? = nil
// Experimental: IndexCache
var indexCacheFreq: Int? = nil
// Experimental: SpecPrefill
var specprefillEnabled: Bool? = nil
var specprefillDraftModel: String? = nil
var specprefillKeepPct: Double? = nil
var specprefillThreshold: Int? = nil
// Experimental: DFlash
var dflashEnabled: Bool? = nil
var dflashDraftModel: String? = nil
var dflashDraftQuantEnabled: Bool? = nil
var dflashDraftQuantWeightBits: Int? = nil
var dflashDraftQuantActivationBits: Int? = nil
var dflashDraftQuantGroupSize: Int? = nil
var dflashMaxCtx: Int? = nil
var dflashInMemoryCache: Bool? = nil
var dflashInMemoryCacheMaxEntries: Int? = nil
var dflashInMemoryCacheMaxBytes: Int64? = nil
var dflashSsdCache: Bool? = nil
var dflashSsdCacheMaxBytes: Int64? = nil
var dflashDraftWindowSize: Int? = nil
var dflashDraftSinkSize: Int? = nil
var dflashVerifyMode: String? = nil
// Experimental: native MTP
var mtpEnabled: Bool? = nil
// Experimental: VLM MTP
var vlmMtpEnabled: Bool? = nil
var vlmMtpDraftModel: String? = nil
var vlmMtpDraftBlockSize: Int? = nil
}
/// Generic acknowledgment shape returned by non-streaming admin endpoints
/// that just need to signal completion (model load/unload, settings patch,
/// task cancel/remove, stats clear, sub-key CRUD, etc.). Server responses
/// vary in which subset of `status`/`message`/`success` they populate, so
/// all three are optional and callers typically only check that the call
/// did not throw.
struct SimpleStatusResponse: Codable, Sendable {
let status: String?
let message: String?
let success: Bool?
}