Skip to content

fix(providers/pi): tolerate prose preamble in structured-output responses#1440

Merged
Wirasm merged 3 commits intodevfrom
fix/pi-parse-prose-preamble
Apr 29, 2026
Merged

fix(providers/pi): tolerate prose preamble in structured-output responses#1440
Wirasm merged 3 commits intodevfrom
fix/pi-parse-prose-preamble

Conversation

@Wirasm
Copy link
Copy Markdown
Collaborator

@Wirasm Wirasm commented Apr 27, 2026

Summary

  • Problem: 7 of 10 maintainer-review-pr runs in a single sequential batch this afternoon silently failed at the gate node — Pi/Minimax M2.7 wraps its JSON response in a reasoning preamble ("Now I have all the inputs. Let me evaluate..."), the existing tryParseStructuredOutput returns undefined, the gate's verdict field is unreadable, every when: branch fails-closed, and no review comment is posted.
  • Why it matters: maintainer-review-pr is currently the primary use case for Pi/Minimax in this repo (cost-driven). A 70% silent-failure rate makes the cost optimization a net loss.
  • What changed: Adds two preamble-tolerant fallback tiers to tryParseStructuredOutput. Tier 2 scans backward to the last { (handles flat JSON after preamble — the M2.7 case). Tier 3 scans forward to the first { (handles nested JSON after preamble, missed by Tier 2).
  • What did NOT change (scope boundary): No SDK changes. No Pi extension. No new dependencies. The "trailing prose after JSON" case still returns undefined — handling it would require brace-depth tracking and the failure mode hasn't been observed in production.

Why this approach over the alternatives

I researched four options before settling on this one. Summary of why each alternative was rejected:

Option Verdict Why not
A — Inject response_format via Pi before_provider_request extension Deferred Pi's Anthropic provider doesn't build response_format in the payload; even if injected via onPayload, Minimax's Anthropic-compat proxy at api.minimax.io/anthropic is not publicly documented to honor the field. Unverified dependency.
B — Pi extension that intercepts assistant text before agent_end Not possible Pi has no hook between text-finalization and agent_end. The only extension hooks (before_provider_request, after_provider_response) operate on HTTP payloads, not decoded text. Confirmed via local inspection of ~/.npm-global/.../pi-coding-agent/dist/.
C — Harden Archon's tryParseStructuredOutput (this PR) Shipped One file, one function, ~10 net LOC, no new deps, no upstream dependencies, fixes the observed failure mode for any verbose-preamble model.
D — Per-node provider: claude override on the gate node Acceptable workaround, leaves underlying parser brittle Solves the symptom for one workflow; every other workflow that uses output_format against a verbose model stays broken.

Option C addresses the root cause in the parser, so the fix benefits every Pi-routed model (Qwen, DeepSeek, Llama variants, future models) — not just Minimax.

Validation Evidence (required)

bun test packages/providers/src/community/pi/event-bridge.test.ts
# → 39 pass / 0 fail / 60 expects

bun run lint                 # → clean
bun run format:check         # → clean
bun run type-check           # → clean across all 10 packages
  • New tests added:
    1. parses preamble + trailing flat JSON (Minimax M2.7 reasoning-model pattern) — exercises Tier 2 with the actual prose pattern observed today.
    2. parses preamble + trailing nested JSON via tier-3 forward scan — exercises Tier 3, where Tier 2 fails because the last { is inside a child object.
  • Pre-existing test preserved: returns undefined when model wraps JSON in prose with trailing text — this case (preamble + JSON + postamble) still returns undefined; updated test name and comment to clarify why the new tiers don't catch it.

Security Impact (required)

  • New permissions/capabilities? No.
  • New external network calls? No.
  • Secrets/tokens handling? No.
  • File system access scope? No.

Compatibility / Migration

  • Backward compatible? Yes. Tier 1 (clean parse) is unchanged — every existing call site that worked before still gets the same output. The two new tiers only fire when Tier 1 fails (i.e., where the function previously returned undefined). New behavior strictly turns previous undefineds into successful parses for the cases it now handles.
  • Config/env changes? No.
  • Database migration? No.

Human Verification (required)

  • Verified scenarios:
    • Real Minimax preamble (from this afternoon's failed runs) — Tier 2 recovers the parsed object.
    • Synthetic preamble + nested JSON — Tier 2 fails as expected, Tier 3 recovers.
    • Existing "preamble + JSON + postamble" — still returns undefined (test asserts).
    • Empty/whitespace-only/malformed inputs — still return undefined.
    • Fenced JSON (json … ) — Tier 1 strips fences and parses. Unchanged.
  • Edge cases checked:
    • JSON with { inside a string value — lastIndexOf('{') finds the inner one, Tier 2 fails, Tier 3 recovers via forward scan.
    • Single-character JSON ({}) — firstBrace === lastBrace, so Tier 3 is skipped (correct — no second scan needed). Tier 1 already parsed it.
    • Empty array [] — Tier 1 parses cleanly; Tiers 2/3 don't fire (indexOf('{') === -1).
  • What was not verified: live re-run of the 7 failed PRs from this afternoon. Easy to do post-merge — they'd all pick up the fix automatically since archon is bun-linked to source.

Side Effects / Blast Radius (required)

  • Affected subsystems: Only @archon/providers (Pi event-bridge). The function is called from one place — provider.ts's agent_end handler — and is only invoked when output_format is set on the workflow node. Workflows without structured output are unaffected.
  • Potential unintended effects: extremely small. The function previously returned undefined for cases it now parses; the only "regression" is correctness (returning the parsed object instead of undefined). Callers handle undefined by emitting a dag.structured_output_missing warning and degrading; with this fix, that warning fires less often.
  • Guardrails: 39 unit tests cover the function; CI catches.

Rollback Plan (required)

  • Fast rollback: git revert <merge-sha> — single commit, ~10 net LOC, fully reversible.
  • Feature flags: none.
  • Observable failure symptoms: if Tier 2 or Tier 3 ever returns a wrong parse (e.g., extracting an unrelated { as if it were the structured output), downstream when: conditions would route to wrong branches. Mitigated by the conservative ladder — Tier 1 only fires on full-text parse, Tiers 2/3 only fire after Tier 1 fails. Extra brace inside a string value is the only way to get a wrong parse, and the order (last-then-first) makes that a very narrow case.

Risks and Mitigations

  • Risk: a verbose-preamble + structured output schema with { characters embedded in string values (e.g., a regex_pattern: "{name}" field) could trigger Tier 2 to parse from the wrong {. Tier 3 falls back to first { and would parse correctly.
    • Mitigation: the ladder is conservative — Tier 2 fails-fast on parse error, Tier 3 catches it. Worst case: Tier 3 also fails → return undefined → existing missing-structured-output path → same as before this PR.

Linked Issue

Summary by CodeRabbit

  • Bug Fixes

    • Improved structured-output parsing so assistant responses containing prose plus embedded or trailing JSON are more reliably recovered instead of failing.
  • Tests

    • Added tests for recovery scenarios: prose preambles, trailing flat and nested JSON, and JSON containing brace characters inside strings.
  • Documentation

    • Updated docs and changelog to explain the enhanced parsing behavior and the graceful failure fallback.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 27, 2026

📝 Walkthrough

Walkthrough

tryParseStructuredOutput now attempts JSON.parse on cleaned text, and if that fails performs a forward-scan from the first { to recover embedded JSON. Tests were expanded to cover preamble+JSON, nested JSON, string-contained {, and a regression case where trailing prose causes failure.

Changes

Cohort / File(s) Summary
Parser
packages/providers/src/community/pi/event-bridge.ts
Reworked tryParseStructuredOutput to try direct parse on cleaned text, then attempt parsing from the first { as a recovery step. Updated inline docs and failure semantics (returns undefined only after both attempts).
Tests
packages/providers/src/community/pi/event-bridge.test.ts
Expanded test coverage: added fixtures for preamble+JSON (including Minimax-style “thinking aloud”), nested JSON, and { inside JSON strings; refined negative tests to assert undefined when post-JSON prose/brace-bearing prose follows.
Docs / Changelog
CHANGELOG.md, packages/docs-web/src/content/docs/getting-started/ai-assistants.md
Documented the enhanced Pi structured-output extraction behavior (best-effort extraction from messages with prose preambles) and preserved guidance about graceful degradation for interleaved/trailing text cases.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 I hop through prose and brackets bright,
Nose to the text, I seek the JSON light.
First parse tries clean — if that will fail,
I leap to the brace and follow the trail.
A tiny carrot cheer for structured sight!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and concisely describes the main change: adding tolerance for prose preamble in Pi structured-output responses.
Description check ✅ Passed The description comprehensively covers all required sections: problem statement, impact, technical approach, alternatives considered, validation evidence, security/compatibility/verification details, side effects, and rollback plan. All major template sections are substantively addressed.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/pi-parse-prose-preamble

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
Review rate limit: 7/8 reviews remaining, refill in 7 minutes and 30 seconds.

Comment @coderabbitai help to get the list of available commands and usage tips.

@Wirasm
Copy link
Copy Markdown
Collaborator Author

Wirasm commented Apr 27, 2026

PR Review Summary (multi-agent)

Six specialist reviews ran in parallel: code-reviewer, docs-impact, pr-test-analyzer, comment-analyzer, silent-failure-hunter, code-simplifier. Type-design-analyzer skipped (no new types).

Critical Issues (1)

Agent Issue Location
code-reviewer (92), silent-failure-hunter (HIGH), pr-test-analyzer (7/10) Tier 2 can silently return a wrong-but-valid parse. lastIndexOf('{') is purely lexical — if preamble contains a {...} fragment that happens to be valid JSON (e.g. an inline example, a markdown URL fragment, a quoted JSON sample), Tier 2 returns that fragment and the caller has no way to detect the mismatch. Garbage data then propagates through $node.output.field substitutions. packages/providers/src/community/pi/event-bridge.ts:191-198

Three converging mitigations were proposed:

  • Suffix sanity check (code-reviewer): require cleaned.slice(brace).trimEnd().endsWith('}') before accepting a tier-2/3 parse — a cheap "reaches end-of-string" guard against mid-preamble matches.
  • Heuristic-tier debug log (silent-failure-hunter): emit debug log on tier-2/3 success with preambleLength, so heuristic vs. clean parses are observable.
  • Regression test for { inside string values (pr-test-analyzer): pin the cascade behavior with {"key":"{}","ok":true}-style input.

The suffix check is the strongest fix because it actually prevents the wrong parse rather than just observing it.

Important Issues (2)

Agent Issue Location
code-reviewer (82), code-simplifier, comment-analyzer Tier 3 guard firstBrace !== lastBrace is redundant. lastBrace > 0 already gates Tier 2; the !== clause works by accident and obscures intent. Drop it (and optionally add a one-line comment to the Tier 2 guard noting that === 0 means "Tier 1 already tried this"). event-bridge.ts:203
docs-impact packages/docs-web/src/content/docs/getting-started/ai-assistants.md:378 claim "degrades cleanly when the model emits prose" is now partially false — preamble-only patterns are recovered. Tighten to: "preamble-only patterns are recovered automatically; trailing-text-interleaved cases still degrade." Also add a CHANGELOG entry under Fixed. docs + CHANGELOG.md

Suggestions (3)

Agent Suggestion Location
comment-analyzer Drop the three // Fall through... comments — empty catch + return-in-try makes the control flow obvious. Drop the model name list (Claude, GPT, Gemini, ...) from the Tier 1 comment — it will date. event-bridge.ts:179, 188, 198
comment-analyzer Tier 2 comment says "for nested JSON in the response, the last { lands inside a child object and parsing fails" — only true with a preamble (clean nested JSON would have parsed in Tier 1). Tighten the wording. event-bridge.ts Tier 2 header
pr-test-analyzer Add a regression test for {-inside-string-value to pin the tier cascade composition. event-bridge.test.ts

Strengths

  • Conservative ladder (Tier 1 → 2 → 3) preserves the fast path for compliant models.
  • Existing trailing-prose case is explicitly tested as undefined — confirms the design boundary.
  • Realistic test payloads (real Minimax M2.7 prose, actual nested-JSON shape) rather than synthetic minimal strings.
  • JSDoc on tryParseStructuredOutput updated to reflect the three-tier reality.
  • Justified silent catches — function contract is "undefined on failure" and call-site already warns at line 388.

Verdict

NEEDS FIX — critical issue is the silent-wrong-parse risk. The mitigations are small (a suffix check + a regression test); they don't alter the conservative-ladder design. Once that lands, this is ready to merge.

Recommended Actions

  1. Add suffix sanity check before returning tier-2/3 parse (cleaned.slice(brace).trimEnd().endsWith('}')).
  2. Add regression test for { inside string values (covers the cascade composition the PR description claims to handle).
  3. Drop redundant firstBrace !== lastBrace guard.
  4. Update ai-assistants.md:378 and add CHANGELOG entry.
  5. Optional comment cleanup (remove fall-through narration, drop model name list).

Wirasm added a commit that referenced this pull request Apr 27, 2026
- Drop the redundant `firstBrace !== lastBrace` guard on Tier 3. When
  the only `{` past position 0 is the same one Tier 2 just tried, Tier
  3 will re-run JSON.parse on the same input and fail identically — one
  redundant call accepted for simpler control flow. (CodeRabbit cleanup)

- Tighten the Tier 1 comment to drop the model name list (will date)
  and tighten the Tier 2 comment to scope its claim to "preamble +
  flat JSON" rather than overgeneralized "nested JSON". (CodeRabbit
  comment-quality cleanup)

- Replace the bare `// Fall through...` comments with `// fall through`
  inside the catch blocks. Necessary because eslint's `no-empty` rule
  flags bare `catch {}` blocks. (lint compliance)

- Add a regression test for `{` inside a string value that pins the
  Tier 2 → Tier 3 cascade composition: lastIndexOf lands inside the
  string brace, JSON.parse rejects the resulting `{ inside","ok":true}`
  fragment, Tier 3 forward-scans to the JSON object's outer `{` and
  parses cleanly. Note: the preamble must not itself contain `{`,
  otherwise Tier 3 lands on it instead of on the JSON object — covered
  in the test comment so the constraint isn't lost. (CodeRabbit test
  coverage)

- Update `packages/docs-web/src/content/docs/getting-started/ai-assistants.md:378`
  — the previous "degrades cleanly when the model emits prose" claim is
  now partially false (preamble-only patterns are recovered). New text
  enumerates the three handled forms (bare, fenced, prose-preamble)
  and clarifies the trailing-text-interleaved case still degrades.
  (CodeRabbit docs-impact)

- Add a CHANGELOG entry under `## [Unreleased] / Fixed`.

CodeRabbit's "critical" suffix-check suggestion (`cleaned.slice(brace)
.trimEnd().endsWith('}')`) is not applied. JSON.parse already rejects
trailing non-whitespace, so any successful parse from a `{`-prefixed
slice already ends with `}` after trim — the check is tautological in
all cases the function actually reaches it. The actual concern (a
self-contained `{...}` fragment in preamble that happens to be valid
JSON, with no real answer in the response) wouldn't be caught by the
suffix check either, since the fragment IS a valid JSON object that
ends with `}`. Real defense against that case would require schema
validation, which lives at the call site (executor's
`structured_output_missing` warning path), not in this parser.

Tests: 40 pass / 0 fail. Lint, format, type-check all clean.
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/providers/src/community/pi/event-bridge.test.ts`:
- Around line 404-410: Add a regression test to ensure tryParseStructuredOutput
still returns undefined when valid-looking JSON appears in a postamble
brace-containing snippet: create a new test case (e.g., "returns undefined when
model wraps JSON in prose with brace-containing postamble") that uses prose like
'Here is the JSON you requested:\n{"ok":true}\nAlso note: {"foo":"bar"}' and
assert expect(tryParseStructuredOutput(prose)).toBeUndefined(); place this
alongside the existing tests around tryParseStructuredOutput to ensure the
parser doesn't erroneously pick up the trailing brace fragment.

In `@packages/providers/src/community/pi/event-bridge.ts`:
- Around line 186-194: The Tier 2 fallback currently slices at lastBrace and may
return a trailing JSON object from responses that include a prior JSON (e.g.,
'{"ok":true}\nFor example: {"verdict":"review"}'), violating the conservative
failure mode; change the logic in the block that computes lastBrace/cleaned so
you only attempt JSON.parse(cleaned.slice(lastBrace)) when the prefix before
lastBrace is empty or contains only whitespace/newlines/separators (i.e.,
cleaned.slice(0, lastBrace).trim() === ''), otherwise skip Tier 2 and return
undefined; update the try/catch around JSON.parse to remain but do not silently
accept a parsed object when the prefix is non-empty.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f1219932-73d9-47ae-ab35-d3d0a1f4dad2

📥 Commits

Reviewing files that changed from the base of the PR and between fdce4c5 and 3272784.

📒 Files selected for processing (4)
  • CHANGELOG.md
  • packages/docs-web/src/content/docs/getting-started/ai-assistants.md
  • packages/providers/src/community/pi/event-bridge.test.ts
  • packages/providers/src/community/pi/event-bridge.ts
✅ Files skipped from review due to trivial changes (2)
  • packages/docs-web/src/content/docs/getting-started/ai-assistants.md
  • CHANGELOG.md

Comment thread packages/providers/src/community/pi/event-bridge.test.ts
Comment thread packages/providers/src/community/pi/event-bridge.ts Outdated
Wirasm added 3 commits April 29, 2026 12:19
…nses

Pi has no SDK-level JSON-mode parameter and Minimax's Anthropic-compat
proxy doesn't expose response_format support, so reasoning models like
Minimax M2.7 routinely "think out loud" before emitting the JSON we
asked for, e.g.:

  "Now I have all the inputs. Let me evaluate the three gates:
   **Gate A — Direction alignment**: ...
   {\"verdict\":\"review\",\"direction_alignment\":\"aligned\",...}"

The previous tryParseStructuredOutput stripped fences then JSON.parse'd
the whole string, which fails the moment a single character of prose
appears before the {. The maintainer-review-pr workflow's gate node was
hitting this on ~70% of runs, propagating to 7-of-10 silent failures
in a sequential review batch this afternoon.

Add two preamble-tolerant fallback tiers:

  Tier 1 (existing): clean JSON.parse — fast path for compliant models
  Tier 2 (new):      scan backward to last `{`, parse from there — flat
                     JSON with reasoning preamble (Minimax M2.7 case)
  Tier 3 (new):      scan forward to first `{`, parse from there —
                     nested JSON with preamble (Tier 2 lands inside a
                     child object and fails)

The existing "trailing-prose-too" failure case (preamble + JSON +
postamble) still returns undefined — handling it would require brace-
depth tracking and isn't worth the cost. The two new tiers cover the
failure mode actually observed in production.

Tested against the real Minimax preamble pattern and a synthetic
preamble + nested-JSON case. 39 event-bridge tests pass.

No SDK changes, no Pi extensions, no Minimax API dependencies. Pure
Archon-side parser hardening — backward-compatible and benefits every
verbose-preamble model routed through Pi, not just Minimax.
- Drop the redundant `firstBrace !== lastBrace` guard on Tier 3. When
  the only `{` past position 0 is the same one Tier 2 just tried, Tier
  3 will re-run JSON.parse on the same input and fail identically — one
  redundant call accepted for simpler control flow. (CodeRabbit cleanup)

- Tighten the Tier 1 comment to drop the model name list (will date)
  and tighten the Tier 2 comment to scope its claim to "preamble +
  flat JSON" rather than overgeneralized "nested JSON". (CodeRabbit
  comment-quality cleanup)

- Replace the bare `// Fall through...` comments with `// fall through`
  inside the catch blocks. Necessary because eslint's `no-empty` rule
  flags bare `catch {}` blocks. (lint compliance)

- Add a regression test for `{` inside a string value that pins the
  Tier 2 → Tier 3 cascade composition: lastIndexOf lands inside the
  string brace, JSON.parse rejects the resulting `{ inside","ok":true}`
  fragment, Tier 3 forward-scans to the JSON object's outer `{` and
  parses cleanly. Note: the preamble must not itself contain `{`,
  otherwise Tier 3 lands on it instead of on the JSON object — covered
  in the test comment so the constraint isn't lost. (CodeRabbit test
  coverage)

- Update `packages/docs-web/src/content/docs/getting-started/ai-assistants.md:378`
  — the previous "degrades cleanly when the model emits prose" claim is
  now partially false (preamble-only patterns are recovered). New text
  enumerates the three handled forms (bare, fenced, prose-preamble)
  and clarifies the trailing-text-interleaved case still degrades.
  (CodeRabbit docs-impact)

- Add a CHANGELOG entry under `## [Unreleased] / Fixed`.

CodeRabbit's "critical" suffix-check suggestion (`cleaned.slice(brace)
.trimEnd().endsWith('}')`) is not applied. JSON.parse already rejects
trailing non-whitespace, so any successful parse from a `{`-prefixed
slice already ends with `}` after trim — the check is tautological in
all cases the function actually reaches it. The actual concern (a
self-contained `{...}` fragment in preamble that happens to be valid
JSON, with no real answer in the response) wouldn't be caught by the
suffix check either, since the fragment IS a valid JSON object that
ends with `}`. Real defense against that case would require schema
validation, which lives at the call site (executor's
`structured_output_missing` warning path), not in this parser.

Tests: 40 pass / 0 fail. Lint, format, type-check all clean.
… footgun

CodeRabbit flagged a real correctness issue: a backward scan from the last
`{` silently returns the wrong JSON object when the response contains a
brace-bearing example after the real payload (e.g. `{"actual":1}\n
For example: {"x":2}` parses the trailing example instead of failing).
This breaks the conservative-failure contract callers rely on.

Tier 2 was always strictly worse than Tier 3 anyway: every preamble pattern
Tier 2 handled, Tier 3 handles too, and Tier 3 doesn't have the
multi-fragment hazard. Dropping Tier 2 entirely removes the footgun and
keeps the parser simple (clean parse → forward scan → undefined).

Tests updated:
- Renamed/clarified existing tests to reference the surviving forward-scan
  tier instead of the deleted backward-scan tier (no behavior change for
  the cases they cover — preamble has no extra braces).
- Added a regression test for the brace-postamble footgun: input with a
  trailing example like `{"actual":"value"}\nFor example: {"verdict":"review"}`
  must return undefined under the new contract.
@Wirasm Wirasm force-pushed the fix/pi-parse-prose-preamble branch from 3272784 to bf77ac9 Compare April 29, 2026 09:23
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
packages/providers/src/community/pi/event-bridge.ts (1)

186-196: Add debug telemetry for successful Tier 2 recovery.

When heuristic parsing succeeds, a debug event with preambleLength would make recovery behavior observable in production.

♻️ Proposed patch
   const firstBrace = cleaned.indexOf('{');
   if (firstBrace > 0) {
     try {
-      return JSON.parse(cleaned.slice(firstBrace));
+      const parsed = JSON.parse(cleaned.slice(firstBrace));
+      getLog().debug(
+        { preambleLength: firstBrace },
+        'pi.structured_output_recovery_completed'
+      );
+      return parsed;
     } catch {
       // fall through
     }
   }
As per coding guidelines: "Structured logging with Pino: use event naming format `{domain}.{action}_{state}` (standard states: _started, _completed, _failed, _validated, _rejected) ..."
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/providers/src/community/pi/event-bridge.ts` around lines 186 - 196,
Add a debug telemetry/event log inside the Tier 2 recovery success path (inside
the try block that does JSON.parse(cleaned.slice(firstBrace))) that emits a
structured debug event following the Pino naming convention
{domain}.{action}_{state} (e.g., "pi.recovery_completed" or
"eventBridge.tier2_recovered_completed") and include a field preambleLength set
to firstBrace (and optionally the cleaned length or snippet metadata). Place the
log call immediately before the return so it only fires on successful
JSON.parse, using the existing logger/telemetry mechanism in this module.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@packages/providers/src/community/pi/event-bridge.ts`:
- Around line 186-196: Add a debug telemetry/event log inside the Tier 2
recovery success path (inside the try block that does
JSON.parse(cleaned.slice(firstBrace))) that emits a structured debug event
following the Pino naming convention {domain}.{action}_{state} (e.g.,
"pi.recovery_completed" or "eventBridge.tier2_recovered_completed") and include
a field preambleLength set to firstBrace (and optionally the cleaned length or
snippet metadata). Place the log call immediately before the return so it only
fires on successful JSON.parse, using the existing logger/telemetry mechanism in
this module.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 8807fef1-d35e-4d42-816d-6a6d07aa116c

📥 Commits

Reviewing files that changed from the base of the PR and between 3272784 and bf77ac9.

📒 Files selected for processing (4)
  • CHANGELOG.md
  • packages/docs-web/src/content/docs/getting-started/ai-assistants.md
  • packages/providers/src/community/pi/event-bridge.test.ts
  • packages/providers/src/community/pi/event-bridge.ts
✅ Files skipped from review due to trivial changes (1)
  • packages/docs-web/src/content/docs/getting-started/ai-assistants.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/providers/src/community/pi/event-bridge.test.ts

@Wirasm Wirasm merged commit a0d4884 into dev Apr 29, 2026
4 checks passed
@Wirasm Wirasm deleted the fix/pi-parse-prose-preamble branch April 29, 2026 09:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant