YamlReporter: structuredOutput is stored as a JSON-encoded string inside a block scalar, not as native YAML data
还没有人认领这个 Issue。
评估
- 难度
- 2/5
- 预计耗时
- 1-3 小时
- 新手友好度
- 78/100
- Issue 类型
- 缺陷
- 描述清晰度
- 描述清楚
- 活跃度
- 冷清
- 技术栈
- typescript, yaml
- 领域
- tooling
调研方向
从 src/reporters/yaml.ts 开始,检查现有的 YAML reporter 测试,该测试目前只检查序列化后的子字符串。在更改 structuredOutput 路径之前运行该测试。当 YAML parser 返回一个对象形式的 structuredOutput,且其中包含与输入相同的嵌套数据,同时现有的报告行为保持不变时,即表示完成。
由索引模型根据 Issue 内容生成。
描述
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,通用步骤见我们的新手贡献指南。
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
joewalker/loop-the-loop 的其他 Issue
-
bug S4
难度 2/5 1-3 小时 新手友好度 75/100
joewalker/loop-the-loop#88 ·
-
Git exec(): child killed by a signal rejects with new Error('') and loses the signal information未关闭bug S3
难度 2/5 1-3 小时 新手友好度 82/100
joewalker/loop-the-loop#84 ·
-
bug S3
难度 2/5 1-3 小时 新手友好度 78/100
joewalker/loop-the-loop#83 ·
-
bug S3
难度 2/5 1-3 小时 新手友好度 76/100
joewalker/loop-the-loop#82 ·
-
bug S4
难度 1/5 1 小时以内 新手友好度 90/100
joewalker/loop-the-loop#79 ·
查看 joewalker/loop-the-loop 的全部 Issue
相似的 Issue
-
bug hacktoberfest help wanted
难度 2/5 1-3 小时 新手友好度 82/100
libredb/libredb-studio#1941 ·
维护者通常 1 天内回复
-
chore other
难度 2/5 1-3 小时 新手友好度 78/100
alastair-smith/card-games#308 ·
维护者通常 1 天内回复
-
难度 1/5 1 小时以内 新手友好度 86/100
paperclipai/paperclip#17379 ·
维护者通常 1 天内回复
-
[good first issue, hacktoberfest] 🏯 Hacktoberfest Task - Add new Anime Quote 626 (good-first-issue)未关闭community first-timers-only good first issue hacktoberfest help wanted low hanging fruit up-for-grabs
难度 1/5 1 小时以内 新手友好度 76/100
lingdojo/kana-dojo#33040 · 1 条评论 · 5 个 reaction ·
维护者通常 1 天内回复
-
bug mobile ui
难度 2/5 1-3 小时 新手友好度 88/100
维护者通常 1 天内回复