Skip to content

feat: add openchoreo assistant perch#511

Merged
yashodgayashan merged 1 commit into
openchoreo:mainfrom
yashodgayashan:perch
May 14, 2026
Merged

feat: add openchoreo assistant perch#511
yashodgayashan merged 1 commit into
openchoreo:mainfrom
yashodgayashan:perch

Conversation

@yashodgayashan
Copy link
Copy Markdown
Contributor

@yashodgayashan yashodgayashan commented May 7, 2026

Purpose

Add Perch the OpenChoreo assistant

Goals

Describe the solutions that this feature/fix will introduce to resolve the problems described above

Approach

Screen.Recording.2026-05-07.at.16.02.33.mov

User stories

Summary of user stories addressed by this change>

Release note

Brief description of the new feature or bug fix as it will appear in the release notes

Documentation

Link(s) to product documentation that addresses the changes of this PR. If no doc impact, enter “N/A” plus brief explanation of why there’s no doc impact

Training

Link to the PR for changes to the training content in https://github.com/wso2/WSO2-Training, if applicable

Certification

Type “Sent” when you have provided new/updated certification questions, plus four answers for each question (correct answer highlighted in bold), based on this change. Certification questions/answers should be sent to certification@wso2.com and NOT pasted in this PR. If there is no impact on certification exams, type “N/A” and explain why.

Marketing

Link to drafts of marketing content that will describe and promote this feature, including product page changes, technical articles, blog posts, videos, etc., if applicable

Automation tests

  • Unit tests

    Code coverage information

  • Integration tests

    Details about the test cases and coverage

Security checks

Samples

Provide high-level details about the samples related to this feature

Related PRs

List any other related PRs

Migrations (if applicable)

Describe migration steps and platforms on which migration has been tested

Test environment

List all JDK versions, operating systems, databases, and browser/versions on which this feature/fix was tested

Learning

Describe the research phase and any blog posts, patterns, libraries, or add-ons you used to solve the problem.

Summary by CodeRabbit

  • New Features

    • Adds an AI assistant chat drawer with streaming responses, action execution, and contextual prompt launchers (Build, Logs) plus a failed-build snackbar.
  • Chores / Configuration

    • Assistant is opt-in and disabled by default; new feature flag and optional upstream URL env/config wiring and app/backend registration added.
  • Documentation

    • Expanded docs and config examples covering setup, routing, streaming behavior, and feature gating.
  • Tests

    • New unit/integration tests for backend forwarder, router, hooks, and API wiring.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 7, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This pull request introduces Perch, an opt-in AI assistant: configuration keys and a feature flag, a backend forwarder plugin and streaming router, a frontend plugin with API client, drawer/context, and contextual launchers, app-level wiring, CI hook for failed-run detection, tests, and documentation.

Changes

Perch Assistant Feature Introduction

Layer / File(s) Summary
Configuration and Feature Types
app-config.yaml, app-config.production.yaml, app-config.local.yaml.example, plugins/openchoreo-common/src/types/features.ts
Adds commented assistantAgentUrl placeholders and openchoreo.features.assistant.enabled feature flag; extends feature types to include assistant.
App Dependency & API Wiring
packages/app/package.json, packages/app/src/apis.ts, packages/app/src/components/Root/Root.tsx, packages/app/src/components/catalog/EntityPage.tsx, packages/app/src/components/catalog/FeatureGatedContent.tsx, packages/backend/package.json, packages/backend/src/index.ts, packages/app/src/apis.test.ts
Adds perch plugin deps; registers assistantAgentApiRef API factory; wraps Root with AssistantDrawerProvider; mounts Perch launchers/snackbar on entity pages; updates feature name mapping; registers backend plugin; adds apis factory smoke tests.
Backend Plugin Package & Registration
plugins/openchoreo-perch-backend/package.json, plugins/openchoreo-perch-backend/src/plugin.ts, plugins/openchoreo-perch-backend/src/index.ts, plugins/openchoreo-perch-backend/src/plugin.test.ts
New backend plugin package and registration that resolves assistantAgentUrl (preferring perch.* then openchoreo.*), self-disables if unset, mounts router when configured, and registers unauthenticated HTTP policy; includes startup tests.
Backend Router & Forwarders
plugins/openchoreo-perch-backend/src/router.ts
Implements createRouter with streaming /chat (ndjson piping) and non-streaming /execute//warmup, header filtering, x-request-id synthesis, timeout/error classification, and helper isTimeoutError.
Backend Tests & Docs
plugins/openchoreo-perch-backend/src/router.test.ts, plugins/openchoreo-perch-backend/README.md
Comprehensive router tests for headers, NDJSON streaming order, timeout scenarios, unreachable upstream handling; README documents forwarding semantics and streaming/cancellation details.
Frontend Plugin Package & Registration
plugins/openchoreo-perch/package.json, plugins/openchoreo-perch/src/plugin.ts, plugins/openchoreo-perch/src/index.ts, plugins/openchoreo-perch/tsconfig.json, plugins/openchoreo-perch/.eslintrc.js, plugins/openchoreo-perch/README.md
Adds the openchoreo-perch frontend plugin package, registers API factory wiring AssistantAgentClient to discovery/fetch, centralizes exports for API, context, and UI components, and documents usage.
Frontend API Contract & Client
plugins/openchoreo-perch/src/api/AssistantAgentApi.ts
Defines types (ChatMessage, ChatScope, ChatRequest, ProposedAction, ExecuteResult, StreamEvent) and implements AssistantAgentClient with streamChat, executeAction, and warmup including incremental NDJSON parsing and best-effort error extraction.
Assistant Drawer Context & Provider
plugins/openchoreo-perch/src/components/AssistantContext/AssistantDrawerContext.tsx
Provides AssistantDrawerProvider, useAssistantDrawer, conversationKey tracking, openSeq for seeded opens, hasConversation, and warmup side-effect.
Assistant Chat Drawer
plugins/openchoreo-perch/src/components/AssistantChatDrawer/*
Main chat drawer: derives scope, streams assistant responses into a timeline, renders proposed action cards, supports approving/executing actions, aborts, clears, and conversation continuity.
Prompt Launcher Components
plugins/openchoreo-perch/src/components/AssistantPromptLauncher/*, .../BuildPagePromptLauncher/*, .../FailedBuildSnackbar/*, .../LogsPageDebugPrompt/*
Contextual launchers (FAB/panel, failed-build snackbar, build page launcher, logs debug prompt) that open the drawer with seeded context and deterministic conversation keys; barrel re-exports added.
CI Latest Failed Run Hook
plugins/openchoreo-ci/src/hooks/useLatestFailedRun.ts, plugins/openchoreo-ci/src/hooks/index.ts, plugins/openchoreo-ci/src/index.ts, plugins/openchoreo-ci/src/hooks/useLatestFailedRun.test.tsx
Adds useLatestFailedRun() hook returning derived latestRun/isFailed with idle 30s polling (no-overlap scheduling) and tests for selection, polling, error handling, and cleanup.
Tests / Lint / Manifests
various *.test.ts, *.eslintrc.js, tsconfig.json, package.json files under new plugin packages
Adds backend router and plugin tests, front-end tests for assistant defaults and helper hook, and introduces ESLint/TS config and package manifests for new plugins.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

🐰 A rabbit hops with glee so bright,
New Perch brings chat to Backstage's light!
With streams and drawers and features grand,
The assistant flows throughout the land.
Config, hooks, and backend play,
Making debugging a better day! 🌿✨

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

@codecov
Copy link
Copy Markdown

codecov Bot commented May 7, 2026

Codecov Report

❌ Patch coverage is 91.82692% with 17 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
plugins/openchoreo-perch-backend/src/router.ts 87.40% 17 Missing ⚠️

📢 Thoughts on this report? Let us know!

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: 5

🧹 Nitpick comments (5)
plugins/openchoreo-perch/package.json (1)

36-38: ⚡ Quick win

React-markdown and remark-gfm are ESM-only packages — plan test setup accordingly if adding tests.

react-markdown v9 and remark-gfm v4 are ESM-only modules. However, the sibling openchoreo-observability plugin uses the same packages with a comprehensive test suite, using @backstage/cli which abstracts Jest configuration. No custom jest.config.js or transformIgnorePatterns are visible in either plugin.

Since openchoreo-perch currently has no test files, there is no immediate concern. If tests are added in the future, follow the same pattern as openchoreo-observability (use @backstage/cli package test, renderInTestApp for Backstage components, and the utilities documented in TESTING_GUIDE.md).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugins/openchoreo-perch/package.json` around lines 36 - 38, The package.json
added ESM-only dependencies react-markdown and remark-gfm which will break Jest
if tests are added; update the test plan to mirror openchoreo-observability by
using `@backstage/cli` test runner (run via `@backstage/cli package test`), rely
on the Backstage testing utilities (renderInTestApp) and the TESTING_GUIDE.md
patterns, and avoid custom jest.config.js that mishandles ESM modules—if you
must add custom jest settings, configure transforms/transformIgnorePatterns to
handle ESM or use the `@backstage/cli` abstraction so react-markdown and
remark-gfm are resolved correctly when tests are added.
app-config.production.yaml (1)

167-172: ⚡ Quick win

Mismatched assistant feature flag and agent URL can silently degrade Perch.

If OPENCHOREO_FEATURES_ASSISTANT_ENABLED=true but OPENCHOREO_ASSISTANT_AGENT_URL is unset, the frontend renders Perch UI components while the backend proxy self-disables — every assistant API call returns 404 with no obvious error in the config.

Backstage's config substitution evaluates a missing env var to undefined (not an error), but also supports a ${MY_VAR:-default} fallback syntax. Consider documenting this dependency in a comment, and optionally using the fallback syntax to make the misconfiguration more visible:

-  assistantAgentUrl: ${OPENCHOREO_ASSISTANT_AGENT_URL}
+  # Must be set when openchoreo.features.assistant.enabled is true.
+  # If omitted, the perch-backend plugin self-disables and all Perch API
+  # calls will 404 even though the UI feature flag is on.
+  assistantAgentUrl: ${OPENCHOREO_ASSISTANT_AGENT_URL:-}

Using :- (empty-string default) ensures the key is always present in config, which may help debuggability — an empty assistantAgentUrl is more obvious in a config dump than a completely absent key.

Also applies to: 201-205

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app-config.production.yaml` around lines 167 - 172, The assistantAgentUrl key
can be unset when OPENCHOREO_FEATURES_ASSISTANT_ENABLED=true which causes silent
degradation; update the app-config entries that reference
OPENCHOREO_ASSISTANT_AGENT_URL (including assistantAgentUrl and the other
similar entries around lines 201-205) to use Backstage's fallback substitution
(e.g. the ${VAR:-} form) so the config always contains the key (an empty string
makes misconfiguration obvious), and add a short comment referencing the
dependency on OPENCHOREO_FEATURES_ASSISTANT_ENABLED and advising operators to
set OPENCHOREO_ASSISTANT_AGENT_URL when enabling the assistant.
packages/app/src/components/catalog/EntityPage.tsx (1)

261-264: ⚡ Quick win

Perch components call hooks before checking the assistant feature gate—wrap with FeatureGate to prevent unnecessary mounting.

FailedBuildSnackbar, BuildPagePromptLauncher, and LogsPageDebugPrompt all call useAssistantEnabled() internally and return null when disabled, which is correct. However, they call other hooks (useLatestFailedRun(), useAssistantDrawer()) before the feature check. In particular, useLatestFailedRun() triggers polling of build data even when the assistant feature is disabled.

While the components don't render when assistant is false, they still mount, execute hooks, and potentially trigger API calls. Wrapping them with FeatureGate feature="assistant" at the composition level in EntityPage.tsx prevents this wasted work entirely:

♻️ Proposed pattern (applies to genericComponentEntityPage and systemPage as well)
-          <FailedBuildSnackbar />
+          <FeatureGate feature="assistant">
+            <FailedBuildSnackbar />
+          </FeatureGate>
     <FeatureGatedContent feature="workflows">
+      <FeatureGate feature="assistant">
         <BuildPagePromptLauncher />
+      </FeatureGate>
       <Workflows />
     </FeatureGatedContent>
     <FeatureGatedContent feature="observability">
       <ObservabilityRuntimeLogs />
+      <FeatureGate feature="assistant">
         <LogsPageDebugPrompt />
+      </FeatureGate>
     </FeatureGatedContent>
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/app/src/components/catalog/EntityPage.tsx` around lines 261 - 264,
The three components FailedBuildSnackbar, BuildPagePromptLauncher, and
LogsPageDebugPrompt currently mount and run internal hooks (like
useLatestFailedRun and useAssistantDrawer) even when the assistant feature is
disabled; wrap each usage in EntityPage.tsx with <FeatureGate
feature="assistant">...</FeatureGate> so they never mount unless the assistant
gate is enabled—apply the same pattern to instances in
genericComponentEntityPage and systemPage; locate the component usages
(FailedBuildSnackbar, BuildPagePromptLauncher, LogsPageDebugPrompt) and
replace/encapsulate them with FeatureGate to prevent unnecessary hook execution
and polling.
plugins/openchoreo-react/src/hooks/useOpenChoreoFeatures.ts (1)

22-24: ⚡ Quick win

Update the defaulting doc to match actual behavior.

Line 23 says all features default to enabled, but cilium and assistant intentionally default to false. Please align the comment with runtime behavior to avoid config confusion.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugins/openchoreo-react/src/hooks/useOpenChoreoFeatures.ts` around lines 22
- 24, Update the top-of-file doc comment in useOpenChoreoFeatures.ts to reflect
runtime defaults: instead of saying "All features default to enabled",
explicitly state that most features default to enabled but the "cilium" and
"assistant" features intentionally default to false; mention that defaults come
from openchoreo.features.* in app-config.yaml and that the hook
useOpenChoreoFeatures enforces these exceptions so readers understand the actual
behavior.
plugins/openchoreo-perch/src/components/AssistantChatDrawer/AssistantChatDrawer.tsx (1)

348-387: 💤 Low value

Read timeline via functional setState to drop it from deps.

handleApprove reads timeline directly via .find(), so timeline must be in the useCallback deps. As a result the callback is recreated on every streaming chunk, message append, status update, etc., which churns the JSX-bound onClick handlers on all proposal cards. The same pattern applies to sendMessage (line 500: depends on messageHistory which is derived from timeline).

Reading the proposal via setTimeline(prev => …) lets you keep the deps minimal and always operate on the latest state without recreating the callback on unrelated timeline mutations.

Additionally, api.executeAction(actionId) is awaited without an AbortSignal, so closing the drawer mid-execute leaves the request in flight and may then update state on an unmounted/cleared timeline.

♻️ Sketch of the proposed pattern
 const handleApprove = useCallback(
   async (actionId: string) => {
     updateProposalStatus(actionId, { kind: 'running' });
-    const proposalItem = timeline.find(
-      (it): it is Extract<ChatItem, { kind: 'proposal' }> =>
-        it.kind === 'proposal' && it.action.action_id === actionId,
-    );
+    let proposalItem: Extract<ChatItem, { kind: 'proposal' }> | undefined;
+    setTimeline(prev => {
+      proposalItem = prev.find(
+        (it): it is Extract<ChatItem, { kind: 'proposal' }> =>
+          it.kind === 'proposal' && it.action.action_id === actionId,
+      );
+      return prev;
+    });
     try {
       const result = await api.executeAction(actionId);
       ...
     }
   },
-  [api, ackForAction, timeline, updateProposalStatus],
+  [api, ackForAction, updateProposalStatus],
 );
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@plugins/openchoreo-perch/src/components/AssistantChatDrawer/AssistantChatDrawer.tsx`
around lines 348 - 387, handleApprove currently reads timeline directly and so
must be included in the callback deps, causing frequent recreation; change it to
read the proposal via functional state (use setTimeline(prev => { const
proposalItem = prev.find(...); ... return prev; })) so you no longer reference
timeline in the hook deps (remove timeline from the dependency array) and keep
updateProposalStatus, api, and ackForAction as the only deps. Also make
api.executeAction accept/receive an AbortSignal (or wrap the fetch with
AbortController) and pass a signal that you cancel when the drawer unmounts/
closes to avoid updates after unmount; handleAbort by treating it as an error
path and calling updateProposalStatus/ackForAction similarly. Ensure references
to handleApprove, setTimeline, api.executeAction, ackForAction, and
updateProposalStatus are updated accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@app-config.yaml`:
- Around line 168-172: The app-config.yaml currently references
assistantAgentUrl with ${OPENCHOREO_ASSISTANT_AGENT_URL}, which causes startup
failures when the env var is unset; comment out the assistantAgentUrl line
(following the pattern used for optional keys like thunder.token) so the setting
is inactive by default and only enabled when explicitly configured, ensuring
deployments that leave openchoreo.features.assistant.enabled false don’t require
the env var.

In `@plugins/openchoreo-ci/src/hooks/useLatestFailedRun.ts`:
- Around line 63-65: The polling using setInterval in useLatestFailedRun can
start overlapping fetchBuilds() calls; change the logic to a self-scheduling
loop (use setTimeout or an async loop) instead of setInterval and ensure each
iteration awaits fetchBuilds() before scheduling the next run to prevent
concurrency; also propagate or log errors from fetchBuilds() instead of
swallowing them (replace .catch(() => {}) with proper error handling), and keep
the timeout id cleanup that currently uses id so clearTimeout/clearInterval in
the hook teardown still cancels pending schedules.

In `@plugins/openchoreo-perch-backend/src/router.ts`:
- Around line 217-256: forwardJson currently calls fetch without a timeout,
causing hung upstream requests; add an AbortSignal.timeout-based signal to the
fetch options (e.g., signal:
AbortSignal.timeout(routerOptions?.upstreamTimeoutMs ?? 30000)) so the request
is aborted after a bounded period; locate forwardJson and modify the fetch
invocation to include that signal and surface the timeout via RouterOptions
(e.g., upstreamTimeoutMs) so it’s configurable. Also update forwardStream to
combine its existing client-disconnect AbortController with an upstream deadline
using AbortSignal.any([clientAbort.signal,
AbortSignal.timeout(routerOptions?.streamTimeoutMs ?? <longer-ms>)]) to ensure
streaming handlers also time out if the backend stalls.

In
`@plugins/openchoreo-perch/src/components/AssistantChatDrawer/AssistantChatDrawer.tsx`:
- Around line 36-40: The module-level sentinel constant NO_KEY_YET is declared
between import statements, which breaks import ordering and triggers the
import/first lint rule; move the const NO_KEY_YET = Symbol('no-key-yet') so that
all import lines (including import type { PinnedContext } from
'../AssistantContext/AssistantDrawerContext') appear first, followed by the
NO_KEY_YET declaration and then the rest of the module code to restore idiomatic
import ordering and satisfy ESLint.

In
`@plugins/openchoreo-perch/src/components/AssistantPromptLauncher/AssistantPromptLauncher.tsx`:
- Around line 139-146: The close IconButton currently uses a hardcoded
aria-label ("Dismiss Perch prompt") which won't match a customized title; update
the IconButton in AssistantPromptLauncher so its aria-label is derived from the
component's title prop (falling back to a sensible default like "Perch prompt")
and keep the existing onClick={setOpen(false)} behavior and classes.closeBtn;
locate the IconButton render and replace the static aria-label with a computed
string that includes the title prop (e.g., `Dismiss ${title || 'Perch prompt'}`)
to ensure assistive tech announces the correct panel name.

---

Nitpick comments:
In `@app-config.production.yaml`:
- Around line 167-172: The assistantAgentUrl key can be unset when
OPENCHOREO_FEATURES_ASSISTANT_ENABLED=true which causes silent degradation;
update the app-config entries that reference OPENCHOREO_ASSISTANT_AGENT_URL
(including assistantAgentUrl and the other similar entries around lines 201-205)
to use Backstage's fallback substitution (e.g. the ${VAR:-} form) so the config
always contains the key (an empty string makes misconfiguration obvious), and
add a short comment referencing the dependency on
OPENCHOREO_FEATURES_ASSISTANT_ENABLED and advising operators to set
OPENCHOREO_ASSISTANT_AGENT_URL when enabling the assistant.

In `@packages/app/src/components/catalog/EntityPage.tsx`:
- Around line 261-264: The three components FailedBuildSnackbar,
BuildPagePromptLauncher, and LogsPageDebugPrompt currently mount and run
internal hooks (like useLatestFailedRun and useAssistantDrawer) even when the
assistant feature is disabled; wrap each usage in EntityPage.tsx with
<FeatureGate feature="assistant">...</FeatureGate> so they never mount unless
the assistant gate is enabled—apply the same pattern to instances in
genericComponentEntityPage and systemPage; locate the component usages
(FailedBuildSnackbar, BuildPagePromptLauncher, LogsPageDebugPrompt) and
replace/encapsulate them with FeatureGate to prevent unnecessary hook execution
and polling.

In `@plugins/openchoreo-perch/package.json`:
- Around line 36-38: The package.json added ESM-only dependencies react-markdown
and remark-gfm which will break Jest if tests are added; update the test plan to
mirror openchoreo-observability by using `@backstage/cli` test runner (run via
`@backstage/cli package test`), rely on the Backstage testing utilities
(renderInTestApp) and the TESTING_GUIDE.md patterns, and avoid custom
jest.config.js that mishandles ESM modules—if you must add custom jest settings,
configure transforms/transformIgnorePatterns to handle ESM or use the
`@backstage/cli` abstraction so react-markdown and remark-gfm are resolved
correctly when tests are added.

In
`@plugins/openchoreo-perch/src/components/AssistantChatDrawer/AssistantChatDrawer.tsx`:
- Around line 348-387: handleApprove currently reads timeline directly and so
must be included in the callback deps, causing frequent recreation; change it to
read the proposal via functional state (use setTimeline(prev => { const
proposalItem = prev.find(...); ... return prev; })) so you no longer reference
timeline in the hook deps (remove timeline from the dependency array) and keep
updateProposalStatus, api, and ackForAction as the only deps. Also make
api.executeAction accept/receive an AbortSignal (or wrap the fetch with
AbortController) and pass a signal that you cancel when the drawer unmounts/
closes to avoid updates after unmount; handleAbort by treating it as an error
path and calling updateProposalStatus/ackForAction similarly. Ensure references
to handleApprove, setTimeline, api.executeAction, ackForAction, and
updateProposalStatus are updated accordingly.

In `@plugins/openchoreo-react/src/hooks/useOpenChoreoFeatures.ts`:
- Around line 22-24: Update the top-of-file doc comment in
useOpenChoreoFeatures.ts to reflect runtime defaults: instead of saying "All
features default to enabled", explicitly state that most features default to
enabled but the "cilium" and "assistant" features intentionally default to
false; mention that defaults come from openchoreo.features.* in app-config.yaml
and that the hook useOpenChoreoFeatures enforces these exceptions so readers
understand the actual behavior.
🪄 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: b155aa8b-bf6e-4843-8602-3180f99aa3e9

📥 Commits

Reviewing files that changed from the base of the PR and between f605423 and b43b5b7.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (38)
  • app-config.local.yaml.example
  • app-config.production.yaml
  • app-config.yaml
  • packages/app/package.json
  • packages/app/src/apis.ts
  • packages/app/src/components/Root/Root.tsx
  • packages/app/src/components/catalog/EntityPage.tsx
  • packages/app/src/components/catalog/FeatureGatedContent.tsx
  • packages/backend/package.json
  • packages/backend/src/index.ts
  • plugins/openchoreo-ci/src/hooks/index.ts
  • plugins/openchoreo-ci/src/hooks/useLatestFailedRun.ts
  • plugins/openchoreo-ci/src/index.ts
  • plugins/openchoreo-common/src/types/features.ts
  • plugins/openchoreo-perch-backend/README.md
  • plugins/openchoreo-perch-backend/package.json
  • plugins/openchoreo-perch-backend/src/index.ts
  • plugins/openchoreo-perch-backend/src/plugin.test.ts
  • plugins/openchoreo-perch-backend/src/plugin.ts
  • plugins/openchoreo-perch-backend/src/router.test.ts
  • plugins/openchoreo-perch-backend/src/router.ts
  • plugins/openchoreo-perch/README.md
  • plugins/openchoreo-perch/package.json
  • plugins/openchoreo-perch/src/api/AssistantAgentApi.ts
  • plugins/openchoreo-perch/src/components/AssistantChatDrawer/AssistantChatDrawer.tsx
  • plugins/openchoreo-perch/src/components/AssistantChatDrawer/index.ts
  • plugins/openchoreo-perch/src/components/AssistantContext/AssistantDrawerContext.tsx
  • plugins/openchoreo-perch/src/components/AssistantPromptLauncher/AssistantPromptLauncher.tsx
  • plugins/openchoreo-perch/src/components/AssistantPromptLauncher/index.ts
  • plugins/openchoreo-perch/src/components/BuildPagePromptLauncher/BuildPagePromptLauncher.tsx
  • plugins/openchoreo-perch/src/components/FailedBuildSnackbar/FailedBuildSnackbar.tsx
  • plugins/openchoreo-perch/src/components/LogsPageDebugPrompt/LogsPageDebugPrompt.tsx
  • plugins/openchoreo-perch/src/index.ts
  • plugins/openchoreo-perch/src/plugin.ts
  • plugins/openchoreo-perch/tsconfig.json
  • plugins/openchoreo-react/src/hooks/useOpenChoreoFeatures.test.ts
  • plugins/openchoreo-react/src/hooks/useOpenChoreoFeatures.ts
  • plugins/openchoreo-react/src/index.ts

Comment thread app-config.yaml Outdated
Comment thread plugins/openchoreo-ci/src/hooks/useLatestFailedRun.ts Outdated
Comment thread plugins/openchoreo-perch-backend/src/router.ts
@yashodgayashan yashodgayashan force-pushed the perch branch 2 times, most recently from 84deb1e to c68a725 Compare May 7, 2026 12:44
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: 4

🧹 Nitpick comments (2)
plugins/openchoreo-perch-backend/src/router.test.ts (1)

291-312: ⚡ Quick win

forwardStream timeout test is missing several assertions present in the forwardJson timeout test.

The warmup-timeout test (lines 258-289) validates the full 504 payload shape (error, message, request_id), elapsed bound, and logger.error. The streaming-timeout test only checks res.body.error and elapsed, leaving the response body structure and server-side logging unverified for the streaming path.

♻️ Proposed additions to bring parity with the warmup-timeout test
     expect(res.status).toBe(504);
     expect(res.body.error).toBe('GATEWAY_TIMEOUT');
+    expect(res.body).toMatchObject({
+      error: 'GATEWAY_TIMEOUT',
+      message: expect.stringMatching(/\d+ ms/),
+      request_id: expect.any(String),
+    });
     expect(elapsed).toBeLessThan(2_000);
+    expect(logger.error).toHaveBeenCalledWith(
+      expect.stringMatching(/upstream.*timed out/i),
+    );
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugins/openchoreo-perch-backend/src/router.test.ts` around lines 291 - 312,
The streaming timeout test for forwardStream is missing assertions present in
the forwardJson/warmup-timeout test: extend the 'forwardStream returns 504 when
the upstream does not send response headers within streamTimeoutMs' test (which
sets up upstream, tightRouter via createRouter, tightApp and streamTimeoutMs) to
also assert the full 504 payload shape (res.body.error, res.body.message,
res.body.request_id) and verify the server logged the timeout via logger.error
(the same pattern used in the warmup-timeout test for forwardJson); ensure the
elapsed bound check remains and that the logger assertion looks for the
forward-stream timeout message emitted by forwardStream.
plugins/openchoreo-perch/src/components/BuildPagePromptLauncher/BuildPagePromptLauncher.tsx (1)

24-99: ⚡ Quick win

Reuse isFailedStatus from useLatestFailedRun instead of duplicating it.

The same predicate (includes('fail') || includes('error') on a lower-cased status, with a "kept in sync with BuildStatusChip" intent) lives in plugins/openchoreo-ci/src/hooks/useLatestFailedRun.ts. Two copies will drift the moment one side updates the heuristic. Export it from the CI plugin and import it here.

♻️ Proposed change (in `useLatestFailedRun.ts`)
-/** Failure heuristic — kept in sync with BuildStatusChip. */
-const isFailedStatus = (status?: string) => {
+/** Failure heuristic — kept in sync with BuildStatusChip. */
+export const isFailedStatus = (status?: string) => {
   const lowered = (status ?? '').toLowerCase();
   return lowered.includes('fail') || lowered.includes('error');
 };

And in this file:

-import { useLatestFailedRun } from '@openchoreo/backstage-plugin-openchoreo-ci';
+import {
+  isFailedStatus,
+  useLatestFailedRun,
+} from '@openchoreo/backstage-plugin-openchoreo-ci';
@@
-const isFailedStatus = (status?: string) => {
-  const lowered = (status ?? '').toLowerCase();
-  return lowered.includes('fail') || lowered.includes('error');
-};
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@plugins/openchoreo-perch/src/components/BuildPagePromptLauncher/BuildPagePromptLauncher.tsx`
around lines 24 - 99, The component duplicates the status predicate; remove the
local isFailedStatus in BuildPagePromptLauncher and instead import the shared
predicate exported from useLatestFailedRun (the existing hook that contains the
canonical isFailedStatus), update the component's imports to reference that
exported isFailedStatus, and ensure BuildPagePromptLauncher (and any callers
using targetIsFailed) uses the imported isFailedStatus consistently so the
heuristic stays in one place.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@plugins/openchoreo-perch/package.json`:
- Around line 5-12: The package.json has contradictory settings: "private": true
prevents publishing but publishConfig.access is set to "public"; either remove
"private": true if you intend to publish, or remove only the
publishConfig.access field if this is a permanently private package; keep
publishConfig.main and publishConfig.types if you still want the
prepack/postpack path-swapping behavior, but drop publishConfig.access when
choosing the private option (edit the "private" and the publishConfig.access
keys accordingly).
- Line 41: Update the peer dependency range for "react" in package.json to only
allow React 18 (change the "react" peerDependency from "^16.13.1 || ^17.0.0 ||
^18.0.0" to "^18.0.0") because react-markdown@^9.0.1 requires React ≥18; ensure
the "react" key in package.json's peerDependencies reflects this narrower
constraint so consumers using React 16/17 won't be allowed.
- Line 42: The package.json currently pins the react-router-dom peer dependency
to an exact version "6.30.1", causing peer resolution conflicts; update the
dependency entry for react-router-dom in plugins/openchoreo-perch's package.json
from the exact version to a caret range (e.g., "^6.30.1" or a repo-consistent
range like "^6.0.0") so it matches the repository pattern and allows compatible
minor/patch versions; locate the react-router-dom entry in package.json to make
this change and run a quick install/test to ensure no new peer warnings.

In
`@plugins/openchoreo-perch/src/components/AssistantChatDrawer/AssistantChatDrawer.tsx`:
- Around line 596-602: The disabled predicate on the Clear IconButton is
inverted/unreachable because sendMessage appends to timeline before setting
isSending, so change the condition in the IconButton (inside
AssistantChatDrawer.tsx) from disabled={isSending && timeline.length === 0} to
disabled={isSending || timeline.length === 0} so the Clear button is disabled
when sending or when the timeline is empty; update the IconButton/Tooltip block
that wraps handleClear accordingly (references: handleClear, isSending,
timeline, sendMessage).

---

Nitpick comments:
In `@plugins/openchoreo-perch-backend/src/router.test.ts`:
- Around line 291-312: The streaming timeout test for forwardStream is missing
assertions present in the forwardJson/warmup-timeout test: extend the
'forwardStream returns 504 when the upstream does not send response headers
within streamTimeoutMs' test (which sets up upstream, tightRouter via
createRouter, tightApp and streamTimeoutMs) to also assert the full 504 payload
shape (res.body.error, res.body.message, res.body.request_id) and verify the
server logged the timeout via logger.error (the same pattern used in the
warmup-timeout test for forwardJson); ensure the elapsed bound check remains and
that the logger assertion looks for the forward-stream timeout message emitted
by forwardStream.

In
`@plugins/openchoreo-perch/src/components/BuildPagePromptLauncher/BuildPagePromptLauncher.tsx`:
- Around line 24-99: The component duplicates the status predicate; remove the
local isFailedStatus in BuildPagePromptLauncher and instead import the shared
predicate exported from useLatestFailedRun (the existing hook that contains the
canonical isFailedStatus), update the component's imports to reference that
exported isFailedStatus, and ensure BuildPagePromptLauncher (and any callers
using targetIsFailed) uses the imported isFailedStatus consistently so the
heuristic stays in one place.
🪄 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: cae4df87-ad66-452f-8e0a-9534c43b6298

📥 Commits

Reviewing files that changed from the base of the PR and between b43b5b7 and 84deb1e.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (40)
  • app-config.local.yaml.example
  • app-config.production.yaml
  • app-config.yaml
  • packages/app/package.json
  • packages/app/src/apis.ts
  • packages/app/src/components/Root/Root.tsx
  • packages/app/src/components/catalog/EntityPage.tsx
  • packages/app/src/components/catalog/FeatureGatedContent.tsx
  • packages/backend/package.json
  • packages/backend/src/index.ts
  • plugins/openchoreo-ci/src/hooks/index.ts
  • plugins/openchoreo-ci/src/hooks/useLatestFailedRun.ts
  • plugins/openchoreo-ci/src/index.ts
  • plugins/openchoreo-common/src/types/features.ts
  • plugins/openchoreo-perch-backend/.eslintrc.js
  • plugins/openchoreo-perch-backend/README.md
  • plugins/openchoreo-perch-backend/package.json
  • plugins/openchoreo-perch-backend/src/index.ts
  • plugins/openchoreo-perch-backend/src/plugin.test.ts
  • plugins/openchoreo-perch-backend/src/plugin.ts
  • plugins/openchoreo-perch-backend/src/router.test.ts
  • plugins/openchoreo-perch-backend/src/router.ts
  • plugins/openchoreo-perch/.eslintrc.js
  • plugins/openchoreo-perch/README.md
  • plugins/openchoreo-perch/package.json
  • plugins/openchoreo-perch/src/api/AssistantAgentApi.ts
  • plugins/openchoreo-perch/src/components/AssistantChatDrawer/AssistantChatDrawer.tsx
  • plugins/openchoreo-perch/src/components/AssistantChatDrawer/index.ts
  • plugins/openchoreo-perch/src/components/AssistantContext/AssistantDrawerContext.tsx
  • plugins/openchoreo-perch/src/components/AssistantPromptLauncher/AssistantPromptLauncher.tsx
  • plugins/openchoreo-perch/src/components/AssistantPromptLauncher/index.ts
  • plugins/openchoreo-perch/src/components/BuildPagePromptLauncher/BuildPagePromptLauncher.tsx
  • plugins/openchoreo-perch/src/components/FailedBuildSnackbar/FailedBuildSnackbar.tsx
  • plugins/openchoreo-perch/src/components/LogsPageDebugPrompt/LogsPageDebugPrompt.tsx
  • plugins/openchoreo-perch/src/index.ts
  • plugins/openchoreo-perch/src/plugin.ts
  • plugins/openchoreo-perch/tsconfig.json
  • plugins/openchoreo-react/src/hooks/useOpenChoreoFeatures.test.ts
  • plugins/openchoreo-react/src/hooks/useOpenChoreoFeatures.ts
  • plugins/openchoreo-react/src/index.ts
✅ Files skipped from review due to trivial changes (15)
  • plugins/openchoreo-perch/.eslintrc.js
  • plugins/openchoreo-perch/src/components/AssistantChatDrawer/index.ts
  • plugins/openchoreo-perch-backend/src/index.ts
  • plugins/openchoreo-perch/tsconfig.json
  • packages/app/package.json
  • plugins/openchoreo-perch/src/components/AssistantPromptLauncher/index.ts
  • packages/backend/package.json
  • plugins/openchoreo-ci/src/hooks/index.ts
  • plugins/openchoreo-perch-backend/.eslintrc.js
  • plugins/openchoreo-perch-backend/package.json
  • plugins/openchoreo-common/src/types/features.ts
  • plugins/openchoreo-perch-backend/src/plugin.ts
  • packages/backend/src/index.ts
  • packages/app/src/components/catalog/FeatureGatedContent.tsx
  • plugins/openchoreo-perch/README.md
🚧 Files skipped from review as they are similar to previous changes (16)
  • plugins/openchoreo-react/src/index.ts
  • packages/app/src/components/Root/Root.tsx
  • packages/app/src/apis.ts
  • plugins/openchoreo-perch/src/plugin.ts
  • plugins/openchoreo-ci/src/index.ts
  • plugins/openchoreo-perch-backend/src/plugin.test.ts
  • app-config.local.yaml.example
  • plugins/openchoreo-perch/src/components/FailedBuildSnackbar/FailedBuildSnackbar.tsx
  • plugins/openchoreo-react/src/hooks/useOpenChoreoFeatures.ts
  • packages/app/src/components/catalog/EntityPage.tsx
  • plugins/openchoreo-perch/src/components/AssistantPromptLauncher/AssistantPromptLauncher.tsx
  • app-config.production.yaml
  • plugins/openchoreo-perch-backend/README.md
  • plugins/openchoreo-perch/src/index.ts
  • plugins/openchoreo-perch/src/api/AssistantAgentApi.ts
  • plugins/openchoreo-perch-backend/src/router.ts

Comment thread plugins/openchoreo-perch/package.json
Comment thread plugins/openchoreo-perch/package.json Outdated
Comment thread plugins/openchoreo-perch/package.json Outdated
@yashodgayashan yashodgayashan force-pushed the perch branch 2 times, most recently from 78bef2f to 42d23ad Compare May 7, 2026 13:38
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: 1

🧹 Nitpick comments (3)
plugins/openchoreo-perch/src/api/AssistantAgentApi.ts (1)

167-175: ⚡ Quick win

Tighten the error swallow to JSON parsing only.

The current try/catch wraps both JSON.parse(trimmed) and the consumer's onEvent(...) invocation, so any exception thrown from an onEvent handler (e.g. a bug in the drawer's reducer) is silently dropped under the comment "Skip malformed JSON". Parse and dispatch separately so handler errors actually surface — they should at minimum reach the outer catch in streamChat's caller, otherwise the stream looks like it's silently working while the UI never updates.

♻️ Proposed fix
         for (const line of lines) {
           const trimmed = line.trim();
           if (!trimmed) continue;
+          let event: StreamEvent;
           try {
-            onEvent(JSON.parse(trimmed) as StreamEvent);
+            event = JSON.parse(trimmed) as StreamEvent;
           } catch {
             // Skip malformed JSON
+            continue;
           }
+          onEvent(event);
         }

The same pattern should be applied to the tail-buffer block at lines 177-184.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugins/openchoreo-perch/src/api/AssistantAgentApi.ts` around lines 167 -
175, The JSON parsing and event dispatch are currently wrapped together so
handler errors are swallowed; update the loop in AssistantAgentApi.ts to first
attempt JSON.parse(trimmed) inside a try/catch that only handles and skips
malformed JSON (so parse errors are ignored), then call onEvent(parsed as
StreamEvent) outside that parse-catch so any exceptions thrown by the consumer
handler propagate; apply the same change to the tail-buffer block that mirrors
this parsing+dispatch logic so handler exceptions are not silently swallowed
there either.
plugins/openchoreo-react/src/hooks/useOpenChoreoFeatures.ts (1)

113-121: 💤 Low value

Use /** JSDoc to match the other helper-hook docstrings.

The new hook's leading block comment opens with /* (line 114) instead of /** like every other helper hook in this file (e.g. useWorkflowsEnabled at line 74, useObservabilityEnabled at line 82, etc.). As-is, IDEs and TypeDoc will not pick this up as JSDoc for useAssistantEnabled.

♻️ Proposed fix
-/*
+/**
  * Helper hook to check if the OpenChoreo Assistant is enabled.
  * Defaults to false (opt-in).
  */
 export function useAssistantEnabled(): boolean {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugins/openchoreo-react/src/hooks/useOpenChoreoFeatures.ts` around lines 113
- 121, The leading block comment for the helper hook useAssistantEnabled uses /*
instead of JSDoc /**, so IDEs/TypeDoc won't pick up its docstring; update the
comment immediately above export function useAssistantEnabled() to start with
/** (matching other helpers like useWorkflowsEnabled and
useObservabilityEnabled) and keep the same description text and formatting so it
becomes a proper JSDoc comment.
plugins/openchoreo-perch/src/components/AssistantChatDrawer/AssistantChatDrawer.tsx (1)

442-464: 💤 Low value

Defensive fallback can attach a stale prior reply.

If event.message is ever empty/falsy on done, the fallback walks prev for the last assistant message and re-appends its content as a new turn — duplicating the previous reply. The StreamEvent contract types done.message as required string (AssistantAgentApi.ts line 71-72), so this only triggers if the agent violates the contract, but the chosen fallback is still incorrect: the in-flight turn lives in the streaming state, not in prev. Either drop the fallback (let the empty turn render) or capture the streaming buffer via a ref and use it here.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@plugins/openchoreo-perch/src/components/AssistantChatDrawer/AssistantChatDrawer.tsx`
around lines 442 - 464, The current 'done' case in the setTimeline block uses a
fallback that re-reads the last assistant message from prev and can duplicate
stale replies; instead either remove that fallback or use the in-flight
streaming buffer: create a ref (e.g., streamingBufferRef) that you update
wherever you append streaming chunks to the timeline/streaming state, then in
the 'done' handler use event.message || streamingBufferRef.current as the
content for the new assistant message (or simply use event.message and drop the
fallback), and finally clear setStreaming('')/setToolStatus(null) as before;
update references to streaming and streaming handlers to maintain the ref so the
final append uses the actual in-flight buffer rather than prev.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@plugins/openchoreo-perch-backend/src/router.ts`:
- Around line 137-155: buildForwardHeaders is currently copying most incoming
headers (leaking sensitive headers like cookie) and generates an x-request-id
that other code paths still read from req.headers; change buildForwardHeaders to
forward only a tight whitelist of safe headers (e.g., accept, accept-language,
content-type, user-agent, authorization if needed) and explicitly exclude
cookies and other sensitive headers, and return the effective request ID (the
generated or forwarded x-request-id) so callers can use that single source of
truth; update call sites that currently read req.header('x-request-id') (the
handlers that log/respond at the locations corresponding to lines ~185/186,
~223/224, ~325/326, ~331/333) to use the returned x-request-id from
buildForwardHeaders instead of reading the original request header.

---

Nitpick comments:
In `@plugins/openchoreo-perch/src/api/AssistantAgentApi.ts`:
- Around line 167-175: The JSON parsing and event dispatch are currently wrapped
together so handler errors are swallowed; update the loop in
AssistantAgentApi.ts to first attempt JSON.parse(trimmed) inside a try/catch
that only handles and skips malformed JSON (so parse errors are ignored), then
call onEvent(parsed as StreamEvent) outside that parse-catch so any exceptions
thrown by the consumer handler propagate; apply the same change to the
tail-buffer block that mirrors this parsing+dispatch logic so handler exceptions
are not silently swallowed there either.

In
`@plugins/openchoreo-perch/src/components/AssistantChatDrawer/AssistantChatDrawer.tsx`:
- Around line 442-464: The current 'done' case in the setTimeline block uses a
fallback that re-reads the last assistant message from prev and can duplicate
stale replies; instead either remove that fallback or use the in-flight
streaming buffer: create a ref (e.g., streamingBufferRef) that you update
wherever you append streaming chunks to the timeline/streaming state, then in
the 'done' handler use event.message || streamingBufferRef.current as the
content for the new assistant message (or simply use event.message and drop the
fallback), and finally clear setStreaming('')/setToolStatus(null) as before;
update references to streaming and streaming handlers to maintain the ref so the
final append uses the actual in-flight buffer rather than prev.

In `@plugins/openchoreo-react/src/hooks/useOpenChoreoFeatures.ts`:
- Around line 113-121: The leading block comment for the helper hook
useAssistantEnabled uses /* instead of JSDoc /**, so IDEs/TypeDoc won't pick up
its docstring; update the comment immediately above export function
useAssistantEnabled() to start with /** (matching other helpers like
useWorkflowsEnabled and useObservabilityEnabled) and keep the same description
text and formatting so it becomes a proper JSDoc comment.
🪄 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: 35dd5b5d-706d-4740-a6aa-1267b9e0ef80

📥 Commits

Reviewing files that changed from the base of the PR and between 84deb1e and 42d23ad.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (40)
  • app-config.local.yaml.example
  • app-config.production.yaml
  • app-config.yaml
  • packages/app/package.json
  • packages/app/src/apis.ts
  • packages/app/src/components/Root/Root.tsx
  • packages/app/src/components/catalog/EntityPage.tsx
  • packages/app/src/components/catalog/FeatureGatedContent.tsx
  • packages/backend/package.json
  • packages/backend/src/index.ts
  • plugins/openchoreo-ci/src/hooks/index.ts
  • plugins/openchoreo-ci/src/hooks/useLatestFailedRun.ts
  • plugins/openchoreo-ci/src/index.ts
  • plugins/openchoreo-common/src/types/features.ts
  • plugins/openchoreo-perch-backend/.eslintrc.js
  • plugins/openchoreo-perch-backend/README.md
  • plugins/openchoreo-perch-backend/package.json
  • plugins/openchoreo-perch-backend/src/index.ts
  • plugins/openchoreo-perch-backend/src/plugin.test.ts
  • plugins/openchoreo-perch-backend/src/plugin.ts
  • plugins/openchoreo-perch-backend/src/router.test.ts
  • plugins/openchoreo-perch-backend/src/router.ts
  • plugins/openchoreo-perch/.eslintrc.js
  • plugins/openchoreo-perch/README.md
  • plugins/openchoreo-perch/package.json
  • plugins/openchoreo-perch/src/api/AssistantAgentApi.ts
  • plugins/openchoreo-perch/src/components/AssistantChatDrawer/AssistantChatDrawer.tsx
  • plugins/openchoreo-perch/src/components/AssistantChatDrawer/index.ts
  • plugins/openchoreo-perch/src/components/AssistantContext/AssistantDrawerContext.tsx
  • plugins/openchoreo-perch/src/components/AssistantPromptLauncher/AssistantPromptLauncher.tsx
  • plugins/openchoreo-perch/src/components/AssistantPromptLauncher/index.ts
  • plugins/openchoreo-perch/src/components/BuildPagePromptLauncher/BuildPagePromptLauncher.tsx
  • plugins/openchoreo-perch/src/components/FailedBuildSnackbar/FailedBuildSnackbar.tsx
  • plugins/openchoreo-perch/src/components/LogsPageDebugPrompt/LogsPageDebugPrompt.tsx
  • plugins/openchoreo-perch/src/index.ts
  • plugins/openchoreo-perch/src/plugin.ts
  • plugins/openchoreo-perch/tsconfig.json
  • plugins/openchoreo-react/src/hooks/useOpenChoreoFeatures.test.ts
  • plugins/openchoreo-react/src/hooks/useOpenChoreoFeatures.ts
  • plugins/openchoreo-react/src/index.ts
✅ Files skipped from review due to trivial changes (11)
  • packages/app/package.json
  • plugins/openchoreo-perch/.eslintrc.js
  • plugins/openchoreo-perch/src/components/AssistantPromptLauncher/index.ts
  • plugins/openchoreo-perch-backend/src/index.ts
  • plugins/openchoreo-perch-backend/.eslintrc.js
  • plugins/openchoreo-perch/tsconfig.json
  • plugins/openchoreo-perch/src/components/AssistantChatDrawer/index.ts
  • plugins/openchoreo-perch-backend/package.json
  • plugins/openchoreo-perch/README.md
  • plugins/openchoreo-perch/src/index.ts
  • plugins/openchoreo-perch/package.json
🚧 Files skipped from review as they are similar to previous changes (18)
  • plugins/openchoreo-react/src/index.ts
  • plugins/openchoreo-ci/src/hooks/index.ts
  • packages/app/src/components/Root/Root.tsx
  • plugins/openchoreo-common/src/types/features.ts
  • plugins/openchoreo-perch-backend/src/plugin.test.ts
  • app-config.production.yaml
  • plugins/openchoreo-ci/src/index.ts
  • app-config.yaml
  • app-config.local.yaml.example
  • plugins/openchoreo-react/src/hooks/useOpenChoreoFeatures.test.ts
  • plugins/openchoreo-perch-backend/src/plugin.ts
  • plugins/openchoreo-ci/src/hooks/useLatestFailedRun.ts
  • plugins/openchoreo-perch-backend/README.md
  • packages/app/src/apis.ts
  • plugins/openchoreo-perch/src/plugin.ts
  • plugins/openchoreo-perch/src/components/AssistantContext/AssistantDrawerContext.tsx
  • plugins/openchoreo-perch/src/components/BuildPagePromptLauncher/BuildPagePromptLauncher.tsx
  • plugins/openchoreo-perch/src/components/LogsPageDebugPrompt/LogsPageDebugPrompt.tsx

Comment thread plugins/openchoreo-perch-backend/src/router.ts Outdated
@yashodgayashan yashodgayashan force-pushed the perch branch 3 times, most recently from 0c8da59 to 684e771 Compare May 7, 2026 15:45
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: 6

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/app/src/apis.ts`:
- Around line 43-46: Remove the redundant app-level assistantAgentApiRef factory
and its AssistantAgentClient import: the plugin already registers
assistantAgentApiRef in createPlugin, so delete the assistantAgentApiRef factory
registration and the AssistantAgentClient import from the app-level APIs to
avoid shadowing the plugin implementation; keep any other app-level API
registrations intact and ensure no other code references the removed factory
before committing.

In `@plugins/openchoreo-perch-backend/src/router.ts`:
- Around line 395-402: The response body read (await upstream.text()) must be
performed and error-handled before writing headers/status to the client to avoid
mid-stream failures turning into generic 500s; move the upstream.text() call
into a try-catch, read the body and on success then call res.status(...) and
applyResponseHeaders(upstream.headers, res) and send the body (res.send or
res.end), and on error catch the failure and return the plugin BAD_GATEWAY (502)
envelope with the request_id (matching the pattern used around the upstream
fetch handling earlier) so upstream connection resets are converted to proper
502 responses.

In
`@plugins/openchoreo-perch/src/components/AssistantChatDrawer/AssistantChatDrawer.tsx`:
- Around line 301-304: The useEffect that auto-scrolls the drawer (useEffect in
AssistantChatDrawer.tsx using bodyRef.current and setting el.scrollTop =
el.scrollHeight) is missing `error` in its dependency array, so add `error` to
the dependencies alongside `timeline`, `streaming`, and `toolStatus` to ensure
the drawer scrolls when an error appears; update the dependency list referenced
in that useEffect accordingly.

In
`@plugins/openchoreo-perch/src/components/AssistantPromptLauncher/AssistantPromptLauncher.tsx`:
- Around line 16-21: The launcher uses the same stacking layer as real snackbars
which can cause overlap; update the styles in useStyles (root) to lower its
z-index below snackbars by subtracting one or using a dedicated value (e.g.,
theme.zIndex.snackbar - 1 or a new theme value) so AssistantPromptLauncher
renders beneath FailedBuildSnackbar and other MUI Snackbars; change the zIndex
assignment in the root style to reference the adjusted value.
- Around line 165-176: The FAB (the <Fab> in AssistantPromptLauncher) needs an
aria-controls that points to the panel's id and focus management so assistive
tech and keyboard users can navigate: add a stable id for the panel (ensure the
panel element rendered by this component has that id), add
aria-controls={panelId} to the <Fab> (alongside existing aria-expanded), and use
refs (e.g., fabRef for the Fab and panelRef for the panel) to move focus into
the panel when setOpen(true) runs and return focus to fabRef when setOpen(false)
runs; update the onClick handler or use an effect watching open to call
panelRef.current.focus() on open and fabRef.current.focus() on close.

In `@plugins/openchoreo-perch/src/plugin.ts`:
- Around line 31-41: The plugin-level createApiFactory for assistantAgentApiRef
is duplicated by the app-level registration and is therefore shadowed; remove
the duplicate and keep a single canonical registration. Either delete the
createApiFactory entry from the openchoreoPerchPlugin apis array (the
createPlugin call that constructs AssistantAgentClient) or remove the app-level
createApiFactory for assistantAgentApiRef so only the plugin registers it;
whichever you keep, ensure the remaining factory uses AssistantAgentClient with
deps { discoveryApiRef, fetchApiRef } and update or remove the JSDoc in
openchoreoPerchPlugin/assistantAgentApiRef to reflect the chosen canonical
location.
🪄 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: 573d7b80-80f6-43e5-aad7-fc553e00316a

📥 Commits

Reviewing files that changed from the base of the PR and between 42d23ad and 0c8da59.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (42)
  • app-config.local.yaml.example
  • app-config.production.yaml
  • app-config.yaml
  • packages/app/package.json
  • packages/app/src/apis.test.ts
  • packages/app/src/apis.ts
  • packages/app/src/components/Root/Root.tsx
  • packages/app/src/components/catalog/EntityPage.tsx
  • packages/app/src/components/catalog/FeatureGatedContent.tsx
  • packages/backend/package.json
  • packages/backend/src/index.ts
  • plugins/openchoreo-ci/src/hooks/index.ts
  • plugins/openchoreo-ci/src/hooks/useLatestFailedRun.test.tsx
  • plugins/openchoreo-ci/src/hooks/useLatestFailedRun.ts
  • plugins/openchoreo-ci/src/index.ts
  • plugins/openchoreo-common/src/types/features.ts
  • plugins/openchoreo-perch-backend/.eslintrc.js
  • plugins/openchoreo-perch-backend/README.md
  • plugins/openchoreo-perch-backend/package.json
  • plugins/openchoreo-perch-backend/src/index.ts
  • plugins/openchoreo-perch-backend/src/plugin.test.ts
  • plugins/openchoreo-perch-backend/src/plugin.ts
  • plugins/openchoreo-perch-backend/src/router.test.ts
  • plugins/openchoreo-perch-backend/src/router.ts
  • plugins/openchoreo-perch/.eslintrc.js
  • plugins/openchoreo-perch/README.md
  • plugins/openchoreo-perch/package.json
  • plugins/openchoreo-perch/src/api/AssistantAgentApi.ts
  • plugins/openchoreo-perch/src/components/AssistantChatDrawer/AssistantChatDrawer.tsx
  • plugins/openchoreo-perch/src/components/AssistantChatDrawer/index.ts
  • plugins/openchoreo-perch/src/components/AssistantContext/AssistantDrawerContext.tsx
  • plugins/openchoreo-perch/src/components/AssistantPromptLauncher/AssistantPromptLauncher.tsx
  • plugins/openchoreo-perch/src/components/AssistantPromptLauncher/index.ts
  • plugins/openchoreo-perch/src/components/BuildPagePromptLauncher/BuildPagePromptLauncher.tsx
  • plugins/openchoreo-perch/src/components/FailedBuildSnackbar/FailedBuildSnackbar.tsx
  • plugins/openchoreo-perch/src/components/LogsPageDebugPrompt/LogsPageDebugPrompt.tsx
  • plugins/openchoreo-perch/src/index.ts
  • plugins/openchoreo-perch/src/plugin.ts
  • plugins/openchoreo-perch/tsconfig.json
  • plugins/openchoreo-react/src/hooks/useOpenChoreoFeatures.test.ts
  • plugins/openchoreo-react/src/hooks/useOpenChoreoFeatures.ts
  • plugins/openchoreo-react/src/index.ts
✅ Files skipped from review due to trivial changes (13)
  • plugins/openchoreo-perch/src/components/AssistantChatDrawer/index.ts
  • plugins/openchoreo-react/src/index.ts
  • plugins/openchoreo-perch-backend/src/index.ts
  • plugins/openchoreo-perch/.eslintrc.js
  • plugins/openchoreo-perch/tsconfig.json
  • plugins/openchoreo-perch/src/components/AssistantPromptLauncher/index.ts
  • plugins/openchoreo-ci/src/hooks/index.ts
  • packages/backend/package.json
  • packages/app/src/apis.test.ts
  • plugins/openchoreo-perch/package.json
  • plugins/openchoreo-perch/README.md
  • plugins/openchoreo-perch-backend/package.json
  • plugins/openchoreo-perch-backend/src/plugin.test.ts
🚧 Files skipped from review as they are similar to previous changes (20)
  • packages/app/src/components/catalog/FeatureGatedContent.tsx
  • plugins/openchoreo-perch-backend/.eslintrc.js
  • packages/app/src/components/Root/Root.tsx
  • plugins/openchoreo-ci/src/index.ts
  • app-config.local.yaml.example
  • app-config.yaml
  • plugins/openchoreo-react/src/hooks/useOpenChoreoFeatures.ts
  • app-config.production.yaml
  • plugins/openchoreo-react/src/hooks/useOpenChoreoFeatures.test.ts
  • packages/app/src/components/catalog/EntityPage.tsx
  • plugins/openchoreo-common/src/types/features.ts
  • plugins/openchoreo-perch-backend/README.md
  • plugins/openchoreo-perch-backend/src/plugin.ts
  • packages/backend/src/index.ts
  • plugins/openchoreo-perch/src/components/LogsPageDebugPrompt/LogsPageDebugPrompt.tsx
  • plugins/openchoreo-perch/src/components/BuildPagePromptLauncher/BuildPagePromptLauncher.tsx
  • plugins/openchoreo-perch/src/components/FailedBuildSnackbar/FailedBuildSnackbar.tsx
  • plugins/openchoreo-perch/src/components/AssistantContext/AssistantDrawerContext.tsx
  • plugins/openchoreo-perch/src/api/AssistantAgentApi.ts
  • plugins/openchoreo-perch/src/index.ts

Comment thread packages/app/src/apis.ts
Comment thread plugins/openchoreo-perch-backend/src/router.ts
Comment thread plugins/openchoreo-perch/src/plugin.ts
LakshanSS
LakshanSS previously approved these changes May 8, 2026
Copy link
Copy Markdown
Contributor

@LakshanSS LakshanSS left a comment

Choose a reason for hiding this comment

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

LGTM

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: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
app-config.yaml (1)

185-213: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Keep the feature-env documentation list in sync with actual keys.

Line 186’s env-var summary is now stale after adding assistant.enabled; please include OPENCHOREO_FEATURES_ASSISTANT_ENABLED (and OPENCHOREO_FEATURES_AUTHZ_ENABLED, which is also used below) to avoid operator misconfiguration.

Suggested update
-  # Environment variables: OPENCHOREO_FEATURES_WORKFLOWS_ENABLED, OPENCHOREO_FEATURES_OBSERVABILITY_ENABLED, OPENCHOREO_FEATURES_AUTH_ENABLED, OPENCHOREO_FEATURES_CILIUM_ENABLED
+  # Environment variables: OPENCHOREO_FEATURES_WORKFLOWS_ENABLED, OPENCHOREO_FEATURES_OBSERVABILITY_ENABLED, OPENCHOREO_FEATURES_AUTH_ENABLED, OPENCHOREO_FEATURES_AUTHZ_ENABLED, OPENCHOREO_FEATURES_CILIUM_ENABLED, OPENCHOREO_FEATURES_ASSISTANT_ENABLED
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app-config.yaml` around lines 185 - 213, The environment-variable summary
comment is out of date and missing the new assistant and authz feature keys;
update the top comment that lists environment variables so it includes
OPENCHOREO_FEATURES_ASSISTANT_ENABLED and OPENCHOREO_FEATURES_AUTHZ_ENABLED, and
verify the features block keys (workflows.enabled, observability.enabled,
auth.enabled, authz.enabled, cilium.enabled, assistant.enabled) match the
documented env var names so operators can configure via those variables.
🧹 Nitpick comments (1)
plugins/openchoreo-ci/src/hooks/useLatestFailedRun.test.tsx (1)

244-258: ⚡ Quick win

Double Promise.resolve() flush is fragile.

The two chained await Promise.resolve() calls at lines 248–251 assume the rejection flows through exactly two microtask hops in the hook's catch block. If the implementation adds an extra await, this flush will be insufficient and fetchBuilds may not yet be rescheduled when the 30 s timer is advanced, causing a flaky test.

A more robust pattern is to flush all pending microtasks explicitly:

♻️ Proposed fix
-      // Allow the rejected promise to settle through the catch.
-      await act(async () => {
-        await Promise.resolve();
-        await Promise.resolve();
-      });
+      // Flush all pending microtasks so the catch block fully settles.
+      await act(async () => {
+        await new Promise(resolve => setTimeout(resolve, 0));
+      });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugins/openchoreo-ci/src/hooks/useLatestFailedRun.test.tsx` around lines 244
- 258, The double await Promise.resolve() is fragile; replace it with a robust
microtask flush (e.g., await act(async () => await new Promise(r =>
setImmediate(r)))) so the rejected promise in the hook's catch always settles
before advancing timers; update the test in useLatestFailedRun.test.tsx around
the fetchBuilds assertions to call this microtask flush (referencing the
existing act(...) / jest.advanceTimersByTime(...) sequence and the fetchBuilds
mock) instead of the two chained Promise.resolve() calls.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/app/src/apis.test.ts`:
- Around line 119-123: Replace the fragile apis.find(... )! lookup and the
unused catalogApi argument with the provided helper: use findFactory(apis,
catalogGraphApiRef) to locate the factory and then invoke that factory; remove
the hardcoded 'plugin.catalog-graph.service' string and drop the unnecessary
catalogApi: stubCatalog parameter from the invoke call so the test uses the
official catalogGraphApiRef factory lookup and no longer relies on a
non-existent dep.

In `@plugins/openchoreo-ci/src/hooks/useLatestFailedRun.test.tsx`:
- Around line 40-42: The afterEach hook currently calls jest.useRealTimers() but
does not clear pending fake timers, which can leak timeouts into later tests;
update the afterEach block (the afterEach function that calls
jest.useRealTimers) to first call jest.clearAllTimers() (and optionally
jest.resetAllMocks() if needed) before calling jest.useRealTimers(), ensuring
any pending fake timers created in tests are cleared prior to restoring real
timers.
- Around line 88-100: The test mounts useLatestFailedRun repeatedly in a loop
without unmounting prior instances, leaving their effects/timers active; update
the loop so each renderHook call captures and calls its unmount (e.g., const {
result, unmount } = renderHook(() => useLatestFailedRun()) and call unmount() at
the end of each iteration) or use the testing-library cleanup between
iterations; adjust the test that iterates over statuses (using
mockUseWorkflowData and makeBuild) to unmount after each expectation to ensure
timers/effects from previous hook mounts are disposed.

In
`@plugins/openchoreo-perch/src/components/AssistantChatDrawer/AssistantChatDrawer.tsx`:
- Around line 442-463: The current done-event handler in AssistantChatDrawer.tsx
appends an assistant message using event.message || fallback which can duplicate
the last assistant message when event.message is falsy; change the logic in the
done case inside setTimeline/setStreaming handling so you only append a new
timeline entry when event.message is a non-empty string (i.e., guard before
calling setTimeline), and if event.message is empty just call setStreaming('')
and setToolStatus(null) (or log a warning) instead of using the last timeline
entry as a fallback; update references to setTimeline, setStreaming,
setToolStatus, event.message, and the fallback lookup so duplication is avoided.
- Line 754: Replace the deprecated TextField prop rowsMax with the newer maxRows
inside the AssistantChatDrawer component; locate the TextField usage in
AssistantChatDrawer (look for rowsMax={4}) and change that prop name to
maxRows={4} so Material-UI no longer emits the deprecation warning.

---

Outside diff comments:
In `@app-config.yaml`:
- Around line 185-213: The environment-variable summary comment is out of date
and missing the new assistant and authz feature keys; update the top comment
that lists environment variables so it includes
OPENCHOREO_FEATURES_ASSISTANT_ENABLED and OPENCHOREO_FEATURES_AUTHZ_ENABLED, and
verify the features block keys (workflows.enabled, observability.enabled,
auth.enabled, authz.enabled, cilium.enabled, assistant.enabled) match the
documented env var names so operators can configure via those variables.

---

Nitpick comments:
In `@plugins/openchoreo-ci/src/hooks/useLatestFailedRun.test.tsx`:
- Around line 244-258: The double await Promise.resolve() is fragile; replace it
with a robust microtask flush (e.g., await act(async () => await new Promise(r
=> setImmediate(r)))) so the rejected promise in the hook's catch always settles
before advancing timers; update the test in useLatestFailedRun.test.tsx around
the fetchBuilds assertions to call this microtask flush (referencing the
existing act(...) / jest.advanceTimersByTime(...) sequence and the fetchBuilds
mock) instead of the two chained Promise.resolve() calls.
🪄 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: 1f250f4e-94e8-4602-91ed-ceba06ac9707

📥 Commits

Reviewing files that changed from the base of the PR and between 0c8da59 and a497adc.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (42)
  • app-config.local.yaml.example
  • app-config.production.yaml
  • app-config.yaml
  • packages/app/package.json
  • packages/app/src/apis.test.ts
  • packages/app/src/apis.ts
  • packages/app/src/components/Root/Root.tsx
  • packages/app/src/components/catalog/EntityPage.tsx
  • packages/app/src/components/catalog/FeatureGatedContent.tsx
  • packages/backend/package.json
  • packages/backend/src/index.ts
  • plugins/openchoreo-ci/src/hooks/index.ts
  • plugins/openchoreo-ci/src/hooks/useLatestFailedRun.test.tsx
  • plugins/openchoreo-ci/src/hooks/useLatestFailedRun.ts
  • plugins/openchoreo-ci/src/index.ts
  • plugins/openchoreo-common/src/types/features.ts
  • plugins/openchoreo-perch-backend/.eslintrc.js
  • plugins/openchoreo-perch-backend/README.md
  • plugins/openchoreo-perch-backend/package.json
  • plugins/openchoreo-perch-backend/src/index.ts
  • plugins/openchoreo-perch-backend/src/plugin.test.ts
  • plugins/openchoreo-perch-backend/src/plugin.ts
  • plugins/openchoreo-perch-backend/src/router.test.ts
  • plugins/openchoreo-perch-backend/src/router.ts
  • plugins/openchoreo-perch/.eslintrc.js
  • plugins/openchoreo-perch/README.md
  • plugins/openchoreo-perch/package.json
  • plugins/openchoreo-perch/src/api/AssistantAgentApi.ts
  • plugins/openchoreo-perch/src/components/AssistantChatDrawer/AssistantChatDrawer.tsx
  • plugins/openchoreo-perch/src/components/AssistantChatDrawer/index.ts
  • plugins/openchoreo-perch/src/components/AssistantContext/AssistantDrawerContext.tsx
  • plugins/openchoreo-perch/src/components/AssistantPromptLauncher/AssistantPromptLauncher.tsx
  • plugins/openchoreo-perch/src/components/AssistantPromptLauncher/index.ts
  • plugins/openchoreo-perch/src/components/BuildPagePromptLauncher/BuildPagePromptLauncher.tsx
  • plugins/openchoreo-perch/src/components/FailedBuildSnackbar/FailedBuildSnackbar.tsx
  • plugins/openchoreo-perch/src/components/LogsPageDebugPrompt/LogsPageDebugPrompt.tsx
  • plugins/openchoreo-perch/src/index.ts
  • plugins/openchoreo-perch/src/plugin.ts
  • plugins/openchoreo-perch/tsconfig.json
  • plugins/openchoreo-react/src/hooks/useOpenChoreoFeatures.test.ts
  • plugins/openchoreo-react/src/hooks/useOpenChoreoFeatures.ts
  • plugins/openchoreo-react/src/index.ts
✅ Files skipped from review due to trivial changes (20)
  • plugins/openchoreo-perch-backend/.eslintrc.js
  • plugins/openchoreo-perch/.eslintrc.js
  • plugins/openchoreo-perch-backend/src/index.ts
  • packages/app/package.json
  • plugins/openchoreo-perch/src/components/AssistantPromptLauncher/index.ts
  • plugins/openchoreo-perch/tsconfig.json
  • plugins/openchoreo-ci/src/hooks/index.ts
  • plugins/openchoreo-react/src/index.ts
  • plugins/openchoreo-perch/src/plugin.ts
  • app-config.local.yaml.example
  • plugins/openchoreo-perch-backend/src/plugin.test.ts
  • packages/backend/package.json
  • plugins/openchoreo-common/src/types/features.ts
  • plugins/openchoreo-perch/src/components/AssistantChatDrawer/index.ts
  • plugins/openchoreo-perch-backend/package.json
  • plugins/openchoreo-perch-backend/README.md
  • packages/backend/src/index.ts
  • plugins/openchoreo-perch/src/index.ts
  • plugins/openchoreo-perch/package.json
  • plugins/openchoreo-perch/README.md
🚧 Files skipped from review as they are similar to previous changes (16)
  • plugins/openchoreo-ci/src/index.ts
  • plugins/openchoreo-react/src/hooks/useOpenChoreoFeatures.ts
  • app-config.production.yaml
  • packages/app/src/components/catalog/FeatureGatedContent.tsx
  • plugins/openchoreo-react/src/hooks/useOpenChoreoFeatures.test.ts
  • plugins/openchoreo-perch-backend/src/plugin.ts
  • plugins/openchoreo-perch/src/components/LogsPageDebugPrompt/LogsPageDebugPrompt.tsx
  • plugins/openchoreo-ci/src/hooks/useLatestFailedRun.ts
  • plugins/openchoreo-perch/src/components/BuildPagePromptLauncher/BuildPagePromptLauncher.tsx
  • plugins/openchoreo-perch/src/components/FailedBuildSnackbar/FailedBuildSnackbar.tsx
  • plugins/openchoreo-perch-backend/src/router.ts
  • plugins/openchoreo-perch/src/components/AssistantContext/AssistantDrawerContext.tsx
  • plugins/openchoreo-perch/src/api/AssistantAgentApi.ts
  • packages/app/src/components/catalog/EntityPage.tsx
  • plugins/openchoreo-perch/src/components/AssistantPromptLauncher/AssistantPromptLauncher.tsx
  • plugins/openchoreo-perch-backend/src/router.test.ts

Comment thread packages/app/src/apis.test.ts
Comment thread plugins/openchoreo-ci/src/hooks/useLatestFailedRun.test.tsx
Comment thread plugins/openchoreo-ci/src/hooks/useLatestFailedRun.test.tsx
@yashodgayashan yashodgayashan force-pushed the perch branch 5 times, most recently from ee3d974 to d976faf Compare May 14, 2026 02:40

const DRAWER_WIDTH = 440;

const useStyles = makeStyles(theme => ({
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Shall we move the styles to a separate file since this file is bit long

Comment thread plugins/openchoreo-perch/package.json Outdated
"react-router-dom": "^6.0.0"
},
"devDependencies": {
"@backstage/cli": "0.34.1",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
"@backstage/cli": "0.34.1",
"@backstage/cli": "0.34.3",

Mismatching backstage cli version. We have used 0.34.3 in all other files of this repo.

"@testing-library/jest-dom": "6.0.0",
"@testing-library/react": "15.0.0",
"@types/node": "20.19.13",
"@types/react": "18.0.0",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
"@types/react": "18.0.0",
"@types/react": "^18.0.0",

Comment thread packages/app/package.json
"@openchoreo/backstage-plugin-common": "workspace:^",
"@openchoreo/backstage-plugin-openchoreo-ci": "workspace:^",
"@openchoreo/backstage-plugin-openchoreo-observability": "workspace:^",
"@openchoreo/backstage-plugin-openchoreo-perch": "workspace:^",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This results in sibling package coupling, which is discouraged in the backstage ecosystem.
In the current implementation observerbility plugin directly depends on the perch plugin, and this dependency is only through InvestigateLogButton button.
Shall we pass this button as a prop to LogEntry so that we can pass this through the RuntimeLogs page via the shell app

@yashodgayashan yashodgayashan force-pushed the perch branch 2 times, most recently from c1c5cf3 to 8324f7b Compare May 14, 2026 09:40
Signed-off-by: yashodgayashan <yashodgayashan@gmail.com>
@yashodgayashan yashodgayashan merged commit 9ea456e into openchoreo:main May 14, 2026
8 checks passed
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.

3 participants