Skip to content

feat: connection check for Radarr and Sonarr#5

Open
kid1412621 wants to merge 5 commits intomainfrom
feat/sonarr-radarr-connection
Open

feat: connection check for Radarr and Sonarr#5
kid1412621 wants to merge 5 commits intomainfrom
feat/sonarr-radarr-connection

Conversation

@kid1412621
Copy link
Copy Markdown
Owner

No description provided.

@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello @kid1412621, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly improves the user experience for configuring external service connections by introducing a unified and reusable set of UI components and backend logic. It enables real-time connection testing for Radarr and Sonarr, giving users immediate validation of their settings. Furthermore, the media agent's capabilities are expanded with new tools to query content from these services, laying groundwork for more advanced automation.

Highlights

  • Reusable Connection UI Components: Introduced new shared React components (ConnectableHeader, ConnectableFields) and a hook (useConnectableTest) to standardize the UI and logic for connecting to external services like Radarr, Sonarr, and Trakt.
  • Radarr and Sonarr Connection Testing: Implemented a backend API endpoint (/api/settings/test-connection) and corresponding service methods to allow users to test their Radarr and Sonarr connection details directly from the settings page, providing immediate feedback on configuration.
  • Agent Tool Enhancements: Added new agent tools (createSonarrListTool and createRadarrListTool) to enable the media agent to list existing TV shows and movies from Sonarr and Radarr libraries, respectively.
  • UI Refactoring: Refactored the existing Radarr, Sonarr, and Trakt settings components to utilize the new reusable connection components, reducing code duplication and improving consistency.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • client/src/components/settings/ai-settings.tsx
    • Refactored pasteFromClipboard function into a shared utility.
  • client/src/components/settings/connectable-settings.tsx
    • Added new components and a hook for managing connectable service settings, including pasteFromClipboard, ConnectableHeader, ConnectableFields, and useConnectableTest.
  • client/src/components/settings/radarr-settings.tsx
    • Updated Radarr settings to use shared connectable components and integrate connection testing.
  • client/src/components/settings/sonarr-settings.tsx
    • Updated Sonarr settings to use shared connectable components and integrate connection testing.
  • client/src/components/settings/trakt-settings.tsx
    • Refactored Trakt settings to use the new ConnectableHeader and shared pasteFromClipboard utility.
  • client/src/routes/settings.tsx
    • Added padding to the settings page container for improved layout.
  • server/src/agents/media_agent.ts
    • Integrated new Sonarr and Radarr list tools into the media agent's available tools.
  • server/src/agents/tools.ts
    • Implemented new tools (createSonarrListTool, createRadarrListTool) for listing Sonarr series and Radarr movies.
  • server/src/routes/settings.ts
    • Added a new API endpoint (/test-connection) for testing Sonarr and Radarr connections.
  • server/src/services/radarr.ts
    • Implemented methods for retrieving system status and testing Radarr connections.
  • server/src/services/sonarr.ts
    • Implemented methods for retrieving system status and testing Sonarr connections.
Activity
  • No specific activity has been recorded for this pull request yet.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@kid1412621
Copy link
Copy Markdown
Owner Author

/Gemini review

@kid1412621
Copy link
Copy Markdown
Owner Author

@codex review

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces connection checks for Radarr and Sonarr, enhancing the reliability of service integrations. It also refactors common UI components into a new connectable-settings.tsx file, improving code reusability and maintainability across different service settings. Additionally, new tools for listing items in Sonarr and Radarr libraries have been added to the media agent, expanding its capabilities.

const text = await navigator.clipboard.readText();
field.handleChange(text);
} catch (err) {
console.error('Failed to read clipboard', err);
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.

medium

The error message logged here is generic. While err is passed, it's more helpful to explicitly include the error's message or string representation in the log message for better debugging.

Suggested change
console.error('Failed to read clipboard', err);
console.error('Failed to read clipboard:', err.message || err);

Comment thread client/src/components/settings/connectable-settings.tsx
Comment thread client/src/components/settings/connectable-settings.tsx Outdated
Comment thread server/src/agents/tools.ts
Comment thread server/src/agents/tools.ts
Comment thread server/src/services/radarr.ts Outdated
Comment thread server/src/services/sonarr.ts Outdated
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a connection test feature for Radarr and Sonarr, which is a great addition for user experience. The refactoring of the settings components into a reusable connectable-settings module is very well done and significantly improves code structure and maintainability. I've left a few comments with suggestions for improvement, mainly concerning strengthening type safety in the frontend, adjusting the behavior of the connection test to avoid unintended side effects, improving error handling in the new agent tools, and enhancing code structure on the backend. Overall, this is a solid contribution.

Comment thread client/src/components/settings/connectable-settings.tsx Outdated
}

interface ConnectableFieldsProps {
form: any;
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.

medium

The form prop is typed as any. Throughout this file and related components (radarr-settings, sonarr-settings, etc.), any is used for form and field types. This weakens type safety and should be avoided. Please use the specific types from @tanstack/react-form, such as UseFormReturn<T> for forms and FieldApi<...> for fields. You will need to import these types. This will improve code quality and prevent potential bugs.

Suggested change
form: any;
form: any; // Use a specific type e.g. UseFormReturn<SettingsForm>

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

/Gemini review

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.

Thank you for the re-review, kid1412621! I appreciate you addressing the type safety concerns. The refactoring to use useAppFormContext and useAppForm from @/lib/form is a significant improvement, effectively removing the any type from the form props across your components. This greatly enhances type safety and maintainability.

I noticed a couple of minor instances where any is still explicitly used within form.Subscribe components. While not as critical as the form prop itself, removing these explicit any types would allow TypeScript to infer the correct types, further improving code clarity and type safety.

For example, in client/src/routes/onboarding.tsx and client/src/routes/settings.tsx, the selector and children props of form.Subscribe still use any. You can remove these explicit any annotations, as the types can be inferred from the form object, which is now correctly typed as AppFormApi<SettingsForm>.

Here's a suggestion for one such instance:

Suggested change
form: any;
selector={(state) => state.errors}
children={(errors) => (

Comment on lines +209 to +211
} catch (error) {
return `Error listing Sonarr series: ${error}`;
}
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.

medium

Exposing raw error objects in the string returned to the LLM can leak internal implementation details or stack traces. It's safer to log the detailed error on the server and return a generic, user-friendly error message to the agent. This also applies to the createRadarrListTool.

            } catch (error) {
                logger.error('Error listing Sonarr series: {error}', { error });
                return 'An error occurred while trying to list series from Sonarr.';
            }

Comment on lines +46 to +50
const { type, url, apiKey } = await c.req.json<{
type: 'sonarr' | 'radarr';
url: string;
apiKey: string;
}>();
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.

medium

The type for the /test-connection request body is defined inline. To improve maintainability and ensure type consistency between the client and server, it's best practice to define this type in the shared package and import it here. This would be similar to how SettingsForm is handled.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6e5757f933

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +21 to +23
disabled={
!form.getFieldValue('radarrUrl') ||
!form.getFieldValue('radarrApiKey')
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Subscribe to form values before disabling Connect

disabled (and the helper URL passed below) are derived from form.getFieldValue(...) during render, but this component is not subscribed to those fields, so it may not re-render when users type. On first-time setup with empty Radarr/Sonarr fields, the Connect button can remain disabled (and helper URL stale) until an unrelated re-render happens, which blocks the new connection-test flow for normal input entry.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

@codex review

Comment on lines +200 to +203
const results = await sonarrService.getSeries(userId);
return JSON.stringify(
results.map((s) => ({
title: s.title,
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Cap library list tool output before returning JSON

This list tool returns the entire library payload with no limit or pagination, unlike other tools in this file that slice results. For users with large Sonarr/Radarr libraries, serializing all items into one tool response can blow up token usage and make agent turns slow or fail due context limits.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: da1c58060e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

testConnection,
} = useConnectableTest('radarr', 'radarrUrl', 'radarrApiKey');

const radarrUrl = form.getFieldValue('radarrUrl');
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Subscribe to Radarr fields before deriving connect state

radarrUrl is read via form.getFieldValue outside a form.Subscribe, so this component can keep using the initial values instead of the latest edits. In practice, users can type a URL/API key in the AppFields but still see the connect button stay disabled and the API-key helper link missing until some unrelated rerender occurs. Derive these values from a subscribed form state (or inside field render callbacks) so the header and helper URL update immediately with input changes.

Useful? React with 👍 / 👎.

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