Hacktoberfest 2026: những issue maintainer đã đánh dấu cho tháng Mười, đang mở và phù hợp người mới. Xem issue Hacktoberfest

YamlReporter: structuredOutput is stored as a JSON-encoded string inside a block scalar, not as native YAML data

Đang mở Phù hợp với người mới
#76 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

Đánh giá

Độ khó
2/5
Thời gian dự kiến
1-3 giờ
Mức phù hợp với người mới
78/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Ít trao đổi
Công nghệ
typescript, yaml
Lĩnh vực
tooling

Hướng nghiên cứu

Bắt đầu trong src/reporters/yaml.ts và kiểm tra test YAML reporter hiện có, hiện chỉ kiểm tra các chuỗi con đã được serialize. Chạy test đó trước khi thay đổi đường dẫn structuredOutput. Hoàn thành khi một YAML parser trả về structuredOutput dưới dạng một object có cùng dữ liệu lồng nhau như đầu vào, đồng thời hành vi report hiện có vẫn được giữ nguyên.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

bug S3

Observed behavior

When a successful result includes structuredOutput, YamlReporter.append serialises it by JSON.stringify'ing the value and writing the resulting text into a YAML block scalar:

// src/reporters/yaml.ts
if (result.structuredOutput !== undefined) {
  lines.push('structuredOutput: |');
  const json = JSON.stringify(result.structuredOutput, null, 2);
  for (const line of formatBlockScalar(json).split('\n')) {
    lines.push(line === '' ? /* istanbul ignore next */ '' : `  ${line}`);
  }
}

A consumer parsing the report file with any YAML loader gets back structuredOutput as a string containing JSON, not as the structured object the agent produced. To use the data they have to do a second JSON.parse step that they would not have to do for any other field in the report.

This is inconsistent with JsonlReporter, which spreads the result into the output line:

// src/reporters/jsonl.ts
const output = `${JSON.stringify({ ...prompt, ...result })}\n`;

For the JSONL reporter, structuredOutput round-trips as a nested object, so a consumer can read entry.structuredOutput.found directly. Switching the configured reporter from JSONL to YAML (or to the default, which is YAML) silently changes the shape of structuredOutput from "structured object" to "JSON-encoded string".

The existing test only asserts that the YAML contains the substrings "found": true and "a.ts": "bug", so the bug is not caught.

Expected behavior

structuredOutput is documented in src/types.ts as "the parsed object that conforms to the schema". A reporter that persists a result entry should preserve that shape: parsing the YAML report should yield an object, not a string. This is also what users will expect from a structured-data report format.

Minimal reproduction

import { mkdtemp, readFile } from 'node:fs/promises';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import { parseAllDocuments } from 'yaml';

import { YamlReporter } from 'loop-the-loop/reporters/yaml';

const dir = await mkdtemp(join(tmpdir(), 'yaml-structured-bug-'));
const reporter = await YamlReporter.create({ outputDir: dir, jobName: 'demo' });

await reporter.append(
  { id: 'a', prompt: 'p' },
  {
    status: 'success',
    output: 'ok',
    structuredOutput: { found: true, items: ['a', 'b'] },
  },
);

const text = await readFile(join(dir, 'demo-report.yaml'), 'utf-8');
const obj = parseAllDocuments(text)[0].toJS();

console.log(typeof obj.structuredOutput);    // 'string'
console.log(obj.structuredOutput.found);     // undefined
console.log(JSON.parse(obj.structuredOutput).found); // true

Suggested fix

Emit structuredOutput as native YAML so it round-trips as an object. The minimal change is to use a YAML serializer for this single field (the rest of the entry could stay hand-written for now):

import { stringify } from 'yaml';

if (result.structuredOutput !== undefined) {
  // `stringify` returns a trailing newline; indent under the parent key
  const yaml = stringify(result.structuredOutput, { indent: 2 });
  lines.push('structuredOutput:');
  for (const line of yaml.trimEnd().split('\n')) {
    lines.push(`  ${line}`);
  }
}

The longer-term fix is to delegate serialization of the whole entry to a YAML library, which also resolves the related issues #69 (id field not escaped) and #75 (block scalar indent bug). A test that round-trips structuredOutput through a real YAML parser and asserts deep-equality with the input would prevent regression.

Ngôn ngữ chính
TypeScript
Star
2
Fork
1
Chỉ số merge pull request
Không có pull request nào được merge trong 30 ngày

Chuẩn bị môi trường

Dự án này không cung cấp dev container, Dockerfile hay hướng dẫn đóng góp, nên bạn cần tự thiết lập môi trường: hãy bắt đầu từ README và xem hướng dẫn đóng góp lần đầu của chúng tôi để biết các bước chung.

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của joewalker/loop-the-loop

Tất cả issue của joewalker/loop-the-loop

Issue tương tự

Thêm issue về TypeScript

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.