Skip to content

feat(webui): integrate Runtime WebUI chat into AgentScope Studio#122

Open
zhijianma wants to merge 4 commits intoagentscope-ai:mainfrom
zhijianma:feat/webui
Open

feat(webui): integrate Runtime WebUI chat into AgentScope Studio#122
zhijianma wants to merge 4 commits intoagentscope-ai:mainfrom
zhijianma:feat/webui

Conversation

@zhijianma
Copy link
Member

Description

[Please describe the background, purpose, changes made, and how to test this PR]

Checklist

Please check the following items before code is ready to be reviewed.

  • Code has been formatted with npm run format command in the root directory
  • Docstrings/comments are in appropriate style (TSDoc/JSDoc for TypeScript/JavaScript, Google style for Python)
  • Related documentation has been updated (e.g. links, examples, etc.)
  • Code is ready for review

@gemini-code-assist
Copy link

Summary of Changes

Hello @zhijianma, 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 enhances the AgentScope Studio by introducing a fully integrated and configurable Runtime WebUI chat experience. It provides users with a dedicated interface to interact with agents at runtime, complete with extensive customization options for appearance, messaging, and API connectivity. This addition not only expands the platform's capabilities but also improves the overall user experience by centralizing agent interaction within the studio environment.

Highlights

  • Runtime WebUI Chat Integration: The core feature of this pull request is the integration of the AgentScope Runtime WebUI chat component into AgentScope Studio, providing a dedicated interface for runtime chat interactions.
  • Configurable Chat Options: A new OptionsEditor component has been introduced, allowing users to customize various aspects of the Runtime Chat, including theme (colors, dark mode, logo, title), sender behavior (disclaimer, max length), welcome messages (greeting, description, avatar, prompts), and API settings (baseURL, token).
  • New 'Services' Section: A new 'Services' section has been added to the sidebar navigation, which currently houses the 'Runtime Chat' page, improving application structure and discoverability for new features.
  • Dependency Updates: New dependencies, including @agentscope-ai/chat, @rc-component/util, and @radix-ui/react-checkbox, have been added to support the new chat functionality and UI components.
  • Console Warning Suppression: Logic has been added to main.tsx to suppress known, harmless console warnings originating from third-party libraries like antd-style/emotion and React/Ant Design, improving developer console clarity.
Changelog
  • package.json
    • Added @rc-component/util to overrides.
    • Added @radix-ui/react-checkbox to dependencies.
  • packages/client/package.json
    • Added @agentscope-ai/chat to dependencies.
  • packages/client/src/components/chat/bubbles/MarkdownRender/index.tsx
    • Updated CSS selector from :first-child to :first-of-type for paragraph styling.
  • packages/client/src/components/ui/button-group.tsx
    • Updated CSS selectors from :first-child to :first-of-type for button group styling.
  • packages/client/src/i18n/en.json
    • Added new translation keys for 'services' and 'runtime-chat'.
  • packages/client/src/i18n/zh.json
    • Added new Chinese translation keys for '服务' and 'Runtime WebUI'.
  • packages/client/src/main.tsx
    • Implemented console error suppression for specific React and Emotion warnings.
  • packages/client/src/pages/HomePage/config.tsx
    • Imported MessageSquareIcon from lucide-react.
    • Added a new 'Services' group to the sidebar configuration, including a 'Runtime Chat' item with its icon and URL.
  • packages/client/src/pages/HomePage/index.tsx
    • Imported ServicesPage component.
    • Added a new route for /services/* to render the ServicesPage.
  • packages/client/src/pages/RouterPath.ts
    • Added SERVICES and SERVICES_RUNTIME_CHAT enum values to define new routing paths.
  • packages/client/src/pages/ServicesPage/RuntimeChatPage/OptionsEditor.tsx
    • Added a new component OptionsEditor for configuring Runtime Chat settings, including theme, sender, welcome messages, and API.
  • packages/client/src/pages/ServicesPage/RuntimeChatPage/OptionsPanel.tsx
    • Added a new component OptionsPanel to provide a UI for opening and interacting with the OptionsEditor.
  • packages/client/src/pages/ServicesPage/RuntimeChatPage/defaultConfig.ts
    • Added a new file defining the default configuration object for the Runtime Chat WebUI.
  • packages/client/src/pages/ServicesPage/RuntimeChatPage/index.tsx
    • Added a new page component RuntimeChatPage that integrates the AgentScopeRuntimeWebUI component, manages its configuration via local storage, and incorporates the OptionsPanel.
  • packages/client/src/pages/ServicesPage/RuntimeChatPage/sessionApi.ts
    • Added a new file defining a SessionApi class that implements IAgentScopeRuntimeWebUISessionAPI for managing chat sessions using local storage.
  • packages/client/src/pages/ServicesPage/index.tsx
    • Added a new page component ServicesPage to handle routing for service-related features, specifically the RuntimeChatPage.
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.

Copy link

@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 integrates the Runtime WebUI chat into AgentScope Studio, adding a new 'Services' section with a configurable chat interface. The changes are extensive, including new dependencies, routing, UI components, and state management for chat options and sessions. My review focuses on improving robustness, type safety, and maintainability. Key feedback includes addressing the risky practice of monkey-patching console.error, improving the session management logic in sessionApi.ts to be more robust, and enhancing type safety in the new React components to prevent potential runtime errors and improve developer experience.

Comment on lines +7 to +20
// Suppress known harmless warnings from third-party libraries (antd-style/emotion, React/antd)
// 1. emotion `:first-child` SSR warning — irrelevant for this client-side SPA
// 2. React `flushSync` lifecycle warning — triggered internally by antd components
const _origConsoleError = console.error;
console.error = (...args: unknown[]) => {
const msg = typeof args[0] === 'string' ? args[0] : '';
if (msg.includes(':first-child') && msg.includes('potentially unsafe')) {
return;
}
if (msg.includes('flushSync') && msg.includes('lifecycle')) {
return;
}
_origConsoleError.apply(console, args);
};

Choose a reason for hiding this comment

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

high

Monkey-patching console.error to suppress warnings is a risky practice. While the suppressed warnings might seem harmless now, this approach can hide other legitimate errors in the future, making debugging difficult. It also affects the entire application globally. Since you've already changed :first-child to :first-of-type in some components, which is the correct fix for the emotion SSR warning, could this global override be removed or scoped more narrowly? If suppression is absolutely necessary, consider creating a higher-order component or a custom hook that temporarily suppresses warnings only around the specific components that trigger them.

Comment on lines +65 to +67
const [formData, setFormData] = useState<Record<string, unknown>>(() =>
structuredClone(value ?? {}),
);

Choose a reason for hiding this comment

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

high

The component state formData is typed as Record<string, unknown>, which provides very little type safety. This leads to the use of unsafe type assertions (e.g., as string) and risky patterns throughout the component when accessing nested properties. If the data structure changes, these assertions can lead to runtime errors that are hard to debug.

It would be much safer to define a proper interface for the options object and use it for the state: useState<MyOptionsType>(...). This would enable static type checking and improve the overall robustness and maintainability of the component.

Comment on lines +10 to +13
constructor() {
this.lsKey = 'as-studio-runtime-chat-sessions';
this.sessionList = [];
}

Choose a reason for hiding this comment

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

high

The sessionList is only populated from localStorage inside getSessionList, which makes the class fragile as it depends on methods being called in a specific order. Also, JSON.parse in getSessionList is not in a try-catch block, which can crash the app.

Consider loading the data safely in the constructor to ensure the class is always in a valid state upon instantiation. If you apply this change, you can simplify getSessionList to just return [...this.sessionList];.

    constructor() {
        this.lsKey = 'as-studio-runtime-chat-sessions';
        try {
            this.sessionList = JSON.parse(localStorage.getItem(this.lsKey) || '[]');
        } catch {
            this.sessionList = [];
        }
    }

);
}

const OptionsEditor: React.FC<OptionsEditorProps> = ({

Choose a reason for hiding this comment

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

medium

This component is over 400 lines long and handles the editing of many different sections of the configuration (Theme, Sender, Welcome, API). This makes it difficult to read, understand, and maintain.

Consider refactoring this into smaller, more focused components. For example, you could create separate components for each configuration section (ThemeEditor, SenderEditor, etc.). Each of these smaller components would be responsible for its own part of the form, making the code more modular and easier to manage.

Comment on lines +77 to +79
const leftHeaderConfig = (
optionsConfig as Record<string, Record<string, unknown>>
)?.theme?.leftHeader as { logo?: string; title?: string } | undefined;

Choose a reason for hiding this comment

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

medium

This complex type assertion reduces type safety and makes the code harder to read. It would be better to define a strong type for the optionsConfig state, which would eliminate the need for such casts and improve maintainability. The as unknown as IAgentScopeRuntimeWebUIOptions on line 99 is another symptom of this issue. A stronger type for optionsConfig would allow for safer property access and remove the need for these unsafe casts.

}

async createSession(session: Partial<IAgentScopeRuntimeWebUISession>) {
session.id = Date.now().toString();

Choose a reason for hiding this comment

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

medium

Using Date.now().toString() as a session ID is not guaranteed to be unique. If createSession is called multiple times in the same millisecond, it will generate duplicate IDs, which can lead to bugs. A more robust approach is to use a universally unique identifier, like crypto.randomUUID().

        session.id = crypto.randomUUID();

@github-actions
Copy link

This PR is marked as stale because there has been no activity for 30 days. Remove stale label or add new comments or this PR will be closed in 5 day.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant