Skip to content

Conversation

@chyroc
Copy link
Contributor

@chyroc chyroc commented Nov 5, 2024

  • Added automatic authorization to obtain token
  • Supported fetching voice list from API and enabled preview playback
  • Supported fetching space and bot list from API and automated bot selection

Summary by CodeRabbit

  • New Features

    • Introduced new components for selecting workspaces, bots, and voices, enhancing user interaction.
    • Added audio playback functionality for voice previews.
    • Implemented a custom React hook for interacting with the Coze API, facilitating data fetching for bots, voices, and workspaces.
    • Added a new VoiceSelect component for selecting and cloning voice options.
    • Enhanced the RealtimeClient with options for suppressing stationary and non-stationary noise during audio interactions.
  • Bug Fixes

    • Improved error handling for OAuth token management and audio playback failures.
    • Updated error messages for configuration prompts to provide clearer guidance.
  • Documentation

    • Enhanced the Coze Realtime API documentation to reflect new noise suppression parameters.
  • Tests

    • Expanded test coverage for audio noise reduction features in the EngineClient and RealtimeClient.

@coderabbitai
Copy link

coderabbitai bot commented Nov 5, 2024

Walkthrough

The changes in this pull request involve modifications across multiple files, focusing on enhancing OAuth authentication, workspace management, and voice selection in a React application. The cspell.json configuration file was updated to include new words. Significant updates were made to Settings.tsx, introducing components for selecting workspaces, bots, and voices, along with improvements in state management and error handling. A new custom React hook, useCozeAPI, was added for interacting with the Coze API, and the WorkSpaces class's list method was updated for better response handling. Additionally, the test suite for the WorkSpaces class was simplified.

Changes

File Path Change Summary
cspell.json Updated "words" array to include "pkce" and "PKCE"; rearranged order of existing words.
examples/realtime-console/src/Settings.tsx Added constants and components for OAuth and workspace management; improved state management and error handling.
packages/coze-js/src/resources/workspaces/workspaces.ts Updated list method to return Promise<OpenSpaceData> and enhanced response handling.
examples/realtime-console/src/use-coze-api.tsx Introduced useCozeAPI hook with methods for fetching bots, voices, and workspaces.
packages/coze-js/test/resources/workspaces.spec.ts Simplified test suite by removing specific assertions related to safeJsonParse.
examples/realtime-console/src/ConsoleFooter.tsx Updated error messages for configuration prompts to improve user guidance.
examples/realtime-console/src/RealtimeConsole.tsx Changed error handling in handleInitClient to use console logging instead of user-facing messages.
examples/realtime-console/src/VoiceSelect.tsx Added VoiceSelect component for selecting and cloning voice options with audio playback.
packages/realtime-api/README.md Updated documentation to include new optional parameters for RealtimeClient initialization.
packages/realtime-api/src/client.ts Introduced private property and new methods for audio noise reduction in EngineClient.
packages/realtime-api/src/event-handler.ts Added new event names for audio noise suppression in the EventNames enum.
packages/realtime-api/src/index.ts Added optional properties for noise suppression in RealtimeClientConfig interface.
packages/realtime-api/test/client.spec.ts Enhanced test suite for EngineClient with new mocks and tests for audio noise reduction.
packages/realtime-api/test/index.spec.ts Updated tests for RealtimeClient to verify functionality related to audio noise reduction.

Possibly related PRs

  • feat: add voice api #13: The changes in this PR involve the addition of a voice API, which is relevant to the main PR's updates to the cspell.json configuration file that includes terms related to voice management, indicating a connection to voice functionalities.
  • docs: add console demo reference to README #14: This PR enhances documentation related to the realtime console, which may include references to voice settings and configurations, aligning with the main PR's focus on managing voice-related terms in the configuration file.

Suggested reviewers

  • jsongo
  • Tecvan-fe

Poem

🐇 In the land of code where bunnies play,
New words and hooks brighten the day.
With voices and bots, oh what a delight,
OAuth flows smoothly, everything feels right!
So hop along, let’s celebrate,
For changes like these, we can’t wait! 🎉


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@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

🧹 Outside diff range and nitpick comments (8)
cspell.json (1)

7-13: Consider adding more OAuth-related terms

Since the PR implements OAuth authentication functionality, consider adding these common OAuth-related terms to prevent false positives in spell checking:

   "words": [
     "packagejson",
     "pkce",
     "PKCE",
     "preinstall",
+    "oauth",
+    "authz",
+    "authn",
     "undici"
   ],
examples/realtime-console/src/net.ts (4)

78-78: Remove console.log statements from production code

The console.log statement on line 78 may clutter the console output and is generally not recommended in production code. Consider removing it or replacing it with a proper logging mechanism if needed for debugging.

Apply this diff:

-      console.log(`load ${page_index} page bots`, bots);

58-59: Maintain consistent pagination variable names across functions

In fetchAllWorkspaces, you use page_num, while in fetchAllBots, you use page_index. For consistency and readability, consider using the same variable names across your functions.

Apply this diff to rename page_index to page_num in fetchAllBots:

 export const fetchAllBots = async (
   api: CozeAPI,
   workspaceId: string,
 ): Promise<BotOption[]> => {
-  let page_index = 1;
+  let page_num = 1;
   const page_size = 20;
   let allBots: BotOption[] = [];
   let hasMore = true;

   try {
     while (hasMore) {
       const response = await api.bots.list({
         space_id: workspaceId,
         page_size,
-        page_index,
+        page_num,
       });

       const bots: BotOption[] = response.space_bots.map(bot => ({
         value: bot.bot_id,
         label: bot.bot_name,
         avatar: bot.icon_url,
       }));

       allBots = [...allBots, ...bots];
-      console.log(`load ${page_index} page bots`, bots);
+      console.log(`load ${page_num} page bots`, bots);

       hasMore = response.space_bots.length === page_size;
-      page_index++;
+      page_num++;
     }

     return allBots;
   } catch (error) {
     console.error('get bots error:', error);
     throw error;
   }
 };

Also applies to: 24-25


91-91: Specify return type for fetchAllVoices function

To enhance type safety and maintain consistency, consider specifying the return type as Promise<VoiceOption[]> for the fetchAllVoices function.

Apply this diff:

 export const fetchAllVoices = async (api: CozeAPI)
+  : Promise<VoiceOption[]> => {

95-104: Simplify voice list processing by mapping directly

Currently, you filter and separate customVoices and systemVoices and then merge them back together. You can simplify this by mapping over the entire response.voice_list and, if necessary, sort the voices afterward.

Apply this diff:

     // Merge and format voice list
-    const customVoices = response.voice_list.filter(
-      voice => !voice.is_system_voice,
-    );
-    const systemVoices = response.voice_list.filter(
-      voice => voice.is_system_voice,
-    );

-    const formattedVoices = [...customVoices, ...systemVoices].map(voice => ({
+    const formattedVoices = response.voice_list.map(voice => ({
       value: voice.voice_id,
       preview_url: voice.preview_audio,
       name: voice.name,
       language_name: voice.language_name,
       is_system_voice: voice.is_system_voice,
       label: `${voice.name} (${voice.language_name})`,
     }));

+    // Optionally sort voices if needed
+    // formattedVoices.sort((a, b) => Number(a.is_system_voice) - Number(b.is_system_voice));
examples/realtime-console/src/Settings.tsx (3)

265-294: Enhance error feedback in the loadData function

In the loadData function, when an error occurs, a generic message is displayed: 'Failed to load ' + objectName. Providing more specific error details can help users understand and resolve issues quicker. Consider appending the error message to the notification, ensuring that sensitive information is not exposed.

Update the error handling as follows:

      } catch (error) {
-        message.error('Failed to load ' + objectName);
+        message.error(`Failed to load ${objectName}: ${error.message || error}`);
        console.error(error);
      } finally {

Line range hint 452-483: Use state values instead of localStorage in the settings menu

In the settings dropdown menu, you are retrieving values directly from localStorage to display the current settings. Since these values are already stored in the component's state or form fields, consider using those instead to ensure consistency and reactiveness when the state changes.

Update the menu items to use state or form values:

          <Menu.Item key="1">
            <Text ellipsis style={{ maxWidth: 200 }} title={accessToken}>
              access_token: {accessToken || 'Not set'}
            </Text>
          </Menu.Item>
          <Menu.Item key="2">
            <Text
              ellipsis
              style={{ maxWidth: 200 }}
-             title={form.getFieldValue('workspaceId')}
+             title={selectedWorkspace}
            >
-             workspace_id: {localStorage.getItem('workspaceId') || 'Not set'}
+             workspace_id: {selectedWorkspace || 'Not set'}
            </Text>
          </Menu.Item>

132-144: Prevent multiple audio instances in the VoiceSelect component

In the VoiceSelect component, each click on the play icon may create a new audio instance if handlePreview is called multiple times rapidly. This could lead to overlapping audio playback. Consider disabling the play button while the audio is loading or playing to prevent this issue.

You can modify the handlePreview function to manage playback state:

      const [isPlaying, setIsPlaying] = useState(false);

      const handlePreview = (previewUrl: string, e: React.MouseEvent) => {
        e.stopPropagation();
+       if (isPlaying) return;

        if (audioPlayer.src === previewUrl) {
          if (audioPlayer.paused) {
            audioPlayer.play();
+           setIsPlaying(true);
          } else {
            audioPlayer.pause();
+           setIsPlaying(false);
          }
        } else {
          audioPlayer.src = previewUrl;
          audioPlayer.play();
+         setIsPlaying(true);
        }
      };

+     audioPlayer.onended = () => setIsPlaying(false);
+     audioPlayer.onpause = () => setIsPlaying(false);
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 9a8d5e4 and 109f101.

📒 Files selected for processing (3)
  • cspell.json (1 hunks)
  • examples/realtime-console/src/Settings.tsx (8 hunks)
  • examples/realtime-console/src/net.ts (1 hunks)

Copy link

@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: 3

🧹 Outside diff range and nitpick comments (1)
examples/realtime-console/src/Settings.tsx (1)

270-298: Add retry mechanism for failed API calls.

The loadData function should implement a retry mechanism to handle temporary network issues or API failures.

Consider implementing a retry mechanism:

 const loadData = async (
   api: CozeAPI,
   form: FormInstance<any>,
   objectName: string,
   dataLocalKey: string,
   setLoading: (loading: boolean) => void,
   setData: (data: any[]) => void,
   fetchData: (api: CozeAPI, id?: string) => Promise<any[]>,
   parentId?: string,
+  maxRetries: number = 3,
+  retryDelay: number = 1000,
 ): Promise<void> => {
   setLoading(true);
+  let retries = 0;
+
+  const delay = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
+
+  const attemptFetch = async (): Promise<any[]> => {
+    try {
+      return await fetchData(api, parentId);
+    } catch (error) {
+      if (retries < maxRetries) {
+        retries++;
+        await delay(retryDelay * retries);
+        return attemptFetch();
+      }
+      throw error;
+    }
+  };

   try {
-    const data = await fetchData(api, parentId);
+    const data = await attemptFetch();

     // if no data in localStorage, set the first data as default
     const storedData = localStorage.getItem(dataLocalKey);
     if (!storedData && data.length > 0) {
       const firstData = data[0].value;
       localStorage.setItem(dataLocalKey, firstData);
       form.setFieldsValue({ [dataLocalKey]: firstData });
     }
     setData(data);
   } catch (error) {
     message.error('Failed to load ' + objectName);
     console.error(error);
   } finally {
     setLoading(false);
   }
 };
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 109f101 and 6ed0b3f.

📒 Files selected for processing (2)
  • examples/realtime-console/src/Settings.tsx (8 hunks)
  • packages/coze-js/src/resources/workspaces/workspaces.ts (1 hunks)
🔇 Additional comments (1)
packages/coze-js/src/resources/workspaces/workspaces.ts (1)

24-24: Address the TODO comment regarding response format.

The TODO comment indicates a known issue with the response format. This needs to be investigated and properly documented.

Let's analyze the API response format:

Would you like me to:

  1. Create an issue to track the response format investigation?
  2. Add comprehensive response validation?

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Outside diff range and nitpick comments (6)
packages/coze-js/src/resources/workspaces/workspaces.ts (1)

26-26: Remove console.log statement.

Console.log statements should not be committed to production code. Consider using proper logging mechanisms if debugging information is needed.

-    console.log('response', response);
examples/realtime-console/src/Settings.tsx (3)

211-278: Consider enhancing token security.

While the token management implementation is solid, storing tokens in localStorage makes them vulnerable to XSS attacks. Consider:

  1. Using secure httpOnly cookies (requires backend changes)
  2. Implementing token encryption before storage
  3. Adding additional validation for token format

280-309: Consider implementing retry logic for loadData.

The loadData function handles errors well, but for better reliability, consider:

  1. Implementing retry logic for transient failures
  2. Adding timeout handling

419-423: Improve error message clarity.

The error message combines multiple fields in a single message. Consider separating the validation messages for better user experience:

-          message.error(
-            'Access Token, Workspace, Bot, and Base URL are required!',
-          );
+          const missingFields = [];
+          if (!accessToken) missingFields.push('Access Token');
+          if (!workspaceId) missingFields.push('Workspace');
+          if (!botId) missingFields.push('Bot');
+          message.error(`Please provide: ${missingFields.join(', ')}`);
examples/realtime-console/src/use-coze-api.tsx (2)

70-70: Remove console.log statement from production code

The console.log statement on line 70 is likely intended for debugging purposes. It's advisable to remove such statements from production code or replace them with a proper logging mechanism if necessary.

Apply this diff to remove the debug statement:

-        console.log(`load ${pageIndex} page bots`, bots);

45-81: Refactor pagination logic to reduce code duplication

The pagination logic in fetchAllBots and fetchAllWorkspaces is similar. Consider extracting a reusable helper function to improve maintainability and reduce code duplication.

For example, you could create a generic function to handle paginated API requests:

const fetchAllItems = async <T>(
  fetchPage: (pageIndex: number, pageSize: number) => Promise<T[]>,
  pageSize: number = 20
): Promise<T[]> => {
  let pageIndex = 1;
  let allItems: T[] = [];
  let hasMore = true;

  try {
    while (hasMore) {
      const items = await fetchPage(pageIndex, pageSize);

      allItems = [...allItems, ...items];

      hasMore = items.length === pageSize;
      pageIndex++;
    }

    return allItems;
  } catch (error) {
    throw error;
  }
};

You can then refactor fetchAllBots and fetchAllWorkspaces to use this helper function.

Also applies to: 110-140

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 6ed0b3f and 336fffd.

📒 Files selected for processing (5)
  • cspell.json (1 hunks)
  • examples/realtime-console/src/Settings.tsx (10 hunks)
  • examples/realtime-console/src/use-coze-api.tsx (1 hunks)
  • packages/coze-js/src/resources/workspaces/workspaces.ts (1 hunks)
  • packages/coze-js/test/resources/workspaces.spec.ts (0 hunks)
💤 Files with no reviewable changes (1)
  • packages/coze-js/test/resources/workspaces.spec.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • cspell.json
🔇 Additional comments (5)
packages/coze-js/src/resources/workspaces/workspaces.ts (2)

15-18: LGTM! Good type safety improvement.

The explicit Promise return type enhances type safety and makes the API contract clearer.


27-27: ⚠️ Potential issue

Previous error handling concerns are still valid.

The current implementation still lacks proper error handling and type validation as mentioned in the previous review. The response processing could fail silently or return invalid data.

Let's verify the response format across the codebase:

#!/bin/bash
# Description: Check response handling patterns in workspace-related code
# Look for potential inconsistencies in workspace response handling

# Search for workspace response processing patterns
rg -A 5 'safeJsonParse.*workspace'

# Search for OpenSpaceData type usage to verify consistent handling
ast-grep --pattern 'interface OpenSpaceData {
  $$$
}'
examples/realtime-console/src/Settings.tsx (3)

117-191: LGTM! Well-implemented VoiceSelect component with audio preview.

The component demonstrates good practices:

  • Proper audio resource cleanup
  • Error handling for audio playback
  • Accessibility attributes for the play button
  • Correct state management for play/pause

75-115: LGTM! Well-structured BotSelect component.

Good implementation with:

  • Helpful empty state message
  • Avatar handling with fallback icon
  • Proper disabled state management

564-569: Skip: Tooltip language inconsistency.

Copy link

@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: 3

🧹 Outside diff range and nitpick comments (1)
examples/realtime-console/src/Settings.tsx (1)

422-426: Improve validation message consistency.

The error message doesn't accurately reflect the required fields, and the validation could be handled by the form's built-in validation.

-if (!accessToken || !workspaceId || !botId) {
-  message.error(
-    'Access Token, Workspace, Bot, and Base URL are required!',
-  );
-  return;
-}
+const requiredFields = ['accessToken', 'workspaceId', 'botId', 'baseURL'];
+const missingFields = requiredFields.filter(field => !values[field]);
+if (missingFields.length > 0) {
+  message.error(
+    `The following fields are required: ${missingFields.join(', ')}`,
+  );
+  return;
+}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 336fffd and c8d786a.

📒 Files selected for processing (1)
  • examples/realtime-console/src/Settings.tsx (10 hunks)

Copy link

@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: 13

🧹 Outside diff range and nitpick comments (9)
examples/realtime-console/src/ConsoleFooter.tsx (3)

67-67: Consider enhancing the error message with specific configuration requirements.

While the message guides users to the Settings, it could be more helpful by indicating which configurations are required (e.g., access token, bot ID).

-      message.error('Please click Settings to set configuration first');
+      message.error('Please click Settings to configure your access token and bot ID first');

94-95: Add input validation before JSON parsing.

Consider validating the input string before attempting to parse it to provide more specific error messages and prevent unnecessary try-catch overhead.

   const handleSendMessage = (values: { eventData: string }) => {
     if (!clientRef.current) {
       message.error('Please click Settings to set configuration first');
       return;
     }
+    if (!values.eventData?.trim()) {
+      message.error('Message cannot be empty');
+      return;
+    }
     try {

107-107: Standardize optional chaining usage.

The function uses optional chaining inconsistently. Consider standardizing its usage throughout the function for better code consistency.

-    if (!clientRef?.current) {
+    if (!clientRef.current) {
       message.error('Please click Settings to set configuration first');
       return;
     }
     try {
-      clientRef?.current?.enableAudioPropertiesReport({ interval: 1000 });
+      clientRef.current.enableAudioPropertiesReport({ interval: 1000 });
examples/realtime-console/src/RealtimeConsole.tsx (3)

67-67: Consider enhancing feedback for auto-configuration process.

While the change from error message to console log aligns with the new automatic authorization flow, consider adding user feedback for cases where auto-configuration is in progress or fails.

Consider this enhancement:

-      console.log('no access token or bot id, auto config');
+      console.log('no access token or bot id, auto config');
+      message.loading({
+        content: 'Attempting automatic configuration...',
+        key: 'autoConfig'
+      });

Line range hint 71-82: Consider adding retry mechanism for client initialization.

The client initialization could benefit from a retry mechanism when using automatic configuration, especially since the token might not be immediately available.

Consider adding a retry mechanism:

     const client = new RealtimeClient({
       accessToken: accessToken.trim(),
       botId: botId.trim(),
       voiceId: voiceId.trim(),
-      // conversationId: '1234567890', // Optional
+      retryAttempts: 3, // Add retry attempts
+      retryDelay: 1000, // Add delay between retries
       debug: true,
       baseURL: baseURL.trim(),
       allowPersonalAccessTokenInBrowser: true,
       audioMutedDefault: !isMicrophoneOn,
     });

Line range hint 126-159: Consider optimizing event merging logic.

The mergeEvent function could be optimized to handle more event types and reduce unnecessary iterations.

Consider this optimization:

   const mergeEvent = (prevEvents: any[], event: any) => {
-    if (prevEvents.length === 0) {
+    const lastEvent = prevEvents[prevEvents.length - 1];
+    if (!lastEvent) {
       return null;
     }
-    const lastEvent = prevEvents[prevEvents.length - 1];
     if (
       lastEvent.event === 'conversation.message.delta' &&
       event.event === 'conversation.message.delta'
     ) {
       return {
         time: lastEvent.time,
         event: lastEvent.event,
         data: {
           ...lastEvent.data,
           data: {
             ...lastEvent.data.data,
             content: lastEvent.data.data.content + event.data.data.content,
           },
         },
       };
     }
     return null;
   };
examples/realtime-console/src/Settings.tsx (1)

371-377: Enhance form validation logic

The form validation could be improved by:

  1. Using form-level validation rules instead of manual checks
  2. Adding proper type checking for values
  3. Implementing more descriptive error messages
-  const { workspaceId, botId, voiceId } = values;
-  if (!accessToken || !workspaceId || !botId) {
-    message.error(
-      'Access Token, Workspace, Bot, and Base URL are required!',
-    );
-    return;
-  }
+  const { workspaceId, botId, voiceId, baseURL } = values;
+  
+  // Validate required fields using form rules
+  form.setFields([
+    {
+      name: 'accessToken',
+      errors: !accessToken ? ['Access Token is required'] : [],
+    },
+    {
+      name: 'workspaceId',
+      errors: !workspaceId ? ['Please select a workspace'] : [],
+    },
+    {
+      name: 'botId',
+      errors: !botId ? ['Please select a bot'] : [],
+    },
+    {
+      name: 'baseURL',
+      errors: !baseURL ? ['Base URL is required'] : 
+              !/^https?:\/\/.+/.test(baseURL) ? ['Invalid URL format'] : [],
+    },
+  ]);
examples/realtime-console/src/use-coze-api.tsx (1)

74-74: Consider removing or adjusting the debug log statement

The console.log statement used for debugging may not be suitable for production code as it can clutter the console and potentially reveal sensitive information. Consider using a logging library with appropriate log levels or remove the statement before deploying.

examples/realtime-console/src/VoiceSelect.tsx (1)

30-30: Remove debugging console.log statement

The console.log('voice xx', voice); appears to be a leftover from debugging. It's best practice to remove such statements in production code to keep the console output clean.

Apply this diff to remove the debugging statement:

-   console.log('voice xx', voice);
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between c8d786a and da4d1e7.

📒 Files selected for processing (5)
  • examples/realtime-console/src/ConsoleFooter.tsx (4 hunks)
  • examples/realtime-console/src/RealtimeConsole.tsx (1 hunks)
  • examples/realtime-console/src/Settings.tsx (10 hunks)
  • examples/realtime-console/src/VoiceSelect.tsx (1 hunks)
  • examples/realtime-console/src/use-coze-api.tsx (1 hunks)
🔇 Additional comments (2)
examples/realtime-console/src/ConsoleFooter.tsx (1)

Line range hint 67-121: Overall improvement in user guidance with room for enhancement.

The consistent update of error messages across all functions improves user guidance by directing them to the Settings configuration. However, consider implementing the suggested improvements to enhance:

  1. Error message specificity
  2. Permission handling
  3. Input validation
  4. Code consistency
  5. Error handling organization

These changes would further improve the robustness and maintainability of the component while maintaining its enhanced user experience.

examples/realtime-console/src/RealtimeConsole.tsx (1)

Line range hint 64-82: Verify error handling consistency with auto-configuration flow.

The initialization logic needs to be verified against the new automatic authorization flow mentioned in the PR objectives.

Let's verify the auto-configuration implementation:

✅ Verification successful

Let me gather more information about the auto-configuration implementation.


Let me check one more aspect to understand the OAuth flow implementation better.


Error handling is consistent with auto-configuration flow

The implementation correctly handles the auto-configuration scenario:

  • When access token/bot ID is missing, it logs and returns early with appropriate user feedback
  • OAuth flow is properly implemented with PKCE for secure token exchange
  • Comprehensive error handling exists for token refresh, exchange, and validation
  • User is appropriately guided to configure settings when required through consistent error messages
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for auto-configuration implementation and related error handling

# Test 1: Look for auto-configuration implementation
echo "Checking for auto-configuration implementation..."
rg -l "auto.*config" --type ts --type tsx

# Test 2: Check error handling patterns across the codebase
echo "Checking error handling patterns..."
ast-grep --pattern 'message.error($$$)'

Length of output: 3467


Script:

#!/bin/bash
# Search for auto-configuration related code in RealtimeConsole.tsx and Settings.tsx
echo "Checking RealtimeConsole.tsx implementation..."
rg "auto.*config|!accessToken.*return" examples/realtime-console/src/RealtimeConsole.tsx -A 5

echo -e "\nChecking Settings.tsx implementation..."
rg "auto.*config|initializeOAuth|exchangeCodeForToken" examples/realtime-console/src/Settings.tsx -A 5

Length of output: 945


Script:

#!/bin/bash
# Check for OAuth flow implementation and configuration handling
echo "Checking OAuth implementation..."
rg "getPKCEOAuthToken|initializeOAuth" examples/realtime-console/src/Settings.tsx -B 5 -A 10

echo -e "\nChecking configuration state management..."
rg "setToken|setAccessToken|setBotId" examples/realtime-console/src/Settings.tsx -B 2 -A 2

Length of output: 2466

Copy link

@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

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 26fe53b and 6e9d211.

⛔ Files ignored due to path filters (1)
  • common/config/subspaces/default/pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (3)
  • examples/realtime-console/package.json (2 hunks)
  • examples/realtime-console/src/RealtimeConsole.tsx (4 hunks)
  • packages/realtime-api/src/index.ts (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • examples/realtime-console/src/RealtimeConsole.tsx
  • packages/realtime-api/src/index.ts
🔇 Additional comments (1)
examples/realtime-console/package.json (1)

139-139: LGTM! Surge dependency is correctly configured.

The surge package is appropriately added as a devDependency since it's only needed for deployment operations.

@jsongo jsongo merged commit 023746c into main Nov 7, 2024
4 checks passed
@jsongo jsongo deleted the feat-realtime-console branch November 7, 2024 09:00
@coderabbitai coderabbitai bot mentioned this pull request Feb 6, 2025
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