Render selected PromptKit report formats

This commit is contained in:
2026-10-09 01:24:51 +00:00
parent a431540e19
commit 628dc78083
2 changed files with 61 additions and 19 deletions

View File

@@ -1,6 +1,6 @@
# Performance implementation plan # Performance implementation plan
Status: implementation in progress; Stages 1–2 are complete, Stages 3–11 have not started. Status: implementation in progress; Stages 1–3 are complete, Stages 4–11 have not started.
Date: 2026-10-09. Date: 2026-10-09.
@@ -312,7 +312,7 @@ they are not fixed thresholds or speedup claims.
## Stage 3: render only the selected PromptKit format ## Stage 3: render only the selected PromptKit format
**Status:** not started. **Prerequisite:** Stage 2. **Status:** complete. **Prerequisite:** Stage 2.
**Files:** [promptkit.go](../../promptkit.go), **Files:** [promptkit.go](../../promptkit.go),
[promptkit_test.go](../../promptkit_test.go), relevant report benchmarks, and [promptkit_test.go](../../promptkit_test.go), relevant report benchmarks, and
@@ -342,7 +342,37 @@ report confidentiality; this change introduces no redaction policy.
**Completion:** YAML requests do not construct text reports, and text delivery **Completion:** YAML requests do not construct text reports, and text delivery
has no redundant intermediate builder. has no redundant intermediate builder.
**Evidence:** pending. **Evidence:** `go test -mod=readonly -count=1 .` passed with the workspace,
local toolchain, and offline environment settings from the measurement protocol.
The same five-sample report fixtures passed with:
`GOWORK=off GOTOOLCHAIN=local GOPROXY=off GONOPROXY=none GOSUMDB=off go test -mod=readonly -run '^$' -bench '^BenchmarkPerformancePromptReports$' -benchmem -benchtime=200ms -count=5 .`.
The environment matched Stage 2: Go 1.26.8, linux/amd64, Linux
6.17.0-41-generic, Intel Core i5-7260U CPU @ 2.20 GHz. The measured source was
revision `a431540` plus the `promptkit.go` working-tree change committed with
this evidence. Raw output is in `/tmp/commandkit-performance-prompt-after.txt`.
Every five-sample report case reduced allocation count. Prompt, 4 inputs, text
changed from 41,287–52,115 ns/op, 26,160–26,161 B/op, 294 allocs/op to
29,898–35,259 ns/op, 25,280–25,282 B/op, 291 allocs/op; YAML changed from
88,991–104,671 ns/op, 74,730–74,733 B/op, 557 allocs/op to 83,454–91,286
ns/op, 71,853–71,855 B/op, 505 allocs/op. Prompt, 128 inputs, text changed
from 169,155–198,281 ns/op, 145,524–145,531 B/op, 1,171 allocs/op to
161,185–185,023 ns/op, 128,960–128,966 B/op, 1,168 allocs/op; YAML changed
from 1,418,692–1,490,181 ns/op, 1,393,508–1,393,568 B/op, 6,039–6,040
allocs/op to 1,255,623–1,360,926 ns/op, 1,264,474–1,264,486 B/op, 5,104
allocs/op.
Profile, small extra map, text changed from 74,109–89,337 ns/op,
70,914–70,918 B/op, 462 allocs/op to 75,818–88,197 ns/op, 69,955–69,959
B/op, 459 allocs/op; the timing ranges overlap. YAML changed from
161,470–368,813 ns/op, 162,688–162,717 B/op, 755 allocs/op to 107,244–127,744
ns/op, 114,793–114,795 B/op, 533 allocs/op. Profile, large extra map, text
changed from 1,277,396–2,583,950 ns/op, 836,141–836,296 B/op, 3,027–3,028
allocs/op to 839,692–936,229 ns/op, 826,407–826,448 B/op, 3,024 allocs/op;
YAML changed from 1,756,571–2,377,499 ns/op, 1,586,728–1,586,849 B/op,
5,878–5,879 allocs/op to 796,779–976,685 ns/op, 780,391–780,436 B/op,
3,086 allocs/op. These results confirm that YAML requests avoid text-report
construction; text requests retain their report semantics and formatting errors.
## Stage 4: index backend declarations and traverse parents ## Stage 4: index backend declarations and traverse parents

View File

@@ -1,10 +1,10 @@
package commandkit package commandkit
import ( import (
"bytes"
"context" "context"
"errors" "errors"
"fmt" "fmt"
"io"
"strconv" "strconv"
"strings" "strings"
@@ -290,7 +290,17 @@ func runPromptKitPrompt[C any](invocation Invocation, suite PromptKitSuite[C], i
return promptKitFailure(fmt.Errorf("PromptKit prompt inspection returned no result"), acquired.Diagnostics) return promptKitFailure(fmt.Errorf("PromptKit prompt inspection returned no result"), acquired.Diagnostics)
} }
report := promptReportFromInspection(acquired.Value) report := promptReportFromInspection(acquired.Value)
return writePromptKitReport(invocation, input.Format, report, formatPromptText(report), acquired.Diagnostics) var output []byte
if input.Format == "yaml" {
var buffer bytes.Buffer
if err := encodeYAML(&buffer, report); err != nil {
return promptKitFailure(err, acquired.Diagnostics)
}
output = buffer.Bytes()
} else {
output = []byte(formatPromptText(report))
}
return writePromptKitReport(invocation, output, acquired.Diagnostics)
} }
func runPromptKitProfile[C any](invocation Invocation, suite PromptKitSuite[C], input promptKitInput[C]) Outcome { func runPromptKitProfile[C any](invocation Invocation, suite PromptKitSuite[C], input promptKitInput[C]) Outcome {
@@ -312,11 +322,21 @@ func runPromptKitProfile[C any](invocation Invocation, suite PromptKitSuite[C],
return promptKitFailure(fmt.Errorf("PromptKit profile inspection returned no result"), acquired.Diagnostics) return promptKitFailure(fmt.Errorf("PromptKit profile inspection returned no result"), acquired.Diagnostics)
} }
report := profileReportFromInspection(acquired.Value) report := profileReportFromInspection(acquired.Value)
textReport, err := formatProfileText(report) var output []byte
if err != nil { if input.Format == "yaml" {
return promptKitFailure(err, acquired.Diagnostics) var buffer bytes.Buffer
if err := encodeYAML(&buffer, report); err != nil {
return promptKitFailure(err, acquired.Diagnostics)
}
output = buffer.Bytes()
} else {
textReport, err := formatProfileText(report)
if err != nil {
return promptKitFailure(err, acquired.Diagnostics)
}
output = []byte(textReport)
} }
return writePromptKitReport(invocation, input.Format, report, textReport, acquired.Diagnostics) return writePromptKitReport(invocation, output, acquired.Diagnostics)
} }
func promptKitFailure(err error, diagnostics []Diagnostic) Outcome { func promptKitFailure(err error, diagnostics []Diagnostic) Outcome {
@@ -325,19 +345,11 @@ func promptKitFailure(err error, diagnostics []Diagnostic) Outcome {
return outcome return outcome
} }
func writePromptKitReport(invocation Invocation, format string, report any, textReport string, diagnostics []Diagnostic) Outcome { func writePromptKitReport(invocation Invocation, output []byte, diagnostics []Diagnostic) Outcome {
var output strings.Builder
if format == "yaml" {
if err := encodeYAML(&output, report); err != nil {
return promptKitFailure(err, diagnostics)
}
} else if _, err := io.WriteString(&output, textReport); err != nil {
return promptKitFailure(err, diagnostics)
}
if err := invocation.Context.Err(); err != nil { if err := invocation.Context.Err(); err != nil {
return promptKitFailure(err, diagnostics) return promptKitFailure(err, diagnostics)
} }
if err := writeReport(invocation.Streams.Out, []byte(output.String())); err != nil { if err := writeReport(invocation.Streams.Out, output); err != nil {
outcome := incompleteReport(err) outcome := incompleteReport(err)
outcome.Diagnostics = diagnostics outcome.Diagnostics = diagnostics
return outcome return outcome