Merge nucleic/zesty-jade-weasel-yb6i into dev
This commit is contained in:
@@ -41,6 +41,10 @@ enum SandboxToolDisplay {
|
||||
case "linux_container": "Linux container"
|
||||
case "nucleic_supervise": "Supervising subagents"
|
||||
case AskUserQuestion.nucleicToolName: "Question for you"
|
||||
case "nucleic_knowledge_search": "Search project knowledge"
|
||||
case "nucleic_knowledge_get": "Read project knowledge"
|
||||
case "nucleic_knowledge_add": "Add project knowledge"
|
||||
case "nucleic_knowledge_edit": "Edit project knowledge"
|
||||
default: nil
|
||||
}
|
||||
}
|
||||
@@ -71,6 +75,10 @@ enum SandboxToolDisplay {
|
||||
case "linux_vm_control": "Managing the Linux VM…"
|
||||
case "nucleic_supervise": "Waiting on subagents…"
|
||||
case AskUserQuestion.nucleicToolName: "Waiting on your answer…"
|
||||
case "nucleic_knowledge_search": "Searching project knowledge…"
|
||||
case "nucleic_knowledge_get": "Reading project knowledge…"
|
||||
case "nucleic_knowledge_add": "Adding to project knowledge…"
|
||||
case "nucleic_knowledge_edit": "Editing project knowledge…"
|
||||
default: nil
|
||||
}
|
||||
}
|
||||
@@ -90,6 +98,10 @@ enum SandboxToolDisplay {
|
||||
case "mac_vm_control", "linux_vm_control": "power"
|
||||
case "nucleic_supervise": "eye"
|
||||
case AskUserQuestion.nucleicToolName: "questionmark.bubble"
|
||||
case "nucleic_knowledge_search": "magnifyingglass"
|
||||
case "nucleic_knowledge_get": "point.3.connected.trianglepath.dotted"
|
||||
case "nucleic_knowledge_add": "note.text.badge.plus"
|
||||
case "nucleic_knowledge_edit": "square.and.pencil"
|
||||
default: nil
|
||||
}
|
||||
}
|
||||
@@ -129,6 +141,16 @@ enum SandboxToolDisplay {
|
||||
let first = questions.first else { return nil }
|
||||
let suffix = questions.count > 1 ? " +\(questions.count - 1) more" : ""
|
||||
return singleLine(first.question) + suffix
|
||||
// An empty query isn't a degenerate search — it's how the overview is asked for.
|
||||
case "nucleic_knowledge_search":
|
||||
return string(input, "query").map(singleLine) ?? "overview"
|
||||
case "nucleic_knowledge_get":
|
||||
return entityNames(input)
|
||||
// Writes are shaped as arrays, so the row is what they add rather than one element of them.
|
||||
case "nucleic_knowledge_add":
|
||||
return addSummary(input)
|
||||
case "nucleic_knowledge_edit":
|
||||
return editSummary(input)
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
@@ -196,6 +218,46 @@ enum SandboxToolDisplay {
|
||||
return "\(op) — \(subject)"
|
||||
}
|
||||
|
||||
/// The entities a knowledge fetch asked for, joined — the names are the call. A lone `name` is
|
||||
/// accepted too, since fetching one entity is the common case.
|
||||
private static func entityNames(_ input: JSONValue) -> String? {
|
||||
let names = (input["names"]?.arrayValue ?? [])
|
||||
.compactMap { $0.stringValue ?? $0["name"]?.stringValue }
|
||||
.map { $0.trimmingCharacters(in: .whitespacesAndNewlines) }
|
||||
.filter { !$0.isEmpty }
|
||||
guard !names.isEmpty else { return string(input, "name") }
|
||||
return clip(names.joined(separator: ", "), limit: 60)
|
||||
}
|
||||
|
||||
/// What a knowledge write puts into the graph — "2 entities, 3 relations" — counted per bucket.
|
||||
/// Observations carried inside an entity count toward the observation total, and so do anchors —
|
||||
/// the schema only ever nests those, so the top-level bucket alone would always read as zero.
|
||||
private static func addSummary(_ input: JSONValue) -> String? {
|
||||
let entities = input["entities"]?.arrayValue ?? []
|
||||
let nested = entities.reduce(0) { $0 + ($1["observations"]?.arrayValue?.count ?? 0) }
|
||||
let nestedAnchors = entities.reduce(0) { $0 + ($1["anchors"]?.arrayValue?.count ?? 0) }
|
||||
let buckets: [(singular: String, plural: String, count: Int)] = [
|
||||
("entity", "entities", entities.count),
|
||||
("observation", "observations",
|
||||
(input["observations"]?.arrayValue?.count ?? 0) + nested),
|
||||
("relation", "relations", input["relations"]?.arrayValue?.count ?? 0),
|
||||
("anchor", "anchors",
|
||||
(input["anchors"]?.arrayValue?.count ?? 0) + nestedAnchors),
|
||||
]
|
||||
let parts = buckets.filter { $0.count > 0 }
|
||||
.map { "\($0.count) \($0.count == 1 ? $0.singular : $0.plural)" }
|
||||
return parts.isEmpty ? nil : parts.joined(separator: ", ")
|
||||
}
|
||||
|
||||
/// A knowledge edit as how much it changes — "3 operations" — summed across its buckets, since
|
||||
/// how many changes land says more in a one-line row than which bucket they came from.
|
||||
private static func editSummary(_ input: JSONValue) -> String? {
|
||||
let operations = (input.objectValue ?? [:]).values
|
||||
.reduce(0) { $0 + ($1.arrayValue?.count ?? 0) }
|
||||
guard operations > 0 else { return nil }
|
||||
return "\(operations) operation\(operations == 1 ? "" : "s")"
|
||||
}
|
||||
|
||||
/// A VM lifecycle op as a phrase, so "status" doesn't read as a state label.
|
||||
private static func controlOpPhrase(_ op: String) -> String {
|
||||
switch op {
|
||||
|
||||
Reference in New Issue
Block a user