Skip to content

Fix competitor-analysis live browser preview never appearing - #247

Open
Hotragn wants to merge 1 commit into
tinyfish-io:mainfrom
Hotragn:hotragn/fix-competitor-analysis-streaming
Open

Fix competitor-analysis live browser preview never appearing#247
Hotragn wants to merge 1 commit into
tinyfish-io:mainfrom
Hotragn:hotragn/fix-competitor-analysis-streaming

Conversation

@Hotragn

@Hotragn Hotragn commented Aug 4, 2026

Copy link
Copy Markdown

Refs #86. Found by the conformance check in #244.

The bug

app/api/scrape-pricing/route.ts cast every agent event to any and then read camelCase fields the stream doesn't publish:

const event: any = rawEvent;

if (event.streamingUrl && !streamingUrl) {   // always undefined

The SDK sends streaming_url. So the guard never fired, competitor_streaming was never sent, and the live preview iframe stayed empty for every competitor. The client side was correct the whole time — it just never received the event.

Two more stale reads in the same loop, both masked by a fallback:

Line Read Why it didn't crash
:382 event.type === 'STEP' Not an event type the stream sends. Step forwarding worked only because the condition fell through to || event.purpose.
:395 event.resultJson ?? event.result resultJson doesn't exist; completion worked via the event.result fallback beside it.

The any cast is what let all three through — with the real event union, each would have been a type error.

The fix

Dropped the cast and switched the loop to the SDK's own constants, matching how the already-migrated recipes read the stream. From @tiny-fish/sdk/dist/agent/types.d.ts:

  • STREAMING_URLstreaming_url (:212)
  • PROGRESSpurpose (:218-220)
  • COMPLETEstatus, result, error (:236-253)
  • EventType is STARTED | STREAMING_URL | PROGRESS | HEARTBEAT | COMPLETE (:186) — there is no ERROR event

That last point matters: the old code had if (event.type === 'ERROR' || event.status === 'FAILED'). A failed run actually arrives as COMPLETE with a non-COMPLETED status and an error.message, so error handling now lives inside the COMPLETE branch and reads event.error?.message — the same error?.message idiom already used in fareguard and founder-mode.

Net −21/+15, and one eslint-disable-next-line @typescript-eslint/no-explicit-any goes away.

Scope

The recipe's own SSE vocabulary is unchanged — the route still emits competitor_streaming with a streamingUrl key and competitor_step with a step key, which is exactly what app/analysis/page.tsx and app/dashboard/page.tsx already read. No client changes needed; fixing the route restores the chain end to end.

Behaviour is otherwise identical. The old step-forwarding condition never fired for STARTED, HEARTBEAT or STREAMING_URL either, since none of them carry a purpose.

Verification

cd competitor-analysis && npm ci
npx tsc --noEmit    # clean
npm run lint        # clean

The scrape-pricing route cast each agent event to any and then read
camelCase fields the stream does not publish. event.streamingUrl is
always undefined -- the SDK sends streaming_url -- so the capture guard
never fired, competitor_streaming was never sent, and the preview iframe
stayed empty for every competitor. The client was fine; it never got the
event.

Two more stale reads in the same loop:

- event.type === 'STEP' is not an event type the stream sends. Step
  forwarding only worked because the condition fell through to
  event.purpose.
- event.resultJson does not exist either; completion only worked via the
  event.result fallback beside it.

Dropped the any cast and switched the loop to the SDK's own EventType and
RunStatus constants, matching how the migrated recipes already read the
stream. Per @tiny-fish/sdk/dist/agent/types.d.ts the events are
STREAMING_URL/streaming_url, PROGRESS/purpose and COMPLETE/status+result,
and there is no ERROR event -- a failed run is COMPLETE with a
non-COMPLETED status and an error.message -- so error handling moved
inside the COMPLETE branch.

No change to the recipe's own SSE vocabulary, so the client is untouched.
Verified with tsc --noEmit and npm run lint, both clean.

Found by the check in tinyfish-io#244; refs tinyfish-io#86.
@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 229fb39c-ffe3-40ba-a991-f9723c223995

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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

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

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