nvrsion: Add: Provisioned VM Image Preparation to run on macvm-spike; Fix: Move Model Selector Position.
Nucleic-Promote: 1 Co-authored-by: Nucleic <[email protected]>
This commit is contained in:
@@ -159,23 +159,13 @@ struct SessionDetailView: View {
|
|||||||
return min(100, Int((Double(used) / Double(window)) * 100))
|
return min(100, Int((Double(used) / Double(window)) * 100))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The model / effort / auto controls for the open session — the mobile echo of the Mac's
|
/// The context-occupancy readout and the Auto toggle for the open session, folded into the
|
||||||
/// session header, folded into the glass chat bar so they don't cost a strip of transcript
|
/// glass chat bar so they don't cost a strip of transcript height. The model / effort
|
||||||
/// height. Reads current state from the summary; each change is a control intent.
|
/// selectors used to sit here too, but they moved into the ⋯ menu (`modelEffortMenu`) to keep
|
||||||
|
/// the bar compact. Reads current state from the summary; each change is a control intent.
|
||||||
@ViewBuilder
|
@ViewBuilder
|
||||||
private func controlRow(_ summary: WireSessionSummary) -> some View {
|
private func controlRow(_ summary: WireSessionSummary) -> some View {
|
||||||
HStack(spacing: 10) {
|
HStack(spacing: 10) {
|
||||||
// A session's backend is fixed at creation, so only same-backend models are offered.
|
|
||||||
ModelMenu(model: modelBinding, catalog: store.modelCatalog, backend: summary.backend)
|
|
||||||
EffortMenu(effort: effortBinding, catalog: store.modelCatalog,
|
|
||||||
// No explicit model yet → use the session backend's default, so the menu
|
|
||||||
// shows that backend's effort range rather than collapsing to one level.
|
|
||||||
modelSKU: summary.model ?? store.modelCatalog.models(for: summary.backend).first?.sku,
|
|
||||||
controlled: controlled,
|
|
||||||
// Orchestra is a one-way latch for an existing chat — the host won't turn it
|
|
||||||
// off, so disable the other levels here to match.
|
|
||||||
lockWhenOrchestra: true)
|
|
||||||
Spacer(minLength: 4)
|
|
||||||
if let percent = contextPercent {
|
if let percent = contextPercent {
|
||||||
// Weight and primary ink (not `.secondary`) so the metric stays legible over
|
// Weight and primary ink (not `.secondary`) so the metric stays legible over
|
||||||
// whatever the Liquid Glass bar is blurring through.
|
// whatever the Liquid Glass bar is blurring through.
|
||||||
@@ -183,6 +173,7 @@ struct SessionDetailView: View {
|
|||||||
.font(.caption2.weight(.semibold)).foregroundStyle(.primary)
|
.font(.caption2.weight(.semibold)).foregroundStyle(.primary)
|
||||||
.help("Context window used")
|
.help("Context window used")
|
||||||
}
|
}
|
||||||
|
Spacer(minLength: 4)
|
||||||
// Locked on for a Nucleic Control project — those chats always run autonomously, and
|
// Locked on for a Nucleic Control project — those chats always run autonomously, and
|
||||||
// the host keeps Auto on regardless of what the phone sends, so show it locked on to
|
// the host keeps Auto on regardless of what the phone sends, so show it locked on to
|
||||||
// match rather than offering a toggle that wouldn't take.
|
// match rather than offering a toggle that wouldn't take.
|
||||||
@@ -198,7 +189,8 @@ struct SessionDetailView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The ⋯ menu: the diff viewer for everyone, then the control-scope session actions.
|
/// The ⋯ menu: the diff viewer for everyone, then — at control scope — the next-turn model /
|
||||||
|
/// effort selectors (moved off the composer to keep it compact) and the session actions.
|
||||||
@ViewBuilder
|
@ViewBuilder
|
||||||
private var sessionMenu: some View {
|
private var sessionMenu: some View {
|
||||||
Menu {
|
Menu {
|
||||||
@@ -206,6 +198,8 @@ struct SessionDetailView: View {
|
|||||||
Label(diffLabel, systemImage: "plus.forwardslash.minus")
|
Label(diffLabel, systemImage: "plus.forwardslash.minus")
|
||||||
}
|
}
|
||||||
if let summary, store.canControl {
|
if let summary, store.canControl {
|
||||||
|
Divider()
|
||||||
|
modelEffortMenu(summary)
|
||||||
Divider()
|
Divider()
|
||||||
sessionActions(summary)
|
sessionActions(summary)
|
||||||
}
|
}
|
||||||
@@ -214,6 +208,23 @@ struct SessionDetailView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The model and effort selectors for the next turn, relocated from the composer's control row
|
||||||
|
/// into the ⋯ menu so the glass chat bar stays compact — each opens as a submenu of levels.
|
||||||
|
/// `ModelMenu` / `EffortMenu` are themselves menus, so they nest cleanly here.
|
||||||
|
@ViewBuilder
|
||||||
|
private func modelEffortMenu(_ summary: WireSessionSummary) -> some View {
|
||||||
|
// A session's backend is fixed at creation, so only same-backend models are offered.
|
||||||
|
ModelMenu(model: modelBinding, catalog: store.modelCatalog, backend: summary.backend)
|
||||||
|
EffortMenu(effort: effortBinding, catalog: store.modelCatalog,
|
||||||
|
// No explicit model yet → use the session backend's default, so the menu
|
||||||
|
// shows that backend's effort range rather than collapsing to one level.
|
||||||
|
modelSKU: summary.model ?? store.modelCatalog.models(for: summary.backend).first?.sku,
|
||||||
|
controlled: controlled,
|
||||||
|
// Orchestra is a one-way latch for an existing chat — the host won't turn it
|
||||||
|
// off, so disable the other levels here to match.
|
||||||
|
lockWhenOrchestra: true)
|
||||||
|
}
|
||||||
|
|
||||||
/// "View changes" with the live +/− counts when the host projects them, so the menu hints
|
/// "View changes" with the live +/− counts when the host projects them, so the menu hints
|
||||||
/// whether there's anything to look at before opening the sheet.
|
/// whether there's anything to look at before opening the sheet.
|
||||||
private var diffLabel: String {
|
private var diffLabel: String {
|
||||||
|
|||||||
Reference in New Issue
Block a user