Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

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

未关闭 适合新手
#76 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

评估

难度
2/5
预计耗时
1-3 小时
新手友好度
78/100
Issue 类型
缺陷
描述清晰度
描述清楚
活跃度
冷清
技术栈
typescript, yaml
领域
tooling

调研方向

从 src/reporters/yaml.ts 开始,检查现有的 YAML reporter 测试,该测试目前只检查序列化后的子字符串。在更改 structuredOutput 路径之前运行该测试。当 YAML parser 返回一个对象形式的 structuredOutput,且其中包含与输入相同的嵌套数据,同时现有的报告行为保持不变时,即表示完成。

由索引模型根据 Issue 内容生成。

描述

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.

主要语言
TypeScript
星标
2
派生
1
PR 合并指标
30 天内没有已合并 PR

环境准备

这个项目没有提供开发容器、Dockerfile 或贡献指南,环境需要你自己搭建:先看它的 README,通用步骤见我们的新手贡献指南。

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

joewalker/loop-the-loop 的其他 Issue

查看 joewalker/loop-the-loop 的全部 Issue

相似的 Issue

更多 TypeScript Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。