Support configuring effort alongside model
This commit is contained in:
@@ -16,6 +16,7 @@ final class StepNode: Identifiable {
|
||||
var kind: Kind
|
||||
var name = ""
|
||||
var model = ""
|
||||
var effort = ""
|
||||
var prompt = ""
|
||||
var weight = 0.0
|
||||
var agents: [TeamMember]?
|
||||
@@ -42,6 +43,7 @@ final class StepNode: Identifiable {
|
||||
self.init(kind: .stage)
|
||||
name = step.stage ?? ""
|
||||
model = step.model ?? ""
|
||||
effort = step.effort ?? ""
|
||||
prompt = step.prompt ?? ""
|
||||
agents = step.agents
|
||||
}
|
||||
@@ -52,7 +54,7 @@ final class StepNode: Identifiable {
|
||||
let w = parent?.kind == .random ? weight : nil
|
||||
return switch kind {
|
||||
case .stage:
|
||||
WorkflowStep(stage: name, model: agents == nil ? model : nil, prompt: prompt, weight: w, agents: agents)
|
||||
WorkflowStep(stage: name, model: agents == nil ? model : nil, effort: agents == nil && !effort.isEmpty ? effort : nil, prompt: prompt, weight: w, agents: agents)
|
||||
case .order:
|
||||
WorkflowStep(order: children.map(\.step), weight: w)
|
||||
case .parallel:
|
||||
@@ -90,7 +92,7 @@ final class StepNode: Identifiable {
|
||||
}
|
||||
|
||||
@MainActor
|
||||
private func newStage(_ root: StepNode, _ model: String) -> StepNode {
|
||||
private func newStage(_ root: StepNode, _ model: String, _ effort: String) -> StepNode {
|
||||
let names = Set(root.stageNames())
|
||||
var n = names.count + 1
|
||||
while names.contains("Stage \(n)") {
|
||||
@@ -99,6 +101,7 @@ private func newStage(_ root: StepNode, _ model: String) -> StepNode {
|
||||
let s = StepNode(kind: .stage)
|
||||
s.name = "Stage \(n)"
|
||||
s.model = model
|
||||
s.effort = effort
|
||||
s.open = true
|
||||
return s
|
||||
}
|
||||
@@ -251,7 +254,7 @@ struct WorkflowEditor: View {
|
||||
}
|
||||
.padding(.top, 12)
|
||||
Button("Add stage") {
|
||||
root.insert(newStage(root, store.defaultModel), at: root.children.count)
|
||||
root.insert(newStage(root, store.defaultModel, store.defaultEffort), at: root.children.count)
|
||||
}
|
||||
.buttonStyle(SmallLinkButtonStyle())
|
||||
.padding(.top, 8)
|
||||
@@ -285,7 +288,7 @@ struct WorkflowEditor: View {
|
||||
private func load() async {
|
||||
guard let original else {
|
||||
let r = StepNode(kind: .order)
|
||||
r.insert(newStage(r, store.defaultModel), at: 0)
|
||||
r.insert(newStage(r, store.defaultModel, store.defaultEffort), at: 0)
|
||||
root = r
|
||||
return
|
||||
}
|
||||
@@ -355,7 +358,7 @@ private struct StepRow: View {
|
||||
if let agents = node.agents {
|
||||
Text("team of \(agents.count)").foregroundStyle(Palette.muted).fixedSize()
|
||||
} else {
|
||||
ModelPicker(model: $node.model)
|
||||
ModelPicker(model: $node.model, effort: $node.effort)
|
||||
}
|
||||
case .order:
|
||||
Text("in order").foregroundStyle(Palette.muted)
|
||||
@@ -389,7 +392,8 @@ private struct StepRow: View {
|
||||
TextField("Agent name", text: Binding(get: { node.agents?[i].name ?? "" }, set: { node.agents?[i].name = $0 }))
|
||||
.textFieldStyle(.plain)
|
||||
.font(Fonts.font(13, weight: 700))
|
||||
ModelPicker(model: Binding(get: { node.agents?[i].model ?? "" }, set: { node.agents?[i].model = $0 }))
|
||||
ModelPicker(model: Binding(get: { node.agents?[i].model ?? "" }, set: { node.agents?[i].model = $0 }),
|
||||
effort: Binding(get: { node.agents?[i].effort ?? "" }, set: { node.agents?[i].effort = $0.isEmpty ? nil : $0 }))
|
||||
}
|
||||
.padding(.top, 4)
|
||||
PromptEditor(text: Binding(get: { node.agents?[i].prompt ?? "" }, set: { node.agents?[i].prompt = $0 }))
|
||||
@@ -443,7 +447,7 @@ private struct StepRow: View {
|
||||
private let groupKinds: [(StepNode.Kind, String)] = [(.order, "in order"), (.parallel, "in parallel"), (.random, "one at random")]
|
||||
|
||||
private func stage() -> StepNode {
|
||||
newStage(root, store.defaultModel)
|
||||
newStage(root, store.defaultModel, store.defaultEffort)
|
||||
}
|
||||
|
||||
private func addAfter() {
|
||||
@@ -528,10 +532,17 @@ private struct WeightField: View {
|
||||
|
||||
struct ModelPicker: View {
|
||||
@Binding var model: String
|
||||
@Binding var effort: String
|
||||
|
||||
var body: some View {
|
||||
let list = model.isEmpty || models.contains(model) ? models : [model] + models
|
||||
ChoiceMenu(value: $model, options: list.map { ($0, $0) }, placeholder: "model")
|
||||
HStack(spacing: 6) {
|
||||
ChoiceMenu(value: $model, options: list.map { ($0, $0) }, placeholder: "model")
|
||||
ChoiceMenu(value: $effort, options: efforts(model).map { ($0, effortLabel($0)) })
|
||||
}
|
||||
.onChange(of: model) {
|
||||
effort = effortFor(model, effort)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user