Cut transcript noise: fold grey boxes, drop duplicate review rows

This commit is contained in:
Ian Gulliver
2026-10-20 13:04:17 -07:00
parent 0f33ad4524
commit a7b2333535
14 changed files with 312 additions and 290 deletions
-3
View File
@@ -4,9 +4,6 @@
# M2 — Seeing the work
- Reduce transcript noise
Audit transcripts as they actually render for places where the noise can be cut.
# M3 — Second vendor and review
- Continuous background review
+1 -1
View File
@@ -1797,7 +1797,7 @@ components:
type: object
description: >
context (Markdown with the choices inline as `- ( ) text` / `- (*) text` pick-one or `- [ ] text` / `- [x] text` pick-any list items),
question, why_blocked, options (each choice's text, in order), multiple (true for pick-any), recommended (the marked choices' text), attachments.
question, options (each choice's text, in order), multiple (true for pick-any), recommended (the marked choices' text), attachments.
state: { $ref: "#/components/schemas/InboxState" }
created_at: { type: string, format: date-time }
resolved_by: { type: string }
+1 -1
View File
@@ -97,7 +97,7 @@ Connections belong to `Servers`, not to the window: every saved server's store a
## Views
- **Transcript and Lead.** `TranscriptBuilder` is a pure function from events to a list of rows: user and agent messages, consecutive tool calls folded into one group with its summary ("Read file ×3"), subagents nested with their status, pending tool calls and running subagents (background ones included after the turn ends) outlined in the accent colour with a 0.6s fade, thinking, the byre prompt collapsed, held turns, `NO_REPLY` turns folded away, handoffs, snapshot rows with changes, fork and review (and stop while the review runs), question bubbles that follow their item's `inbox.updated` events, a finished review as its summary row followed by one row per finding, the agent's `respond_to_finding` calls as their own rows, and notes for the other event kinds. Rows that hold a review (`Row.review`) are kept per review id and updated by each later `review.*` event. It is incremental: a new batch extends the existing rows. The composer bar's status (`StatusButton`, from `ChatModel.status`) shows the task's closed state, its working state, or what needs the user (`ChatModel.attention`: open questions, findings of the latest review that neither the user nor the agent has answered, and the current ready-for-merge overview); a click on one of the latter scrolls to the next one, wrapping, and on any other to the end; and when one of those rows closes the transcript scrolls to the next remaining one (`ChatModel.closed`). Jumps from elsewhere (`Store.jumpTo` with a `JumpTarget`: a summary, a question or a snapshot's review) select the task's transcript and scroll there once the row exists. The view is a `ScrollView` with a plain `VStack`, stuck to the bottom unless the user has scrolled more than 80 points up; while an attention row is held (`ChatModel.held`), being stuck instead keeps that row top-anchored, which the scroll view clamps to the bottom until the row reaches the top. The stack isn't lazy because a `LazyVStack` estimates the height of rows it hasn't shown yet and corrects it when they scroll into view, without moving the scroll offset, so scrolling up through rows not yet shown jumped by each correction; SwiftUI can't move the offset mid-scroll without stopping its momentum. While the user is scrolling (`onScrollPhaseChange`), content height changes only update whether it is stuck and never pull it back to the bottom. The lead pages back when the view comes within one screen of the top: the fetched page is held while the scroll phase is scrolling and inserted once it is idle (`ChatModel.older`, `prependOlder`), and the next geometry change moves the offset down by the height added, so the rows on screen stay put; a page that adds no rows (all folded `NO_REPLY` turns) fetches the next one at once. Each Markdown text run's `NSTextView` measures its height with one TextKit stack kept in its coordinator, and a repeat measurement at the same width and text returns the stored size. Pending sends show at the end until the server echoes them. A turn summary counts as read when its row is on screen and its server's window is the key window of the active app (`PaneFocus.windowKey`, `markSummaryRead`), checked again whenever the app activates or a window becomes key. An active task's head carries Compact (with its context-usage fill; a long press opens a menu of models to continue on), Sync from main, Merge and Discard; a closed task has no head, and its `task.merged` note is drawn with a ✓ in the ok colour.
- **Transcript and Lead.** `TranscriptBuilder` is a pure function from events to a list of rows: user and agent messages, consecutive tool calls, byre prompts and subagents folded into one group with its summary ("Read file ×3"), subagents nested with their status, pending tool calls and running subagents (background ones included after the turn ends) outlined in the accent colour with a 0.6s fade, thinking, the byre prompt collapsed, held turns, `NO_REPLY` turns folded away, handoffs, snapshot rows with changes, fork and review (and stop while the review runs), question bubbles that follow their item's `inbox.updated` events, a finished review as its summary row followed by one row per finding, the agent's `respond_to_finding` calls as their own rows, and notes for the other event kinds. Rows that hold a review (`Row.review`) are kept per review id and updated by each later `review.*` event. It is incremental: a new batch extends the existing rows. The composer bar's status (`StatusButton`, from `ChatModel.status`) shows the task's closed state, its working state, or what needs the user (`ChatModel.attention`: open questions, findings of the latest review that neither the user nor the agent has answered, and the current ready-for-merge overview); a click on one of the latter scrolls to the next one, wrapping, and on any other to the end; and when one of those rows closes the transcript scrolls to the next remaining one (`ChatModel.closed`). Jumps from elsewhere (`Store.jumpTo` with a `JumpTarget`: a summary, a question or a snapshot's review) select the task's transcript and scroll there once the row exists. The view is a `ScrollView` with a plain `VStack`, stuck to the bottom unless the user has scrolled more than 80 points up; while an attention row is held (`ChatModel.held`), being stuck instead keeps that row top-anchored, which the scroll view clamps to the bottom until the row reaches the top. The stack isn't lazy because a `LazyVStack` estimates the height of rows it hasn't shown yet and corrects it when they scroll into view, without moving the scroll offset, so scrolling up through rows not yet shown jumped by each correction; SwiftUI can't move the offset mid-scroll without stopping its momentum. While the user is scrolling (`onScrollPhaseChange`), content height changes only update whether it is stuck and never pull it back to the bottom. The lead pages back when the view comes within one screen of the top: the fetched page is held while the scroll phase is scrolling and inserted once it is idle (`ChatModel.older`, `prependOlder`), and the next geometry change moves the offset down by the height added, so the rows on screen stay put; a page that adds no rows (all folded `NO_REPLY` turns) fetches the next one at once. Each Markdown text run's `NSTextView` measures its height with one TextKit stack kept in its coordinator, and a repeat measurement at the same width and text returns the stored size. Pending sends show at the end until the server echoes them. A turn summary counts as read when its row is on screen and its server's window is the key window of the active app (`PaneFocus.windowKey`, `markSummaryRead`), checked again whenever the app activates or a window becomes key. An active task's head carries Compact (with its context-usage fill; a long press opens a menu of models to continue on), Sync from main, Merge and Discard; a closed task has no head, and its `task.merged` note is drawn with a ✓ in the ok colour.
- **Composer.** A `TextEditor`, with paste and drop handled as in "Gaps in SwiftUI". Text, the model menu (filtered to the live session's vendor), Interrupt and Send. Enter sends, Shift-Enter adds a newline, and Enter during IME composition does neither. Pasted or dropped PNG, JPEG, GIF and WebP images become thumbnails with ×, uploaded to `POST /api/blobs` on send; any other image `NSBitmapImageRep` decodes, such as TIFF, is converted to PNG first, its size checked after conversion. A failed send puts the text and images back and shows the error. The ⌄/⌃ button collapses the text box (with its thumbnails) into the bar and brings it back; it is collapsed by default while the task has an open question or is merged or discarded (`ChatModel.composerHiddenByDefault`), and the human's choice holds until that default changes or an explicit focus request (picking the task in the switcher, focusing the lead) opens it; the automatic focus of a task with no session yet only focuses a box that is shown.
- **Questions.** An open question's bubble in the transcript holds its card, rendered from its Markdown context with each choice's marker replaced by a clickable block (pick-one, sends at once, with any Other… text as notes) or checkbox (pick-any, with Submit), the "recommended" tag, image-choice grids, attachments, Let the agent decide and Other…. Arrow keys move between choices. A 409 shows its error. Once answered or dismissed, the bubble shrinks to the question and who answered what.
- **Changes, Files, Workflow, Project, Status, Settings.** Including the pinned-snapshot stepper, open-diff memory, per-task place in Files, nested subtasks, TODO Start and Discuss, rate-limit pace bars and lead notes. The Workflow tab draws its stage graph natively from the `WorkflowRun` (stages as boxes coloured by state, `after` as edges, laid out top to bottom by depth) with the layout and drawing code from "Diagrams", fed from the run's data rather than Mermaid text.
+4 -4
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -24,7 +24,7 @@ const guidance = `You are running inside byre. The human reads your work in byre
- TODO.md at the repo root is the project's list of work for byre; its format is the read_knowledge article todo-file.`
const proseQuestionNudge = "Your final message asks the human something in prose. Ask it with byre's ask_human tool " +
"(context with the choices inline as `- ( ) choice` / `- (*) recommended` or `- [ ] choice` / `- [x] recommended` list items, question, why_blocked), " +
"(context with the choices inline as `- ( ) choice` / `- (*) recommended` or `- [ ] choice` / `- [x] recommended` list items, and question)," +
"then end your turn with a short summary."
var (
+1 -7
View File
@@ -24,7 +24,6 @@ var attachmentKinds = []api.AttachmentKind{
type askArgs struct {
Context string `json:"context"`
Question string `json:"question"`
WhyBlocked string `json:"why_blocked"`
Attachments []api.Attachment `json:"attachments"`
ThreadID string `json:"thread_id"`
}
@@ -58,7 +57,6 @@ func (m *Manager) askTool(l *live) mcp.Tool {
"properties": {
"context": {"type": "string", "description": "Everything the human needs to answer well without reading your transcript: what you are working on, what you found, the relevant facts and data shared by all the choices, and then the choices. Markdown is rendered. Each choice is a list item, at least two, all of one kind: '- ( ) Merge now' / '- (*) Wait for review' (pick one; exactly one (*) marks your recommendation), or '- [ ] Fix the tests' / '- [x] Update the docs' (pick any; [x] marks the ones you recommend). The choice's first line, after the marker, is a short name that comes back verbatim as the answer. Everything about that one choice goes in lines indented two spaces beneath it, not in a paragraph above the list: what it would concretely do, its worked example, any code block, command or sub-list, and its trade-offs. For example:\n\n- ( ) Retry in the client\n Wraps ` + "`fetch` in `retry(3)`" + `; a 500 shows the spinner up to 6s longer.\n ` + "```" + `ts\n await retry(3, () => api.get(path));\n ` + "```" + `\n- (*) Queue on the server\n The request returns at once; the write lands within 1s.\n\nPut long supporting detail (logs, full data, per-option analysis) in collapsed sections the human expands on demand: a line '<details><summary>Title</summary>', the Markdown content, then a line '</details>'."},
"question": {"type": "string", "description": "The question itself, in one or two sentences. Markdown is rendered."},
"why_blocked": {"type": "string", "description": "What you can't do until this is answered, and why you can't decide it yourself."},
"attachments": {"type": "array", "items": {
"type": "object",
"properties": {
@@ -77,7 +75,7 @@ func (m *Manager) askTool(l *live) mcp.Tool {
}},
"thread_id": {"type": "string"}
},
"required": ["context", "question", "why_blocked"]
"required": ["context", "question"]
}`),
Handler: func(ctx context.Context, raw json.RawMessage) (string, error) {
return m.ask(ctx, l, raw)
@@ -121,7 +119,6 @@ func (m *Manager) ask(ctx context.Context, l *live, raw json.RawMessage) (string
payload := map[string]any{
"context": args.Context,
"question": args.Question,
"why_blocked": args.WhyBlocked,
"options": options,
"multiple": choices[0].checkbox,
"recommended": recommended,
@@ -259,9 +256,6 @@ func (m *Manager) validateAsk(ctx context.Context, l *live, args askArgs) error
if strings.TrimSpace(args.Question) == "" {
problems = append(problems, "question is empty")
}
if strings.TrimSpace(args.WhyBlocked) == "" {
problems = append(problems, "why_blocked is empty: say what you can't do until this is answered and why you can't decide it yourself")
}
choices := parseChoices(args.Context)
if len(choices) < 2 {
problems = append(problems, "context needs at least two choices, each a list item on its own line: `- ( ) choice` (pick one) or `- [ ] choice` (pick any)")
+1 -1
View File
@@ -641,7 +641,7 @@ func (m *Manager) itemText(ctx context.Context, item api.InboxItem) string {
}
fmt.Fprintf(b, "- %s%s\n", clip(o, 300), mark)
}
fmt.Fprintf(b, "Blocked on: %v\nThe full context is in read_inbox.", p["why_blocked"])
b.WriteString("The full context is in read_inbox.")
return b.String()
}
+3
View File
@@ -723,6 +723,9 @@ func (m *Manager) recordMessage(ctx context.Context, sess api.AgentSession, task
if isContinuation(actor, text) {
payload["continuation"] = true
}
if isFindingsMessage(actor, text) {
payload["findings"] = true
}
err = m.store.RecordTurnMessage(ctx, sess.Id, newEvent(sess.Id, sess.Owner, task.ProjectId, task.Id, actor, "user.message", payload))
if err != nil {
return nil, false, err
+5 -1
View File
@@ -256,7 +256,11 @@ func (m *Manager) recordQueued(ctx context.Context, l *live, msgs []queued) stri
if l.implementer() && isMergeInPrompt(q.actor, q.text) {
m.takeMergeTurn(l)
}
err := m.emit(ctx, l, q.actor, "user.message", map[string]any{"text": q.text, "mid_turn": true})
payload := map[string]any{"text": q.text, "mid_turn": true}
if isFindingsMessage(q.actor, q.text) {
payload["findings"] = true
}
err := m.emit(ctx, l, q.actor, "user.message", payload)
if err != nil {
slog.Error("record mid-turn message", "session", l.id, "err", err)
}
+7 -1
View File
@@ -358,13 +358,19 @@ func (m *Manager) forwardFindings(taskID, reviewID string) {
slog.Info("review findings forwarded", "review", reviewID, "session", s.Id)
}
const findingsPreamble = "A reviewer looked at snapshot #"
func isFindingsMessage(actor, text string) bool {
return actor == "byre" && strings.HasPrefix(text, findingsPreamble)
}
func findingsMessage(r api.Review) string {
res := map[string]any{}
if r.Result != nil {
res = *r.Result
}
b := &strings.Builder{}
fmt.Fprintf(b, "A reviewer looked at snapshot #%d of your work and raised the findings below. Reviewers can be wrong or miss context: check each one against the code and your brief. "+
fmt.Fprintf(b, findingsPreamble+"%d of your work and raised the findings below. Reviewers can be wrong or miss context: check each one against the code and your brief. "+
"Before you change anything, answer each finding with respond_to_finding (snapshot %d and the finding's number): fixing if it holds up and you'll act on it, ignoring with your reason if you're leaving it. "+
"The human sees your answers on the findings and can overrule an ignore.", r.SnapshotN, r.SnapshotN)
findings, _ := res["findings"].([]any)
+232 -232
View File
@@ -938,7 +938,7 @@ type InboxItem struct {
CreatedAt time.Time `json:"created_at"`
Id string `json:"id"`
// Payload context (Markdown with the choices inline as `- ( ) text` / `- (*) text` pick-one or `- [ ] text` / `- [x] text` pick-any list items), question, why_blocked, options (each choice's text, in order), multiple (true for pick-any), recommended (the marked choices' text), attachments.
// Payload context (Markdown with the choices inline as `- ( ) text` / `- (*) text` pick-one or `- [ ] text` / `- [x] text` pick-any list items), question, options (each choice's text, in order), multiple (true for pick-any), recommended (the marked choices' text), attachments.
Payload map[string]interface{} `json:"payload"`
ProjectId string `json:"project_id"`
ResolvedAt *time.Time `json:"resolved_at,omitempty"`
@@ -4197,237 +4197,237 @@ var swaggerSpec = []string{
"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",
}
// decodeSpec returns the embedded OpenAPI spec as raw JSON bytes,
+1 -1
View File
@@ -146,7 +146,7 @@ final class ChatModel {
}
func working(_ row: Row) -> Bool {
row.pending && (running || subagents && row.inActive) || row.active && (running || subagents)
row.pending && (running || subagents && row.inActive) || row.holdsActive && (running || subagents)
}
var hasOlder: Bool {
+13 -22
View File
@@ -300,19 +300,27 @@ private struct CardBody: View {
var body: some View {
let p = model.payload
let item = model.item
let split = model.context.firstIndex(where: choiceList) ?? model.context.count
VStack(alignment: .leading, spacing: 0) {
MarkdownView(blocks: model.context, ctx: contextCtx)
.onGeometryChange(for: Bool.self) { $0.size.width > 480 } action: { wide = $0 }
.padding(.vertical, 10)
MarkdownView(blocks: Array(model.context[..<split]), ctx: contextCtx)
.padding(.top, 10)
if question {
MarkdownView(blocks: parseMarkdown(jsString(p["question"] ?? "")), ctx: MDContext(taskId: item.taskId))
.padding(.top, 10)
.padding(.bottom, 4)
}
WhyLine(text: jsString(p["why_blocked"] ?? ""), taskId: item.taskId)
MarkdownView(blocks: Array(model.context[split...]), ctx: contextCtx)
.padding(.top, 10)
.padding(.bottom, 8)
Attachments(list: attachments(p["attachments"] ?? nil), taskId: item.taskId)
}
.onGeometryChange(for: Bool.self) { $0.size.width > 480 } action: { wide = $0 }
}
private func choiceList(_ block: MDBlock) -> Bool {
if case .list(_, _, let items, _) = block {
return items.contains { $0.choice != nil }
}
return false
}
private func attachments(_ v: (any Sendable)?) -> [Attachment] {
@@ -328,23 +336,6 @@ private struct CardBody: View {
}
}
private struct WhyLine: View {
let text: String
let taskId: String
@Environment(Store.self) private var store
var body: some View {
var out = AttributedString("Blocked on: ")
out.foregroundColor = Palette.text
var rest = InlineRenderer(store: store, size: 13, taskId: taskId).text(parseInline(text))
rest.foregroundColor = rest.foregroundColor ?? Palette.muted
return Text(out + rest)
.foregroundStyle(Palette.muted)
.textSelection(.enabled)
.fixedSize(horizontal: false, vertical: true)
}
}
private struct ChoiceBox: View {
let model: CardModel
let item: MDItem
+42 -15
View File
@@ -105,6 +105,13 @@ final class Row: Identifiable {
}
}
var holdsActive: Bool {
if case .group = kind {
return body!.rows.contains { $0.active }
}
return active
}
var inActive: Bool {
var o = owner
while let r = o {
@@ -300,7 +307,7 @@ final class TranscriptBuilder {
!parent.isEmpty && ctx.subagents[parent] == nil
}
private func addToRun(_ row: Row, _ call: Call, _ parent: String) {
private func addToRun(_ row: Row, _ call: Call?, _ parent: String) {
if let sub = ctx.subagents[parent] {
sub.run = extendRun(sub.run, row, call, parent) { r in
sub.row.body!.rows.append(r)
@@ -313,12 +320,14 @@ final class TranscriptBuilder {
}
}
private func extendRun(_ run: Run?, _ row: Row, _ call: Call, _ parent: String, _ place: (Row) -> RowList) -> Run {
private func extendRun(_ run: Run?, _ row: Row, _ call: Call?, _ parent: String, _ place: (Row) -> RowList) -> Run {
guard let run, run.parent == parent else {
let list = place(row)
return Run(first: row, container: list, calls: [call], parent: parent)
return Run(first: row, container: list, calls: call.map { [$0] } ?? [], parent: parent)
}
if let call {
run.calls.append(call)
}
run.calls.append(call)
if run.group == nil {
let group = Row(.group, taskId: rowTask, body: true)
group.owner = ctx.subagents[parent]?.row
@@ -383,6 +392,7 @@ final class TranscriptBuilder {
private func openHandoff() {
let row = Row(.handoff, taskId: rowTask, body: true)
row.summary = Note(parts: [.text("writing a handoff…")])
ctx.run = nil
put(row)
ctx.handoff = row
}
@@ -497,8 +507,11 @@ final class TranscriptBuilder {
row.review = r
}
if ev.kind == "review.finished" {
ctx.run = nil
for row in renderReview(r, ev.createdAt) {
let rows = renderReview(r, ev.createdAt)
if !rows.isEmpty {
ctx.run = nil
}
for row in rows {
put(row)
}
continue
@@ -518,8 +531,7 @@ final class TranscriptBuilder {
sub.row.body!.rows.append(row)
continue
}
ctx.run = nil
put(row, keepHeld: true)
addToRun(row, Call(name: jsString(p["name"]), target: ""), parent)
continue
}
if ev.kind == "agent.tool_call" && sub == nil && str(p, "name") == "mcp__byre__respond_to_finding" {
@@ -540,6 +552,9 @@ final class TranscriptBuilder {
let name = toolLabel(jsString(p["name"]))
let row = renderToolCall(p)
row.started = ev.createdAt
if name == "ToolSearch" {
continue
}
addToRun(row, Call(name: name, target: toolTarget(p["input"] ?? nil, worktree())), parent)
continue
}
@@ -551,7 +566,11 @@ final class TranscriptBuilder {
sub.row.body!.rows.append(row)
continue
}
ctx.run = nil
let prompt = if case .byrePrompt = row.kind { true } else { false }
let agentNote = if case .note = row.kind, ev.actor == "agent" { true } else { false }
if !prompt && !agentNote {
ctx.run = nil
}
if ev.kind == "agent.message" && parent.isEmpty {
ctx.drawn = nil
ctx.reply = row
@@ -577,6 +596,7 @@ final class TranscriptBuilder {
ctx.drawn = nil
}
if ev.kind == "user.message" && ev.actor == "byre" && !(ev.owner ?? "").isEmpty && !bool(p, "mid_turn") && !bool(p, "handoff") {
ctx.run = nil
ctx.held = RowList()
ctx.open = false
ctx.drawn = []
@@ -597,6 +617,11 @@ final class TranscriptBuilder {
if (ev.kind == "inbox.created" || ev.kind == "task.ready_cleared") && sink == nil && own {
lastReady = nil
}
if prompt && !row.hidden || agentNote {
release()
addToRun(row, agentNote ? nil : Call(name: "byre", target: ""), parent)
continue
}
put(row, keepHeld: ev.kind == "agent.thinking")
}
return contextChanged
@@ -659,9 +684,12 @@ final class TranscriptBuilder {
}
private func renderReview(_ r: Review, _ when: Date) -> [Row] {
let outcome = r.state == .failed ? "failed: \(r.error)" : r.state == .skipped ? "skipped: no changes" : reviewCounts(r)
let parts: [NotePart] = [.text("review of snapshot #\(r.snapshotN): \(outcome)")]
let fs = findings(r)
if fs.isEmpty && r.state != .failed {
return []
}
let outcome = r.state == .failed ? "failed: \(r.error)" : reviewCounts(r)
let parts: [NotePart] = [.text("review of snapshot #\(r.snapshotN): \(outcome)")]
let head = fs.isEmpty
? Row(.note(Note(parts: parts, when: when, style: r.state == .failed ? .error : .plain)), taskId: rowTask)
: Row(.review(note: Note(parts: parts, when: when), md: parseMarkdown(str(r.result?.value ?? [:], "summary") ?? "")), taskId: rowTask)
@@ -692,7 +720,7 @@ final class TranscriptBuilder {
let first = text.components(separatedBy: "\n").first ?? ""
let brief = first.count > 120 ? "\(first.prefix(120))…" : first
let row = Row(.byrePrompt(brief: brief, when: when, md: parseMarkdown(text)), taskId: rowTask)
row.hidden = bool(p, "continuation")
row.hidden = bool(p, "continuation") || bool(p, "findings")
return row
}
let images = (p["images"] as? [(any Sendable)?] ?? []).map { jsString($0) }
@@ -886,11 +914,10 @@ private func isSubagentCall(_ p: JSONDict) -> Bool {
}
func toolLabel(_ name: String) -> String {
let prefix = "mcp__byre__"
if !name.hasPrefix(prefix) {
guard name.hasPrefix("mcp__"), let sep = name.dropFirst(5).range(of: "__") else {
return name
}
return name.dropFirst(prefix.count).split(separator: "_", omittingEmptySubsequences: false).map { $0.prefix(1).uppercased() + $0.dropFirst() }.joined(separator: " ")
return name[sep.upperBound...].split(separator: "_", omittingEmptySubsequences: false).map { $0.prefix(1).uppercased() + $0.dropFirst() }.joined(separator: " ")
}
private func toolBrief(_ input: (any Sendable)?, _ root: String) -> String {