mirror of
https://github.com/wu736139669/hapi.git
synced 2026-11-07 01:21:37 +00:00
The create form only offered models for Claude and Codex, so every other agent spawned on its default model. The form now loads the catalogs web uses. Agy, cursor, dsh and pi read /machines/:id/<flavor>-models. Copilot, grok, kimi and opencode probe the same route with cwd once the directory exists; the view refetches when the typed path turns out to exist. Option rows follow the web builders: - Copilot and cursor label the default row "Auto". - Kimi and pi prefix the provider; pi values are provider/modelId. - OpenCode marks the agent's own default. - Cursor shows a flat list of ACP ids, without the variant drill-down. Grok efforts and pi thinking levels follow the selected model, and an OpenCode variant becomes the reasoning effort. Grok's auto permission mode is hidden when the probe reports it unsupported. A restored selection the catalog no longer offers falls back to Default, and Create waits while a non-default selection is still being validated. The spawn body sends model for all of these agents, and cursor always sends it, with 'auto' as the default. Grok and pi send effort; opencode sends modelReasoningEffort. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
124 lines
4.5 KiB
Swift
124 lines
4.5 KiB
Swift
import Foundation
|
|
|
|
/// One row of a `<flavor>-models` catalog for the dynamically discovered
|
|
/// agents (agy, copilot, cursor, dsh, grok, kimi, opencode, pi). The union of
|
|
/// the per-flavor `*ModelSummary` shapes in `shared/src/apiTypes.ts`; fields a
|
|
/// flavor does not send stay nil.
|
|
public struct AgentModelSummary: Codable, Equatable, Sendable {
|
|
/// Opaque wire id, sent back verbatim (dsh ids are JSON tuples).
|
|
public var modelId: String
|
|
public var name: String?
|
|
/// Kimi/Pi provider. Pi spawns as `provider/modelId` and switches with a
|
|
/// `{provider, modelId}` reference.
|
|
public var provider: String?
|
|
/// Grok: efforts the model supports.
|
|
public var reasoningEfforts: [AgentReasoningEffortOption]?
|
|
/// Pi: `false` = the model has no thinking levels.
|
|
public var reasoning: Bool?
|
|
/// Pi: thinking level → provider value; `null` marks an unsupported level.
|
|
public var thinkingLevelMap: [String: String?]?
|
|
|
|
public init(
|
|
modelId: String,
|
|
name: String? = nil,
|
|
provider: String? = nil,
|
|
reasoningEfforts: [AgentReasoningEffortOption]? = nil,
|
|
reasoning: Bool? = nil,
|
|
thinkingLevelMap: [String: String?]? = nil
|
|
) {
|
|
self.modelId = modelId
|
|
self.name = name
|
|
self.provider = provider
|
|
self.reasoningEfforts = reasoningEfforts
|
|
self.reasoning = reasoning
|
|
self.thinkingLevelMap = thinkingLevelMap
|
|
}
|
|
}
|
|
|
|
/// `GrokReasoningEffortOption` / `OpencodeReasoningEffortOption`.
|
|
public struct AgentReasoningEffortOption: Codable, Equatable, Sendable {
|
|
public var value: String
|
|
public var name: String?
|
|
|
|
public init(value: String, name: String? = nil) {
|
|
self.value = value
|
|
self.name = name
|
|
}
|
|
}
|
|
|
|
/// `GET /api/machines/:id/<flavor>-models` and
|
|
/// `GET /api/sessions/:id/<flavor>-models`. RPC envelope: a CLI-side failure
|
|
/// is HTTP 200 `success: false`; agy may pair `success: true` with an
|
|
/// `error` (a stale but usable catalog).
|
|
public struct AgentModelsResponse: Codable, Equatable, Sendable {
|
|
public var success: Bool
|
|
public var availableModels: [AgentModelSummary]?
|
|
/// Cursor CLI SKUs (variant rows); the flat iOS picker does not use them.
|
|
public var cliModelSkus: [AgentModelSummary]?
|
|
/// The agent's own default (opencode/grok/copilot/kimi/dsh probes) or
|
|
/// the running model (session routes).
|
|
public var currentModelId: String?
|
|
/// Grok: `false` disables the `auto` permission mode.
|
|
public var autoPermissionModeSupported: Bool?
|
|
public var error: String?
|
|
|
|
public init(
|
|
success: Bool,
|
|
availableModels: [AgentModelSummary]? = nil,
|
|
cliModelSkus: [AgentModelSummary]? = nil,
|
|
currentModelId: String? = nil,
|
|
autoPermissionModeSupported: Bool? = nil,
|
|
error: String? = nil
|
|
) {
|
|
self.success = success
|
|
self.availableModels = availableModels
|
|
self.cliModelSkus = cliModelSkus
|
|
self.currentModelId = currentModelId
|
|
self.autoPermissionModeSupported = autoPermissionModeSupported
|
|
self.error = error
|
|
}
|
|
}
|
|
|
|
/// `GET /api/machines/:id/opencode-model-variants`.
|
|
public struct OpencodeModelVariantsResponse: Codable, Equatable, Sendable {
|
|
public var success: Bool
|
|
/// Variant names keyed by `providerId/modelId`.
|
|
public var variants: [String: [String]]?
|
|
public var error: String?
|
|
|
|
public init(success: Bool, variants: [String: [String]]? = nil, error: String? = nil) {
|
|
self.success = success
|
|
self.variants = variants
|
|
self.error = error
|
|
}
|
|
}
|
|
|
|
/// `GET /api/sessions/:id/grok-reasoning-effort-options` and
|
|
/// `GET /api/sessions/:id/opencode-reasoning-effort-options`.
|
|
public struct ReasoningEffortOptionsResponse: Codable, Equatable, Sendable {
|
|
public var success: Bool
|
|
public var options: [AgentReasoningEffortOption]?
|
|
public var currentValue: String?
|
|
/// OpenCode: the model the options belong to, and the requested model.
|
|
/// The options are stale while they differ.
|
|
public var currentModelId: String?
|
|
public var targetModelId: String?
|
|
public var error: String?
|
|
|
|
public init(
|
|
success: Bool,
|
|
options: [AgentReasoningEffortOption]? = nil,
|
|
currentValue: String? = nil,
|
|
currentModelId: String? = nil,
|
|
targetModelId: String? = nil,
|
|
error: String? = nil
|
|
) {
|
|
self.success = success
|
|
self.options = options
|
|
self.currentValue = currentValue
|
|
self.currentModelId = currentModelId
|
|
self.targetModelId = targetModelId
|
|
self.error = error
|
|
}
|
|
}
|