|
5 | 5 | "strconv" |
6 | 6 | "strings" |
7 | 7 |
|
| 8 | + gcf "github.com/blackwell-systems/gcf-go" |
8 | 9 | "github.com/speakeasy-api/openapi/graph" |
9 | 10 | "github.com/speakeasy-api/openapi/oq/expr" |
10 | 11 | "gopkg.in/yaml.v3" |
@@ -221,6 +222,54 @@ func FormatToon(result *Result, g *graph.SchemaGraph) string { |
221 | 222 | return sb.String() |
222 | 223 | } |
223 | 224 |
|
| 225 | +// FormatGCF formats a result using GCF (Graph Compact Format). |
| 226 | +// GCF uses positional pipe-delimited rows with inline schemas, achieving |
| 227 | +// higher LLM comprehension accuracy than TOON or JSON (90.7% vs 68.5% vs 53.6%). |
| 228 | +// See https://gcformat.com |
| 229 | +func FormatGCF(result *Result, g *graph.SchemaGraph) string { |
| 230 | + if result.Explain != "" { |
| 231 | + return result.Explain |
| 232 | + } |
| 233 | + |
| 234 | + if result.IsCount { |
| 235 | + return gcf.EncodeGeneric(map[string]interface{}{"count": result.Count}) |
| 236 | + } |
| 237 | + |
| 238 | + syncGroupsFromRows(result) |
| 239 | + |
| 240 | + if len(result.Rows) == 0 { |
| 241 | + return gcf.EncodeGeneric([]interface{}{}) |
| 242 | + } |
| 243 | + |
| 244 | + fields := result.Fields |
| 245 | + if len(fields) == 0 { |
| 246 | + fields = resolveDefaultFields(result.Rows) |
| 247 | + } |
| 248 | + |
| 249 | + rows := make([]interface{}, 0, len(result.Rows)) |
| 250 | + for _, row := range result.Rows { |
| 251 | + m := make(map[string]interface{}, len(fields)) |
| 252 | + for _, f := range fields { |
| 253 | + v := fieldValue(row, f, g) |
| 254 | + switch v.Kind { |
| 255 | + case expr.KindString: |
| 256 | + m[f] = v.Str |
| 257 | + case expr.KindInt: |
| 258 | + m[f] = v.Int |
| 259 | + case expr.KindBool: |
| 260 | + m[f] = v.Bool |
| 261 | + case expr.KindArray: |
| 262 | + m[f] = v.Arr |
| 263 | + default: |
| 264 | + m[f] = nil |
| 265 | + } |
| 266 | + } |
| 267 | + rows = append(rows, m) |
| 268 | + } |
| 269 | + |
| 270 | + return gcf.EncodeGeneric(rows) |
| 271 | +} |
| 272 | + |
224 | 273 | // FormatYAML formats results as raw YAML from the underlying schema/operation objects. |
225 | 274 | // For multiple results, outputs a YAML stream with --- separators. |
226 | 275 | // This enables piping into yq for content-level queries. |
|
0 commit comments