diff --git a/.gitattributes b/.gitattributes index dcee3a14925171a6399b9375eadead6a52f07689..7172842aaad6ef8720de48c3de9cfca2f476f921 100644 --- a/.gitattributes +++ b/.gitattributes @@ -31,6 +31,7 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text **/*ckpt*.meta filter=lfs diff=lfs merge=lfs -text **/*ckpt*.index filter=lfs diff=lfs merge=lfs -text *.safetensors filter=lfs diff=lfs merge=lfs -text -*.ckpt filter=lfs diff=lfs merge=lfs -text -*.whl filter=lfs diff=lfs merge=lfs -text -*.mp4 filter=lfs diff=lfs merge=lfs -text +*.ckpt filter=lfs diff=lfs merge=lfs -textcomponents/Chatbot/resources/dog.mp4 filter=lfs diff=lfs merge=lfs -text +components/Markdown/resources/dog.mp4 filter=lfs diff=lfs merge=lfs -text +modelscope_gradio_components-0.0.1b8-py3-none-any.whl filter=lfs diff=lfs merge=lfs -text +components/Chatbot/resources/dog.mp4 filter=lfs diff=lfs merge=lfs -text diff --git a/DOCS.md b/DOCS.md new file mode 100644 index 0000000000000000000000000000000000000000..44a339e41e7e7f2688b651fbe61f81bdf2b966a3 --- /dev/null +++ b/DOCS.md @@ -0,0 +1,15 @@ +# ModelScope Gradio Components + +ModelScope_Gradio_Components is a set of extension component libraries based on gradio 4.x, dedicated to serving the various extension needs of gradio applications within the ModelScope Studio. It mainly focuses on enhancing conversational scenarios, supporting multimodal contexts, and providing assistance for various other specialized scenarios. + +## Install + +```sh +pip install modelscope_gradio_components +``` + +## Components + +- Chatbot +- MultimodalInput +- Markdown diff --git a/Dockerfile b/Dockerfile index 02d9fbef0166f776e36177b00c1e0a9e0dd526ff..6898e9365f8c11bf792fab806c33e930086f16fa 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,3 +1,4 @@ + FROM python:3.9 WORKDIR /code @@ -6,7 +7,7 @@ COPY --link --chown=1000 . . RUN mkdir -p /tmp/cache/ RUN chmod a+rwx -R /tmp/cache/ -ENV TRANSFORMERS_CACHE=/tmp/cache/ +ENV TRANSFORMERS_CACHE=/tmp/cache/ RUN pip install --no-cache-dir -r requirements.txt diff --git a/README-zh_CN.md b/README-zh_CN.md index fa6b26947c86adcca54ec550368e67c989f4e0d8..228bab72e0be1f64d05b970f8ce73438e16d49bf 100644 --- a/README-zh_CN.md +++ b/README-zh_CN.md @@ -1,15 +1,4 @@ -

ModelScope Studio

- -

- - - ✖️ - - -

- -

-GitHub | 🤖 ModelScope Studio | 🤗 Hugging Face Space +# ModelScope Studio `modelscope_studio` 是一套基于 gradio 4.x 的扩展组件库,致力于服务于 ModelScope 创空间中对于 gradio 应用的各类扩展需求,目前主要聚集在对话场景增强、多模态场景以及一些其他垂直场景支持。 @@ -19,15 +8,8 @@ pip install modelscope_studio ``` -## API - -- load - ## Components - Chatbot - MultimodalInput - Markdown -- WaterfallGallery -- Lifecycle -- Flow diff --git a/README.md b/README.md index d66732f798a89c38dd1b735e504479ada60f47e4..4a8e19ea5a69f69c56f31ce6a0eb29aabc9f273f 100644 --- a/README.md +++ b/README.md @@ -6,26 +6,15 @@ tags: - Markdown - gradio-template-Chatbot - gradio-template-Markdown -title: modelscope-studio -colorFrom: blue -colorTo: gray +title: modelscope_gradio_components V0.0.1b8 +colorFrom: red +colorTo: red sdk: docker pinned: false license: apache-2.0 --- -

ModelScope Studio

- -

- - - ✖️ - - -

- -

-GitHub | 🤖 ModelScope Studio | 🤗 Hugging Face Space +# ModelScope Studio `modelscope_studio` is a set of extension component libraries based on gradio 4.x, dedicated to serving the various extension needs of gradio applications within the ModelScope Studio. It mainly focuses on enhancing conversational scenarios, supporting multimodal contexts, and providing assistance for various other specialized scenarios. @@ -35,15 +24,8 @@ license: apache-2.0 pip install modelscope_studio ``` -## API - -- load - ## Components - Chatbot - MultimodalInput - Markdown -- Lifecycle -- WaterfallGallery -- Flow diff --git a/api/app.py b/api/app.py deleted file mode 100644 index 85d6e013ef392b6d67f2a963eadf87dc6c3b5e91..0000000000000000000000000000000000000000 --- a/api/app.py +++ /dev/null @@ -1,19 +0,0 @@ -import os - -from components.Docs import Docs - - -def resolve(relative_path: str): - return os.path.join(os.path.dirname(__file__), relative_path) - - -docs = Docs( - __file__, - markdown_files=([ - filename for filename in os.listdir(resolve('.')) - if filename.endswith(".md") - ]), -) - -if __name__ == "__main__": - docs.render().queue().launch() diff --git a/api/load-zh_CN.md b/api/load-zh_CN.md deleted file mode 100644 index b953acd98aa48211bff6c1ecb19673fc5da3b85e..0000000000000000000000000000000000000000 --- a/api/load-zh_CN.md +++ /dev/null @@ -1,30 +0,0 @@ -# load - -该特性与 [gr.load](https://www.gradio.app/docs/gradio/load) 类似。允许用户从已有创空间 [ModelScope Studio](https://modelscope.cn/studios) 仓库构造 demo。 - -## 如何使用 - -### 基本使用 - -```python -import modelscope_studio as mgr -demo = mgr.load("modelscope/modelscope-studio") -demo.launch() -``` - -### 使用访问令牌 - -使用访问令牌来加载私有创空间。在这里找到您的 sdk 令牌:https://modelscope.cn/my/myaccesstoken。 - -```python -import modelscope_studio as mgr -demo = mgr.load("modelscope/modelscope-studio", token="YOUR_ACCESS_TOKEN") -demo.launch() -``` - -## 初始化 - -| 属性 | 类型 | 默认值 | 描述 | -| ----- | ---- | ------ | ---------------------------------------------------------------------------------------------------- | -| name | str | None | 必填。 创空间名称(如: "modelscope/modelscope-studio")。 | -| token | str | None | 用于加载私有创空间的可选访问令牌。 在这里找到您的 sdk 令牌:https://modelscope.cn/my/myaccesstoken。 | diff --git a/api/load.md b/api/load.md deleted file mode 100644 index f1d4d401593d26d590edadeaeab62df09387a037..0000000000000000000000000000000000000000 --- a/api/load.md +++ /dev/null @@ -1,30 +0,0 @@ -# load - -This feature is similar to [gr.load](https://www.gradio.app/docs/gradio/load). Allow users to Construct a demo from a [ModelScope Studio](https://modelscope.cn/studios) repo. - -## How to Use - -### Basic Usage - -```python -import modelscope_studio as mgr -demo = mgr.load("modelscope/modelscope-studio") -demo.launch() -``` - -### With Access Token - -Use the access token to load a private ModelScope Studio repo. Find your sdk token here: https://modelscope.cn/my/myaccesstoken. - -```python -import modelscope_studio as mgr -demo = mgr.load("modelscope/modelscope-studio", token="YOUR_ACCESS_TOKEN") -demo.launch() -``` - -## Initialization - -| Parameter | Type | Default Value | Description | -| --------- | ---- | ------------- | ----------------------------------------------------------------------------------------------------------------------------------- | -| name | str | None | required. the name of the ModelScope Studio repo (e.g. "modelscope/modelscope-studio"). | -| token | str | None | optional access token for loading private ModelScope Studio repo. Find your sdk token here: https://modelscope.cn/my/myaccesstoken. | diff --git a/app.py b/app.py index 1d93e6b40e04a12732eadb1472f4fef93d1c286a..41659af68b2e1bca6472fbc7d8b25c8da1033d52 100644 --- a/app.py +++ b/app.py @@ -1,24 +1,16 @@ import gradio as gr -from api.app import docs as api_docs from components.Chatbot.app import docs as chatbot_docs from components.Docs import Docs -from components.Flow.app import docs as flow_docs -from components.Lifecycle.app import docs as lifecycle_docs from components.Markdown.app import docs as markdown_docs from components.MultimodalInput.app import docs as multimodel_input_docs -from components.WaterfallGallery.app import docs as waterfall_gallery_docs readme_docs = Docs(__file__) docs = [ ["Quick Start", readme_docs], - ["API", api_docs], ["Chatbot", chatbot_docs], - ["MultimodalInput", multimodel_input_docs], ["Markdown", markdown_docs], - ["Lifecycle", lifecycle_docs], - ["WaterfallGallery", waterfall_gallery_docs], - ["Flow", flow_docs], + ["MultimodalInput", multimodel_input_docs], ] with gr.Blocks() as demo: diff --git a/components/Chatbot/README-zh_CN.md b/components/Chatbot/README-zh_CN.md index d88ea4a8279f43b69b804108bd63606bd26c6771..6229af0559e80a5414ea789c69a3b05a9f3d9869 100644 --- a/components/Chatbot/README-zh_CN.md +++ b/components/Chatbot/README-zh_CN.md @@ -3,10 +3,9 @@ 升级版的 gradio Chatbot。 - 支持前端匀速流式输出 message -- 支持输出多模态内容(音频、视频、图片、文本) -- 内置标签(chart、select-box、accordion) +- 支持输出多模态内容(音频、视频、语音、文件、文本) - 支持多 agent 场景 -- 支持自定义渲染组件,并与 Python 事件交互 +- 支持自定义渲染组件,并与 Python 侧事件交互 ## 如何使用 @@ -54,12 +53,6 @@ Observation: 「任意 md 内容,将作为完成调用的展示的下 -### 支持图表展示 - -在返回的内容中加入 `chart` 标签,更多用法详见 Markdown 内置自定义标签 - - - ### 多 bot 场景 @@ -84,12 +77,6 @@ class FileMessage(GradioModel): class MultimodalMessage(GradioModel): - # 默认以 index 为作为 id,id 改变会导致 message 重新渲染 - id: Optional[str] = None - # message 容器的 elem id - elem_id: Optional[str] = None - # message 容器的 elem classes - elem_classes: Optional[List[str] | str] = None name: Optional[str] = None text: Optional[str] = None flushing: Optional[bool] = None @@ -109,21 +96,19 @@ class ChatbotData(GradioRootModel): ### props -| 属性 | 类型 | 默认值 | 描述 | -| ----------------------------- | -------------------------------------------------------------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| flushing | bool | True | 是否开启打字机效果。默认只有 bot 的 message 会开启,可以通过单独修改 message 的 flushing 属性精确控制每一条 message 的显示效果 | -| enable_base64 | bool | False | 是否支持渲染的内容为 base64,因为直接渲染 base64 会带来安全问题,默认为 False。 | -| enable_latex | bool | True | 是否支持 Latex 公式渲染 | -| latex_single_dollar_delimiter | bool | True | 是否支持单`$`符号在 Latex 公式中渲染 | -| preview | bool | True | 是否开启图片预览功能 | -| avatar_images | tuple\[str \| Path \| None \| dict \| list, str \| Path \| None \| dict\| list\] | None | 拓展gr.Chatbot的参数值,除了接收 url 外还可以接收 dict 和 list,dict 可以传入avatar和name字段,name字段在渲染时会显示在头像下方。
- 当传入 dict 时,必须包含有avatar字段。
- 当传入 list 时,一般对应多 bot 模式,每一项可以接收前面所有的值,每个 bot 的头像与 message 中 bot 的位置一一对应 | -| avatar_image_align | Literal['top', 'middle', 'bottom'] | 'bottom' | 控制头像与 message 的对齐方式,默认为下对齐 | -| avatar_image_width | int | 45 | 头像与名称的宽度 | -| flushing_speed | int | 3 | 打字机速度,值为 1 - 10,值越大速度越快 | -| llm_thinking_presets | list\[dict\] | \[\] | llm 思考链路解析预设,可以将 llm 调用工具的输出格式转为固定的前端展示格式,需要从modelscope_studio.Chatbot.llm_thinking_presets引入,目前支持:qwen | -| custom_components | dict\[str, CustomComponentDict\] CustomComponentDict 定义见下方 | None | 支持用户定义自定义标签,并通过 js 控制标签渲染样式与触发 python 事件。 | - -**CustomComponentDict 定义如下** +| 属性 | 类型 | 默认值 | 描述 | +| -------------------- | -------------------------------------------------------------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| flushing | bool | True | 是否开启打字机效果。默认只有 bot 的 message 会开启,可以通过单独修改 message 的 flushing 属性精确控制每一条 message 的显示效果 | +| enable_base64 | bool | False | 是否支持渲染的内容为 base64,因为直接渲染 base64 有安全问题,默认为 False。 | +| preview | bool | True | 是否开启图片预览功能 | +| avatar_images | tuple\[str \| Path \| None \| dict \| list, str \| Path \| None \| dict\| list\] | None | 拓展gr.Chatbot的参数值,除了接收 url 外还可以接收 dict 和 list,dict 可以传入avatar和name字段,name字段在渲染时会显示在头像下方。
- 当传入 dict 时,必须包含有avatar字段。
- 当传入 list 时,一般对应多 bot 模式,每一项可以接收前面所有的值,每个 bot 的头像与 message 中 bot 的位置一一对应 | +| avatar_image_align | Literal['top', 'middle', 'bottom'] | 'bottom' | 控制头像与 message 的对齐方式,默认为下对齐 | +| avatar_image_width | int | 45 | 头像与名称的宽度 | +| flushing_speed | int | 3 | 打字机速度,值为 1 - 10,值越大速度越快 | +| llm_thinking_presets | list\[dict\] | \[\] | llm 思考链路解析预设,可以将 llm 调用工具的输出格式转为固定的前端展示格式,需要从modelscope_studio.Chatbot.llm_thinking_presets引入,目前支持:qwen | +| custom_components | dict\[str, CustomComponentDict\] CustomComponentDict 定义见下方 | None | 支持用户定义自定义标签,并通过 js 控制标签渲染样式与触发 python 事件。 | + +**CustomComponent 定义如下** ```python class CustomComponentDict(TypedDict): @@ -138,7 +123,7 @@ class CustomComponentDict(TypedDict): ### event listeners -| 事件 | 描述 | -| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `mgr.Chatbot.flushed(fn, ···)` | 当打字机效果结束时触发。EventData 为:
- index:当前 message 的 index tuple。
- value:当前 message value。 | -| `mgr.Chatbot.custom(fn, ···)` | 自定义标签触发事件时触发,EventData 为:
- index:当前 message 的 index tuple ([message index, user group(index 0) or bot group(index 1), user/bot group index])。
- tag:当前触发的标签。
- tag_index:当前触发标签的 index,此 index 在 message 的 index tuple 基础上重新计算。
- value:自定义传入的值。 | +| 事件 | 描述 | +| ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `mgr.Chatbot.flushed(fn, ···)` | 当打字机效果结束时触发。EventData 为:
- index:当前 message 的 index tuple。
- value:当前 message value。 | +| `mgr.Chatbot.custom(fn, ···)` | 自定义标签触发事件时触发,EventData 为:
- index:前 message 的 index tuple。
- tag:当前触发的标签。
- tag_index:当前触发标签的 index,此 index 在 mesage 的 index tuple 基础上重新计算。
- value:自定义传入的值。 | diff --git a/components/Chatbot/README.md b/components/Chatbot/README.md index 21d1904d6ff739bbe3a81ff3b6a4f0293e64384a..048c83e3f0f79604e02289f14986cf446a3e6c81 100644 --- a/components/Chatbot/README.md +++ b/components/Chatbot/README.md @@ -3,10 +3,9 @@ Upgraded gradio Chatbot. - Supports uniform frontend streaming output of messages -- Supports output of multimodal content (audio, video, image, text) -- Built-in tags (chart, select-box, accordion) +- Supports output of multimodal content (audio, video, voice, files, text) - Supports multi-agent scenarios -- Supports custom rendering components and interaction with Python events +- Supports custom rendering components and interaction with events on the Python side ## How to Use @@ -49,16 +48,10 @@ Observation: 「Any md content will be displayed in the drop-down box wh ### Support for User Selection Interaction -Include the `select-box` tag in the returned content. For more usage details, see Markdown Built-in Custom Tags . +Include the `select-box` tag in the returned content for more usage details, see Markdown Built-in Custom Tags . -### Support for Chart Display - -Include the `chart` tag in the returned content. For more usage details, see Markdown Built-in Custom Tags . - - - ### Multi-bot Scenarios @@ -83,12 +76,6 @@ class FileMessage(GradioModel): class MultimodalMessage(GradioModel): - # By default, message index is used as id. it will cause the message to be re-rendered when id changed. - id: Optional[str] = None - # elem id of message container - elem_id: Optional[str] = None - # elem classes of message container - elem_classes: Optional[List[str] | str] = None name: Optional[str] = None text: Optional[str] = None flushing: Optional[bool] = None @@ -108,19 +95,17 @@ class ChatbotData(GradioRootModel): ### props -| Attribute | Type | Default Value | Description | -| ----------------------------- | -------------------------------------------------------------------------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| flushing | bool | True | Whether to enable the typewriter effect. By default, only the bot's messages will have this effect, but you can control the display effect of each message precisely by modifying the flushing attribute of a message individually. | -| enable_base64 | bool | False | Whether to support rendering content as base64, since rendering base64 is unsafe, the default is False. | -| enable_latex | bool | True | Whether to enable LaTeX rendering. | -| latex_single_dollar_delimiter | bool | True | Whether to enable single dollar delimiter `$` for LaTeX rendering. | -| preview | bool | True | Whether to enable image preview functionality. | -| avatar_images | tuple\[str \| Path \| None \| dict \| list, str \| Path \| None \| dict\| list\] | None | An extended parameter value for gr.Chatbot, in addition to accepting a URL, it can also accept a dict and list. The dict can include the fields avatar and name, where the name field will be displayed under the avatar when rendered.
- When passing a dict, it must include an avatar field.
- When passing a list, it generally corresponds to the multi-bot mode, where each item can receive all the aforementioned values, and each bot’s avatar matches with the position of the bot in the messages. | -| avatar_image_align | Literal['top', 'middle', 'bottom'] | 'bottom' | Controls the alignment of the avatar with the messages, default is bottom-aligned. | -| avatar_image_width | int | 45 | The width of the avatar and name. | -| flushing_speed | int | 3 | Typewriter speed, values range from 1 - 10, with larger values indicating faster speeds. | -| llm_thinking_presets | list\[dict\] | \[\] | llm thinking link presets, which can convert the output format of llm calling tools into a fixed front-end display format. It needs to be imported from modelscope_studio.Chatbot.llm_thinking_presets, and currently supports: qwen. | -| custom_components | dict\[str, CustomComponentDict\] CustomComponentDict is defined below | None | Allows users to define custom tags and control tag rendering styles and trigger Python events through JS. | +| Attribute | Type | Default Value | Description | +| -------------------- | -------------------------------------------------------------------------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| flushing | bool | True | Whether to enable the typewriter effect. By default, only the bot's messages will have this effect, but you can control the display effect of each message precisely by modifying the flushing attribute of a message individually. | +| enable_base64 | bool | False | Whether to support rendering content as base64, since rendering base64 is not safe, the default is False. | +| preview | bool | True | Whether to enable image preview functionality. | +| avatar_images | tuple\[str \| Path \| None \| dict \| list, str \| Path \| None \| dict\| list\] | None | An extended parameter value for gr.Chatbot, in addition to accepting a URL, it can also accept a dict and list. The dict can include the fields avatar and name, where the name field will be displayed under the avatar when rendered.
- When passing a dict, it must include an avatar field.
- When passing a list, it generally corresponds to the multi-bot mode, where each item can receive all the aforementioned values, and each bot’s avatar matches with the position of the bot in the messages. | +| avatar_image_align | Literal['top', 'middle', 'bottom'] | 'bottom' | Controls the alignment of the avatar with the messages, default is bottom-aligned. | +| avatar_image_width | int | 45 | The width of the avatar and name. | +| flushing_speed | int | 3 | Typewriter speed, values range from 1 - 10, with larger values indicating faster speeds. | +| llm_thinking_presets | list\[dict\] | \[\] | llm thinking link presets, which can convert the output format of llm calling tools into a fixed front-end display format. It needs to be imported from modelscope_studio.Chatbot.llm_thinking_presets, and currently supports: qwen. | +| custom_components | dict\[str, CustomComponentDict\] CustomComponentDict is defined below | None | Allows users to define custom tags and control tag rendering styles and trigger Python events through JS. | **Definition of CustomComponent is as follows:** @@ -137,7 +122,7 @@ See Markdown Built-in Custom Tags ### event listeners -| Event | Description | -| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `mgr.Chatbot.flushed(fn, ···)` | Triggered when the typewriter effect ends. EventData is:
- index: The index tuple of the current message.
- value: The current message value. | -| `mgr.Chatbot.custom(fn, ···)` | Triggered when a custom tag event occurs. EventData is:
- index: The index tuple of the current message ([message index, user group(index 0) or bot group(index 1), user/bot group index]).
- tag: The current tag that triggered the event.
- tag_index: The index of the current triggered tag, re-calculated based on the message’s index tuple.
- value: The custom value passed in. | +| Event | Description | +| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `mgr.Chatbot.flushed(fn, ···)` | Triggered when the typewriter effect ends. EventData is:
- index: The index tuple of the current message.
- value: The current message value. | +| `mgr.Chatbot.custom(fn, ···)` | Triggered when a custom tag event occurs. EventData is:
- index: The index tuple of the previous message.
- tag: The current tag that triggered the event.
- tag_index: The index of the current triggered tag, re-calculated based on the index tuple of the message.
- value: The custom value passed in. | diff --git a/components/Chatbot/demos/.DS_Store b/components/Chatbot/demos/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..5008ddfcf53c02e82d7eee2e57c38e5672ef89f6 Binary files /dev/null and b/components/Chatbot/demos/.DS_Store differ diff --git a/components/Chatbot/demos/accordion.py b/components/Chatbot/demos/accordion.py index 2f6430bdc6a7143c975a0592b082448dee4bd3ad..ec571ecc489ac6adf0e702cf452faf969de463cd 100644 --- a/components/Chatbot/demos/accordion.py +++ b/components/Chatbot/demos/accordion.py @@ -1,13 +1,12 @@ import os import gradio as gr - import modelscope_studio as mgr from modelscope_studio.components.Chatbot.llm_thinking_presets import qwen def resolve_assets(relative_path): - return os.path.join(os.path.dirname(__file__), "../../resources", + return os.path.join(os.path.dirname(__file__), "../resources", relative_path) @@ -16,13 +15,11 @@ conversation = [ None, { "text": f""" Use accordion tag: - ```json {{"text": "glorious weather", "resolution": "1024*1024"}} ``` - Qwen preset: diff --git a/components/Chatbot/demos/basic.py b/components/Chatbot/demos/basic.py index 6c5361d9783044dbcdd96df790c0dadf46516d54..090485af8d05eaad3835514ba930b19f89f1c82c 100644 --- a/components/Chatbot/demos/basic.py +++ b/components/Chatbot/demos/basic.py @@ -2,7 +2,6 @@ import os import time import gradio as gr - import modelscope_studio as mgr conversation = [ @@ -35,14 +34,14 @@ with gr.Blocks() as demo: chatbot = mgr.Chatbot( value=conversation, avatar_images=[ - os.path.join(os.path.dirname(__file__), - "../../resources/user.jpeg"), { - "name": - "bot", - "avatar": - os.path.join(os.path.dirname(__file__), - "../../resources/bot.jpeg") - } + os.path.join(os.path.dirname(__file__), "../resources/user.jpeg"), + { + "name": + "bot", + "avatar": + os.path.join(os.path.dirname(__file__), + "../resources/bot.jpeg") + } ], height=600, ) diff --git a/components/Chatbot/demos/chart.py b/components/Chatbot/demos/chart.py deleted file mode 100644 index c07b3e0e215952acf6481c6cb7acbd8bb2b77be7..0000000000000000000000000000000000000000 --- a/components/Chatbot/demos/chart.py +++ /dev/null @@ -1,43 +0,0 @@ -import json - -import gradio as gr - -import modelscope_studio as mgr - -# echarts options, see: https://echarts.apache.org/en/index.html -option1 = { - "xAxis": { - "type": 'category', - "data": ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], - }, - "yAxis": { - "type": 'value', - }, - "series": [ - { - "data": [150, 230, 224, 218, 135, 147, 260], - "type": 'line', - }, - ], -} - -conversation = [ - [ - None, { - "text": f""" -Chart: - -""" - } - ], -] - -with gr.Blocks() as demo: - mgr.Chatbot( - value=conversation, - flushing=False, - height=600, - ) - -if __name__ == "__main__": - demo.queue().launch() diff --git a/components/Chatbot/demos/message_config.py b/components/Chatbot/demos/message_config.py index b2fe3e1bb71a97e0ca18ef343ab05ca2ef492d96..12566f3c5500b67f4c9efacaa29e817af1f8db91 100644 --- a/components/Chatbot/demos/message_config.py +++ b/components/Chatbot/demos/message_config.py @@ -1,7 +1,6 @@ import time import gradio as gr - import modelscope_studio as mgr diff --git a/components/Chatbot/demos/multi_bots.py b/components/Chatbot/demos/multi_bots.py index ea167a88d208c38080900a857a2822115a0063f5..13f6642ec1b9155443566235b727bf56689f47af 100644 --- a/components/Chatbot/demos/multi_bots.py +++ b/components/Chatbot/demos/multi_bots.py @@ -2,12 +2,11 @@ import os import time import gradio as gr - import modelscope_studio as mgr def resolve_assets(relative_path): - return os.path.join(os.path.dirname(__file__), "../../resources", + return os.path.join(os.path.dirname(__file__), "../resources", relative_path) diff --git a/components/Chatbot/demos/multimodal.py b/components/Chatbot/demos/multimodal.py index 28aebe4cc924df119e89230790e40e180e806dbe..066cd7d8941f38070daccc472fc72ddfd3387577 100644 --- a/components/Chatbot/demos/multimodal.py +++ b/components/Chatbot/demos/multimodal.py @@ -1,12 +1,11 @@ import os import gradio as gr - import modelscope_studio as mgr def resolve_assets(relative_path): - return os.path.join(os.path.dirname(__file__), "../../resources", + return os.path.join(os.path.dirname(__file__), "../resources", relative_path) diff --git a/components/Chatbot/demos/select-box.py b/components/Chatbot/demos/select-box.py index 6035ba30cf5f7a956396693b600560e34c49073a..97b73cf91b5173c53c5211f0cf61fba49d56de37 100644 --- a/components/Chatbot/demos/select-box.py +++ b/components/Chatbot/demos/select-box.py @@ -1,7 +1,6 @@ import json import gradio as gr - import modelscope_studio as mgr # `label` will display on the page, and `value` is the actual selected value. diff --git a/components/resources/audio.wav b/components/Chatbot/resources/audio.wav similarity index 100% rename from components/resources/audio.wav rename to components/Chatbot/resources/audio.wav diff --git a/components/resources/bot.jpeg b/components/Chatbot/resources/bot.jpeg similarity index 100% rename from components/resources/bot.jpeg rename to components/Chatbot/resources/bot.jpeg diff --git a/components/Chatbot/resources/custom_components/custom_select.js b/components/Chatbot/resources/custom_components/custom_select.js new file mode 100644 index 0000000000000000000000000000000000000000..ca7e2ae712ca53eff775d1f5b22d9c004720db0b --- /dev/null +++ b/components/Chatbot/resources/custom_components/custom_select.js @@ -0,0 +1,26 @@ +(props, cc, { el, onMount }) => { + const options = JSON.parse(props.options); + el.innerHTML = ` + ${options + .map((option) => { + return `

+ +
`; + }) + .join('')} + `; + onMount(() => { + const inputs = Array.from(el.getElementsByTagName('input')); + Array.from(el.getElementsByTagName('label')).forEach((label, i) => { + label.addEventListener('click', () => { + inputs.forEach((input) => { + input.checked = false; + }); + const input = label.getElementsByTagName('input')[0]; + input.checked = true; + // Use cc.dispatch to trigger events. + cc.dispatch(options[i]); + }); + }); + }); +}; diff --git a/components/resources/dog.mp4 b/components/Chatbot/resources/dog.mp4 similarity index 100% rename from components/resources/dog.mp4 rename to components/Chatbot/resources/dog.mp4 diff --git a/components/resources/image-bot.jpeg b/components/Chatbot/resources/image-bot.jpeg similarity index 100% rename from components/resources/image-bot.jpeg rename to components/Chatbot/resources/image-bot.jpeg diff --git a/components/resources/music-bot.jpeg b/components/Chatbot/resources/music-bot.jpeg similarity index 100% rename from components/resources/music-bot.jpeg rename to components/Chatbot/resources/music-bot.jpeg diff --git a/components/resources/screen.jpeg b/components/Chatbot/resources/screen.jpeg similarity index 100% rename from components/resources/screen.jpeg rename to components/Chatbot/resources/screen.jpeg diff --git a/components/resources/user.jpeg b/components/Chatbot/resources/user.jpeg similarity index 100% rename from components/resources/user.jpeg rename to components/Chatbot/resources/user.jpeg diff --git a/components/Docs.py b/components/Docs.py index 71d863bb5d9ed10a6636d868c680ec0651460432..b0932b912662ccf20ce17632fdb37a36d22bd00d 100644 --- a/components/Docs.py +++ b/components/Docs.py @@ -3,7 +3,6 @@ import re from typing import Callable import gradio as gr - import modelscope_studio as mgr from .parse_markdown import parse_markdown @@ -49,7 +48,7 @@ def get_demo_modules(file_path: str): demos = [ demo for demo in list_demos( os.path.join(os.path.dirname(file_path), "demos")) - if demo.endswith(".py") and not demo.startswith("__") + if demo.endswith(".py") ] demo_modules = {} for demo in demos: @@ -93,41 +92,23 @@ class Docs: "r") as f: return f.read() - def render_demo(self, - demo_name, - code_position='left', - prefix='', - suffix=''): + def render_demo(self, demo_name, prefix='', suffix=''): content = self.read_file(f"./demos/{demo_name}.py") module = self.demo_modules[demo_name] with gr.Accordion("Show Demo", open=False): - - def render_code(): - mgr.Markdown(f"""{prefix} + with gr.Row(): + with gr.Column(): + mgr.Markdown(f""" +{prefix} ````python {content} ```` -{suffix}""", - header_links=True, - custom_components=custom_components) - - if code_position == 'top': - with gr.Row(): - with gr.Column(): - render_code() - with gr.Row(): - if code_position == 'left': - with gr.Column(): - render_code() +{suffix} +""", + header_links=True, + custom_components=custom_components) with gr.Column(): module.demo.render() - if code_position == 'right': - with gr.Column(): - render_code() - if code_position == 'bottom': - with gr.Row(): - with gr.Column(): - render_code() def render_markdown(self, markdown_file, @@ -139,16 +120,14 @@ class Docs: if item["type"] == "text": md = mgr.Markdown(item["value"], header_links=True, - custom_components=custom_components, - preview=False) + custom_components=custom_components) deps = [dep for dep in [components_tabs, self.tabs] if dep] if len(deps) > 0: md.custom(fn=on_tab_link_click, outputs=deps) elif item["type"] == "demo": self.render_demo(item["name"], prefix=item["prefix"], - suffix=item["suffix"], - code_position=item["code_position"]) + suffix=item["suffix"]) def render(self, components_tabs=None): diff --git a/components/Flow/README-zh_CN.md b/components/Flow/README-zh_CN.md deleted file mode 100644 index 0c4afb7e97c43aaa3d69acdaacdae787a32d4892..0000000000000000000000000000000000000000 --- a/components/Flow/README-zh_CN.md +++ /dev/null @@ -1,109 +0,0 @@ -# Flow - -基于 [reactflow](https://reactflow.dev/) 实现的 Flow 组件。 - -- 支持通过 schema 自定义渲染节点 -- 支持自定义节点的渲染组件,并与 Python 事件交互 - -## 如何使用 - -### 定义 schema 节点 (重要) - -详见:Define Schema - -### 基本使用 - - - -### 组件配置项 - - - -### 自定义节点类型(高阶用法,需要了解前端知识) - - - -## API 及参数列表 - -### value - -接口定义: - -```python -class NodePosition(GradioModel): - x: Optional[int] = 0 - y: Optional[int] = 0 - - -class Node(GradioModel): - id: Optional[str] = None - name: str - title: Optional[str] = None - position: Optional[Union[NodePosition, dict]] = None - data: Optional[dict] = None - -class EdgePort(GradioModel): - attr: Optional[str] = None - attrItemIndex: Optional[int] = None - handleIndex: Optional[int] = None - -class Edge(GradioModel): - id: Optional[str] = None - source: str - target: str - sourcePort: Optional[Union[EdgePort, dict]] = None - targetPort: Optional[Union[EdgePort, dict]] = None - - -class FlowData(GradioModel): - nodes: Optional[List[Union[Node, dict]]] = [] - edges: Optional[List[Union[Edge, dict]]] = [] - -``` - -### props - -| 属性 | 类型 | 默认值 | 描述 | -| ------------------- | --------------------------------------------------------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| height | int \| str | 600 | Flow 组件高度。 | -| sync_on_data_change | bool | None | 是否仅在数据更改时同步 Python 值(例如:节点属性、节点计数、边缘计数、连接端口等,不包括节点位置)。 如果您想要更好的页面性能而不是完整数据同步,则应将其设置为 True。 | -| schema | FlowSchemaDict \| dict | None | 定义 Flow 组件的 nodes 与 edges。 | -| show_sidebar | bool | True | 是否展示侧 Flow 组件侧边栏。 | -| show_minimap | bool | True | 是否展示侧 Flow 组件小地图。 | -| show_controls | bool | True | 是否展示侧Flow 组件控制栏。 | -| background_props | BackgroundPropsDict \| dict CustomComponentDict 定义见下方 | None | 修改 Flow组件背景,详见 BackgroundPropsDict 类型。 | -| min_zoom | int | 0.1 | Flow 组件最小缩放倍率。 | -| max_zoom | int | 2 | Flow 组件最大缩放倍率。 | -| custom_components | dict\[str, CustomComponentDict\] CustomComponentDict 定义见下方 | None | 支持用户自定义节点类型,并通过 js 控制渲染样式与触发 python 事件。 | - -**BackgroundPropsDict 定义如下** - -```python -class BackgroundPropsDict(TypedDict): - color: Optional[str] - className: Optional[str] - # The gap between patterns. Passing in a tuple allows you to control the x and y gap independently. - gap: Optional[Union[int, Tuple[int, int]]] - # The radius of each dot or the size of each rectangle if BackgroundVariant.Dots or BackgroundVariant.Cross is used. This defaults to 1 or 6 respectively, or ignored if BackgroundVariant.Lines is used. - size: Optional[int] - offset: Optional[int] - lineWidth: Optional[int] - variant: Optional[Literal['dots', 'lines', 'cross']] -``` - -**CustomComponentDict 定义如下** - -```python -class CustomComponentDict(TypedDict): - props: Optional[List[str]] - template: Optional[str] - js: Optional[str] -``` - -### event listeners - -| 事件 | 描述 | -| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `mgr.Flow.change(fn, ···)` | 当 value 更新时触发,如果 sync_on_data_change 值为 True 时,此时 flow 的实际数据可能并不是实时的,建议监听 data_change 事件。 | -| `mgr.Flow.data_change(fn, ···)` | 当在数据更改时触发(例如:节点属性、节点计数、边缘计数、连接端口等,不包括节点位置) | -| `mgr.Flow.custom(fn, ···)` | 自定义标签触发事件时触发,EventData 为:
- id:当前触发节点 id。
- node:当前触发节点类型。
- attr:当前触发节点属性。
- index:当前触发节点属性索引,当节点属性为 list 时有值。
- value:自定义传入的值。 | diff --git a/components/Flow/README.md b/components/Flow/README.md deleted file mode 100644 index b7ebf875a609b8127407d48177bb836b692f4d46..0000000000000000000000000000000000000000 --- a/components/Flow/README.md +++ /dev/null @@ -1,108 +0,0 @@ -# Flow - -A Flow component implemented based on [reactflow](https://reactflow.dev/). - -- Supports customization of node rendering through a schema. -- Allows for custom node render components with interaction from Python. - -## How to Use - -### Defining Schema Nodes (Important) - -See: Define Schema - -### Basic Usage - - - -### Component Options - - - -### Custom Node Types (Advanced usage, requires frontend knowledge) - - - -## API and Parameter List - -### value - -Interface definition: - -```python -class NodePosition(GradioModel): - x: Optional[int] = 0 - y: Optional[int] = 0 - - -class Node(GradioModel): - id: Optional[str] = None - name: str - title: Optional[str] = None - position: Optional[Union[NodePosition, dict]] = None - data: Optional[dict] = None - -class EdgePort(GradioModel): - attr: Optional[str] = None - attrItemIndex: Optional[int] = None - handleIndex: Optional[int] = None - -class Edge(GradioModel): - id: Optional[str] = None - source: str - target: str - sourcePort: Optional[Union[EdgePort, dict]] = None - targetPort: Optional[Union[EdgePort, dict]] = None - - -class FlowData(GradioModel): - nodes: Optional[List[Union[Node, dict]]] = [] - edges: Optional[List[Union[Edge, dict]]] = [] -``` - -### props - -| Attribute | Type | Default Value | Description | -| ------------------- | --------------------------------------------------------------------- | ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| height | int \| str | 600 | Height of the Flow component. | -| sync_on_data_change | bool | None | Whether to sync the Python value only on data change (e.g., node attributes, node count, edge count, connection ports, not including node positions). If you want better page performance without full data sync, set this to True. | -| schema | FlowSchemaDict \| dict | None | Defines the nodes and edges of the Flow component. | -| show_sidebar | bool | True | Whether to display the sidebar in the Flow component. | -| show_minimap | bool | True | Whether to display the minimap in the Flow component. | -| show_controls | bool | True | Whether to display the controls bar in the Flow component. | -| background_props | BackgroundPropsDict \| dict BackgroundPropsDict definition below | None | Modify the background of the Flow component, see the BackgroundPropsDict type. | -| min_zoom | int | 0.1 | Minimum zoom level for the Flow component. | -| max_zoom | int | 2 | Maximum zoom level for the Flow component. | -| custom_components | dict\[str, CustomComponentDict\] CustomComponentDict definition below | None | Supports user-defined custom tags and controls tag rendering styles and triggers Python events through js. | - -**BackgroundPropsDict definition:** - -```python -class BackgroundPropsDict(TypedDict): - color: Optional[str] - className: Optional[str] - # The gap between patterns. Passing in a tuple allows you to control the x and y gap independently. - gap: Optional[Union[int, Tuple[int, int]]] - # The radius of each dot or the size of each rectangle if BackgroundVariant.Dots or BackgroundVariant.Cross is used. This defaults to 1 or 6 respectively, or ignored if BackgroundVariant.Lines is used. - size: Optional[int] - offset: Optional[int] - lineWidth: Optional[int] - variant: Optional[Literal['dots', 'lines', 'cross']] -``` - -**CustomComponentDict definition:** - -```python -class CustomComponentDict(TypedDict): - props: Optional[List[str]] - template: Optional[str] - js: Optional[str] -``` - -### Event Listeners - -| Event | Description | -| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `mgr.Flow.change(fn, ...)` | Triggers when the `value` updates. If `sync_on_data_change` is True, the actual data at this point might not be up-to-date; consider listening to the `data_change` event instead. | -| `mgr.Flow.data_change(fn, ...)` | Triggers when there's a data change (e.g., node attributes, node count, edge count, connection ports), but not node positions. | -| `mgr.Flow.custom(fn, ...)` | Triggers when a custom label event occurs. The `EventData` includes:
- `id`: ID of the currently triggered node.
- `node`: Type of the currently triggered node.
- `attr`: Attributes of the currently triggered node.
- `index`: Index of the attribute if it's a list.
- `value`: Custom passed-in value. | diff --git a/components/Flow/app.py b/components/Flow/app.py deleted file mode 100644 index 77372ef291165f2cf77a8944f3f8b18773972190..0000000000000000000000000000000000000000 --- a/components/Flow/app.py +++ /dev/null @@ -1,6 +0,0 @@ -from components.Docs import Docs - -docs = Docs(__file__) - -if __name__ == "__main__": - docs.render().queue().launch() diff --git a/components/Flow/define_schema-zh_CN.md b/components/Flow/define_schema-zh_CN.md deleted file mode 100644 index dfd15303d31764b01c8170275d0d91b43f61dfe5..0000000000000000000000000000000000000000 --- a/components/Flow/define_schema-zh_CN.md +++ /dev/null @@ -1,266 +0,0 @@ -# Define Schema - -在使用 Flow 组件前,需要预先创建 Schema 定义 node 节点,schema 类型定义如下: - -```ts -export interface FlowSchema { - nodes: FlowNodeSchema[]; -} - -export interface FlowNodeSchema { - /** - * 作为节点的唯一标识。必填。 - */ - name: string; - - /** - * 节点显示图标。 - */ - icon?: string; - - /** - * 节点标题,如果没有提供则默认使用 name。 - */ - title?: string; - - /** - * 节点的简短描述。 - */ - description?: string; - - /** - * 节点宽度。 - */ - width?: number; - - /** - * 节点高度。 - */ - height?: number; - - /** - * 显示/隐藏工具栏(删除、复制、重命名等)。 - * @default true - */ - show_toolbar?: boolean; - - /** - * 启用/禁止添加更多此类节点实例。 - * @default true - */ - addable?: boolean; - - /** - * 启用/禁止删除现有此类节点实例。 - * @default true - */ - deletable?: boolean; - - /** - * 可以同时存在的此类节点的最大数量。 - */ - max?: number; - - /** - * 可以同时存在的此类节点的最小数量。 - */ - min?: number; - - /** - * 节点连接端口的配置。 - */ - ports?: { - /** - * 节点作为连接的源端口。 - * @default ['right'] - */ - source?: Position[]; - - /** - * 允许此节点 source 端口连接到的其他节点或属性。默认为所有节点和属性。 - * @default [] - */ - sourceConnections?: PortConnection[]; - - /** - * 节点作为连接的目标端口。 - * @default ['left'] - */ - target?: Position[]; - - /** - * 其他允许连接到此节点 target 端口的节点或属性。默认为所有节点和属性 - * @default [] - */ - targetConnections?: PortConnection[]; - }; - - /** - * 节点的属性配置。 - */ - attrs?: FlowNodeAttrSchema[]; - - /** - * 创建新实例时节点属性的初始值。 - */ - template?: { - /** - * 在`attrs`字段中与其名称相对应的属性值,例如 { "a": 1, "b": 2 }。 - */ - attrs?: Attrs; - }; -} - -export interface FlowNodeAttrSchema { - /** - * 唯一的属性名称,在 node data 中用作 key。必填。 - */ - name: string; - - /** - * 属性标题,如果没有提供则默认使用 name。 - */ - title?: string; - - /** - * 属性的简短描述 - */ - description?: string; - - /** - * 禁用用户编辑属性值。默认情况下,属性是可编辑的。 - * @default false - */ - disabled?: boolean; - - /** - * 属性输入类型。可以是内置的 Ant Design 组件或自定义组件之一。默认为'input'。 - * @default 'input' - */ - type?: - | 'input' - | 'textarea' - | 'radio' - | 'checkbox' - | 'number' - | 'select' - | 'switch' - | 'upload' - // 自定义 - | (string & {}); - - /** - * 针对所选组件类型的特定配置选项,支持 Ant Design 组件({@link https://ant.design/components/overview/})或自定义组件的属性。 - */ - props?: Record; - - /** - * 节点属性连接端口的配置。 - */ - ports?: { - /** - * 节点属性作为连接的源端口。 - * @default [] - */ - source?: Position[]; - - /** - * 允许此节点属性 source 端口连接到的其他节点或属性。 - * @default [] - */ - sourceConnections?: PortConnection[]; - - /** - * 节点属性作为连接的目标端口。 - * @default [] - */ - target?: Position[]; - - /** - * 其他允许连接到此节点属性 target 端口的节点或属性。 - * @default [] - */ - targetConnections?: PortConnection[]; - }; - - /** - * 表示该属性是否为列表值。 - * @default false - */ - list?: - | boolean - | { - /** - * 列表中每个 item 的端口配置。 - */ - ports?: { - /** - * 列表 item 作为连接的源端口。 - * @default [] - */ - source?: Position[]; - - /** - * 允许此列表 item source 端口连接到的其他节点或属性。 - * @default [] - */ - sourceConnections?: PortConnection[]; - - /** - * 列表 item 作为连接的目标端口。 - */ - target?: Position[]; - - /** - * 其他允许连接到此列表 item target 端口的节点或属性。 - */ - targetConnections?: PortConnection[]; - }; - - /** - * 列表中的最小 item 数量。 - */ - min?: number; - - /** - * 列表中的最大 item 数量。 - */ - max?: number; - }; - - /** - * 启用/禁用手风琴 UI。 - * @default true - */ - accordion?: boolean; - - /** - * 指定该属性值是否为必填项。默认情况为非必填项。 - * @default false - */ - required?: - | boolean - | { - message?: string; - }; - - /** - * 使用 JSON schema 验证属性值。 - */ - json_schema_validator?: Record; -} -``` - -你可以通过 json 文件(推荐)或直接在 Python 端通过导出类型定义: - -- 通过 json 定义: - -```json - -``` - -- 通过 Python 定义: - -```python - -``` diff --git a/components/Flow/define_schema.md b/components/Flow/define_schema.md deleted file mode 100644 index bb2c78c17655240097841083b9feec32981b13a5..0000000000000000000000000000000000000000 --- a/components/Flow/define_schema.md +++ /dev/null @@ -1,262 +0,0 @@ -# Define Schema - -Before using the Flow component, need to create a Schema definition node in advance. The schema type is defined as follows: - -```ts -export interface FlowSchema { - nodes: FlowNodeSchema[]; -} - -export interface FlowNodeSchema { - /** - * As a unique identifier for the node. Mandatory. - */ - name: string; - - /** - * Display icon for the node. - */ - icon?: string; - - /** - * Display title for the node, defaults to the node name if not provided. - */ - title?: string; - - /** - * A short description of the node's purpose. - */ - description?: string; - - /** - * Width of the node. - */ - width?: number; - - /** - * Height of the node. - */ - height?: number; - - /** - * Shows/hides the toolbar (delete, copy, rename, etc.). - * @default true - */ - show_toolbar?: boolean; - - /** - * Enables/disables adding more instances of this node. - * @default true - */ - addable?: boolean; - - /** - * Enables/disables deleting existing instances of this node. - * @default true - */ - deletable?: boolean; - - /** - * Maximum number of this node type that can exist simultaneously. - */ - max?: number; - - /** - * Minimum number of this node type that must exist simultaneously. - */ - min?: number; - - /** - * Configurations for the node's connection ports. - */ - ports?: { - /** - * Source ports for the node as a connection. - * @default ['right'] - */ - source?: Position[]; - - /** - * Allowed the source ports of this node to connect to other nodes or attributes. Defaults to all nodes and attributes - */ - sourceConnections?: PortConnection[]; - - /** - * Target ports for the node as a connection - * @default ['left'] - */ - target?: Position[]; - - /** - * Allowed other nodes or attributes allowed to connect to the target ports of this node. Defaults to all nodes and attributes - * - */ - targetConnections?: PortConnection[]; - }; - - /** - * Configuration of the node's attributes. - */ - attrs?: FlowNodeAttrSchema[]; - - /** - * Initial values for the node's attributes when creating a new instance. - */ - template?: { - /** - * Attribute values corresponding to their names in the `attrs` field, e.g., `{ "a": 1, "b": 2 }`. - */ - attrs?: Attrs; - }; -} - -export interface FlowNodeAttrSchema { - /** - * Unique attribute name used as a key in the node data. Mandatory. - */ - name: string; - - /** - * Display title for the attribute, defaults to the attribute name if not provided. - */ - title?: string; - - /** - * A brief explanation about the attribute purpose. - */ - description?: string; - - /** - * Disables user editing of the attribute value. By default, attributes are editable. - * @default false - */ - disabled?: boolean; - - /** - * Attribute input type. Can be one of the built-in Ant Design components or a custom component. Defaults to 'input'. - * @default 'input' - */ - type?: - | 'input' - | 'textarea' - | 'radio' - | 'checkbox' - | 'number' - | 'select' - | 'switch' - | 'upload' - // custom - | (string & {}); - - /** - * Configuration options specific to the chosen component type, supporting Ant Design ({@link https://ant.design/components/overview/}) or custom component properties. - */ - props?: Record; - - /** - * Configurations for the node attribute ports. - */ - ports?: { - /** - * Source ports for the attribute as a connection. - * @default [] - */ - source?: Position[]; - - /** - * Allowed the source ports of this attribute to connect to other nodes or attributes. Defaults to all nodes and attributes - */ - sourceConnections?: PortConnection[]; - - /** - * Target ports for the attribute as a connection - * @default [] - */ - target?: Position[]; - - /** - * Allowed other nodes or attributes allowed to connect to the target ports of this attribute. Defaults to all nodes and attributes - */ - targetConnections?: PortConnection[]; - }; - - /** - * Indicates whether the attribute is a list. - * @default false - */ - list?: - | boolean - | { - /** - * Port configurations for each item in the list. - */ - ports?: { - /** - * Source ports for the list item as a connection. - * @default [] - */ - source?: Position[]; - - /** - * Allowed the source ports of this list item to connect to other nodes or attributes. Defaults to all nodes and attributes - */ - sourceConnections?: PortConnection[]; - - /** - * Target ports for the list item as a connection - */ - target?: Position[]; - - /** - * Allowed other nodes or attributes allowed to connect to the target ports of this list item. Defaults to all nodes and attributes - */ - targetConnections?: PortConnection[]; - }; - - /** - * Minimum number of items in the list. - */ - min?: number; - - /** - * Maximum number of items in the list. - */ - max?: number; - }; - - /** - * Enable/disable accordion UI. - * @default true - */ - accordion?: boolean; - - /** - * Specifies if the attribute value is mandatory. By default, attributes are optional. - * @default false - */ - required?: - | boolean - | { - message?: string; - }; - - /** - * Validates attribute values using JSON schema. - */ - json_schema_validator?: Record; -} -``` - -You can define the schema by a json file (recommended) or directly on the Python by the exported types: - -- Defined by json: - -```json - -``` - -- Defined by Python: - -```python - -``` diff --git a/components/Flow/demos/basic.py b/components/Flow/demos/basic.py deleted file mode 100644 index 920e7fc58203b70a0f48905e2285395ec7135e24..0000000000000000000000000000000000000000 --- a/components/Flow/demos/basic.py +++ /dev/null @@ -1,35 +0,0 @@ -import json -import os - -import gradio as gr - -import modelscope_studio as mgr -from modelscope_studio.components.Flow import Edge, Node - -with open((os.path.join(os.path.dirname(__file__), - "../schema/agents_schema.json"))) as f: - schema = json.load(f) - -# define the initial value of the flow -data = { - "nodes": [ - Node(id="start-node", name="start", position=dict(x=0, y=0)), - Node(id="initial-agent-node", - name="agent", - position=dict(x=200, y=0), - data=dict(condition=[''])) - ], - "edges": [Edge(source='start-node', target="initial-agent-node")], -} - - -def on_data_change(_flow): - print(_flow) - - -with gr.Blocks() as demo: - flow = mgr.Flow(value=data, schema=schema, sync_on_data_change=True) - flow.data_change(fn=on_data_change, inputs=[flow]) - -if __name__ == "__main__": - demo.queue().launch() diff --git a/components/Flow/demos/component_options.py b/components/Flow/demos/component_options.py deleted file mode 100644 index b080470f54d63694d7a0811c1f48091457920b31..0000000000000000000000000000000000000000 --- a/components/Flow/demos/component_options.py +++ /dev/null @@ -1,108 +0,0 @@ -import json -import os - -import gradio as gr - -import modelscope_studio as mgr -from modelscope_studio.components.Flow import BackgroundPropsDict, Edge, Node - -with open((os.path.join(os.path.dirname(__file__), - "../schema/agents_schema.json"))) as f: - schema = json.load(f) - -# define the initial value of the flow -data = { - "nodes": [ - Node(id="start-node", name="start", position=dict(x=0, y=0)), - Node(id="initial-agent-node", - name="agent", - position=dict(x=200, y=0), - data=dict(condition=[''])) - ], - "edges": [Edge(source='start-node', target="initial-agent-node")], -} - - -def on_data_change(_flow): - print(_flow) - - -flow_props = ["show_sidebar", "show_minimap", "show_controls"] - - -def on_change(_flow_config, _bgc_variant, _bgc_color, _bgc_bg_color, _bgc_gap, - _bgc_size, _bgc_offset, _bgc_line_width): - new_props = {} - new_background_props = { - "variant": _bgc_variant, - "bgColor": _bgc_bg_color, - "color": _bgc_color, - "gap": _bgc_gap, - "size": _bgc_size, - "offset": _bgc_offset, - 'lineWidth': _bgc_line_width - } - for choice in flow_props: - if choice in _flow_config: - new_props[choice] = True - else: - new_props[choice] = False - return gr.update(**new_props, background_props=new_background_props) - - -with gr.Blocks() as demo: - with gr.Accordion(label="Flow Options"): - flow_config = gr.CheckboxGroup( - container=False, - value=["show_sidebar", "show_minimap", "show_controls"], - choices=flow_props) - with gr.Accordion(label="Background Props"): - with gr.Row(): - with gr.Column(): - bgc_variant = gr.Radio(choices=["dots", "lines", "cross"], - label="variant", - value="dots") - with gr.Column(): - bgc_color = gr.ColorPicker(label="color", value="") - with gr.Column(): - bgc_bg_color = gr.ColorPicker(label="bgColor", value="") - with gr.Column(): - bgc_gap = gr.Slider(label="gap", value=28) - with gr.Column(): - bgc_size = gr.Slider(label="size", - value=1, - maximum=10, - step=1) - with gr.Column(): - bgc_offset = gr.Slider(label="offset", - value=1, - step=1, - maximum=10) - with gr.Column(): - bgc_line_width = gr.Slider(label="lineWidth", - value=1, - step=1, - maximum=10) - - flow = mgr.Flow(value=data, - schema=schema, - show_controls=True, - show_minimap=True, - show_sidebar=True, - sync_on_data_change=True, - background_props=BackgroundPropsDict(variant='dots')) - gr.on(triggers=[ - flow_config.change, bgc_variant.change, bgc_color.change, - bgc_bg_color.change, bgc_gap.change, bgc_size.change, - bgc_offset.change, bgc_line_width.change - ], - fn=on_change, - inputs=[ - flow_config, bgc_variant, bgc_color, bgc_bg_color, bgc_gap, - bgc_size, bgc_offset, bgc_line_width - ], - outputs=[flow]) - flow.data_change(fn=on_data_change, inputs=[flow]) - -if __name__ == "__main__": - demo.queue().launch() diff --git a/components/Flow/demos/custom_node_type.py b/components/Flow/demos/custom_node_type.py deleted file mode 100644 index e40d3e40864c0ad3f02af8f7826807c468dbb83f..0000000000000000000000000000000000000000 --- a/components/Flow/demos/custom_node_type.py +++ /dev/null @@ -1,69 +0,0 @@ -import gradio as gr - -import modelscope_studio as mgr -from modelscope_studio.components.Flow import (FlowSchemaDict, Node, - NodeSchemaAttributeDict, - NodeSchemaDict) - - -def on_data_change(_flow): - print(_flow) - - -def on_custom(data: gr.EventData): - print(data._data) - - -custom_components = { - "my-input": { - "js": - """ -(props, cc, { el, theme, onMount, onUpdate }) => { - onMount(() => { - el.innerHTML = `` - const input = el.querySelector('input') - input.style.color = theme === 'dark' ? 'white' : 'black' - input.style.backgroundColor = theme === 'dark' ? 'black' : 'white' - input.addEventListener('change', (e) => { - cc.dispatch(e.target.value) - }) - }) - // props update - onUpdate( - () => { - const input = el.querySelector('input') - input.setAttribute('value', props.value || '') - }, - // By default, the callback will not be called when the component is being mounted. Set `callAfterMount` to true to enable it. - { callAfterMount: true } - ) -} -""" - } -} - -schema = FlowSchemaDict(nodes=[ - NodeSchemaDict(name="my-input-node", - title="MyInputNode", - attrs=[NodeSchemaAttributeDict(name="a", type="my-input")]) -]) - -data = { - "nodes": [ - Node(name="my-input-node", - position=dict(x=0, y=0), - data=dict(a='Hello')) - ] -} - -with gr.Blocks() as demo: - flow = mgr.Flow(value=data, - schema=schema, - custom_components=custom_components, - sync_on_data_change=True) - flow.data_change(fn=on_data_change, inputs=[flow]) - # called when custom component dispatch event - flow.custom(fn=on_custom) - -if __name__ == "__main__": - demo.queue().launch() diff --git a/components/Flow/schema/agents_schema.json b/components/Flow/schema/agents_schema.json deleted file mode 100644 index 3134b2dc35895f14c0f1ff11061db9a13836f0f7..0000000000000000000000000000000000000000 --- a/components/Flow/schema/agents_schema.json +++ /dev/null @@ -1,66 +0,0 @@ -{ - "$schema": "https://raw.githubusercontent.com/modelscope/modelscope-studio/main/frontend/Flow/schema.json", - "nodes": [ - { - "max": 1, - "min": 1, - "addable": false, - "show_toolbar": false, - "name": "start", - "title": "Start", - "ports": { - "source": ["right"], - "target": [] - } - }, - { - "icon": "https://img.alicdn.com/imgextra/i4/O1CN01fvt4it25rEZU4Gjso_!!6000000007579-2-tps-128-128.png", - "name": "agent", - "title": "Agent Node", - "description": "Agent Flow Node", - "ports": { - "target": ["left"], - "source": [] - }, - "attrs": [ - { - "name": "prompt", - "title": "Agent Prompt", - "type": "textarea", - "required": { - "message": "Agent Prompt is required" - } - }, - { - "name": "tool", - "title": "Tools", - "type": "select", - "props": { - "mode": "multiple", - "options": [ - { "label": "Wanx Image Generation", "value": "image_gen" }, - { "label": "Code Interpreter", "value": "code_interpreter" }, - { "label": "Web Browsing", "value": "web_browser" } - ] - } - }, - { - "name": "condition", - "title": "Jump Condition", - "list": { - "min": 1, - "ports": { - "source": ["right"] - } - }, - "accordion": false - } - ], - "template": { - "attrs": { - "condition": [""] - } - } - } - ] -} diff --git a/components/Flow/schema/agents_schema.py b/components/Flow/schema/agents_schema.py deleted file mode 100644 index 9cc1f6c8150b8c4c71ca84d76b0aefd49a196028..0000000000000000000000000000000000000000 --- a/components/Flow/schema/agents_schema.py +++ /dev/null @@ -1,59 +0,0 @@ -import os - -from modelscope_studio.components.Flow import ( - FlowSchemaDict, NodeSchemaAttributeDict, NodeSchemaAttributeListDict, - NodeSchemaAttributeRequiredDict, NodeSchemaDict, NodeSchemaPortsDict, - NodeSchemaTemplateDict) - - -def resolve_assets(relative_path): - return os.path.join(os.path.dirname(__file__), "../../resources", - relative_path) - - -schema = FlowSchemaDict(nodes=[ - NodeSchemaDict(max=1, - min=1, - addable=False, - show_toolbar=False, - name="start", - title="Start", - ports=NodeSchemaPortsDict(source=['right'], target=[])), - NodeSchemaDict( - icon=resolve_assets('./bot.jpeg'), - name="agent", - title="Agent Node", - description="Agent Flow Node", - ports=NodeSchemaPortsDict(source=[], target=['left']), - attrs=[ - NodeSchemaAttributeDict(name="prompt", - title="Agent Prompt", - type='textarea', - required=NodeSchemaAttributeRequiredDict( - message="Agent Prompt is required")), - NodeSchemaAttributeDict(name="tool", - title="Tools", - type="select", - props={ - "mode": - "multiple", - "options": [{ - "label": "Wanx Image Generation", - "value": "image_gen" - }, { - "label": "Code Interpreter", - "value": "code_interpreter" - }, { - "label": "Web Browsing", - "value": "web_browser" - }] - }), - NodeSchemaAttributeDict( - name="condition", - title="Jump Condition", - list=NodeSchemaAttributeListDict( - min=1, ports=NodeSchemaPortsDict(source=['right'])), - accordion=False) - ], - template=NodeSchemaTemplateDict(attrs=dict(condition=['']))) -]) diff --git a/components/Lifecycle/README-zh_CN.md b/components/Lifecycle/README-zh_CN.md deleted file mode 100644 index 2a110cbdbbcd3934c63fd412764634c46b1925bd..0000000000000000000000000000000000000000 --- a/components/Lifecycle/README-zh_CN.md +++ /dev/null @@ -1,53 +0,0 @@ -# Lifecycle - -生命周期组件,用于获取当前用户的环境信息。 - -- 获取当前用户的语言、页面主题、user agent 和屏幕状态。 -- 监听页面行为并触发相应事件(页面加载、尺寸变化、页面关闭等)。 - -## 如何使用 - -### 基本使用 - - - -### 自动适配用户语言环境 - - - -### 根据用户界面主题返回不同权重内容 - - - -## API 及参数列表 - -### value - -接口定义: - -```python -class LifecycleScreenData(GradioModel): - width: float - height: float - scrollX: float - scrollY: float - - -class LifecycleData(GradioModel): - screen: LifecycleScreenData - language: str - theme: str - userAgent: str -``` - -### props - -该组件不支持传入 props。 - -### event listeners - -| 事件 | 描述 | -| -------------------------------- | --------------------------------------------------------------------- | -| `mgr.Lifecycle.mount(fn, ···)` | 用户页面加载时触发,EventData 为当前组件 value 的 dict 类型值。 | -| `mgr.Lifecycle.unmount(fn, ···)` | 用户页面关闭时触发,EventData 为当前组件 value 的 dict 类型值。 | -| `mgr.Lifecycle.resize(fn, ···)` | 自定义标签触发事件时触发,EventData 为当前组件 value 的 dict 类型值。 | diff --git a/components/Lifecycle/README.md b/components/Lifecycle/README.md deleted file mode 100644 index 66c646f9d311a6702078e4cb45cb147308e22a80..0000000000000000000000000000000000000000 --- a/components/Lifecycle/README.md +++ /dev/null @@ -1,53 +0,0 @@ -# Lifecycle - -A Lifecycle component for getting the current user's environment information. - -- Get the current user's language, page theme, user agent, and screen state. -- Listen to page actions and trigger corresponding events (page loading, size changes, page closing, etc.). - -## How to Use - -### Basic Usage - - - -### Automatically Adapt to User Language Environment - - - -### Return Different Weighted Content Based on UI Theme - - - -## API and Parameter List - -### Value - -Interface definition: - -```python -class LifecycleScreenData(GradioModel): - width: float - height: float - scrollX: float - scrollY: float - - -class LifecycleData(GradioModel): - screen: LifecycleScreenData - language: str - theme: str - userAgent: str -``` - -### Props - -This component does not support passing in props. - -### Event Listeners - -| Event | Description | -| -------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | -| `mgr.Lifecycle.mount(fn, ···)` | Triggered when the user's page loads. The EventData is a dictionary type value of the current component's value. | -| `mgr.Lifecycle.unmount(fn, ···)` | Triggered when the user's page closes. The EventData is a dictionary type value of the current component's value. | -| `mgr.Lifecycle.resize(fn, ···)` | Triggered when custom labels trigger events. The EventData is a dictionary type value of the current component's value. | diff --git a/components/Lifecycle/app.py b/components/Lifecycle/app.py deleted file mode 100644 index 77372ef291165f2cf77a8944f3f8b18773972190..0000000000000000000000000000000000000000 --- a/components/Lifecycle/app.py +++ /dev/null @@ -1,6 +0,0 @@ -from components.Docs import Docs - -docs = Docs(__file__) - -if __name__ == "__main__": - docs.render().queue().launch() diff --git a/components/Lifecycle/demos/basic.py b/components/Lifecycle/demos/basic.py deleted file mode 100644 index a7c361684bae1d011653b027c573f4aef436f9c0..0000000000000000000000000000000000000000 --- a/components/Lifecycle/demos/basic.py +++ /dev/null @@ -1,28 +0,0 @@ -import gradio as gr - -import modelscope_studio as mgr - - -def mount(e: gr.EventData): - # current page state - print("onMount", e._data) - - -def resize(e: gr.EventData): - print("onResize", e._data) - - -def onUnmount(e: gr.EventData): - print("onUnmount", e._data) - - -with gr.Blocks() as demo: - gr.Markdown("The Lifecycle component will not be rendered on the page.") - lifecycle = mgr.Lifecycle() - # listen to the page lifecycle - lifecycle.mount(fn=mount) - lifecycle.resize(fn=resize) - lifecycle.unmount(fn=onUnmount) - -if __name__ == "__main__": - demo.queue().launch() diff --git a/components/Lifecycle/demos/language_adaptation.py b/components/Lifecycle/demos/language_adaptation.py deleted file mode 100644 index 9b5043005466c75f1e4032c3999b521669e5403d..0000000000000000000000000000000000000000 --- a/components/Lifecycle/demos/language_adaptation.py +++ /dev/null @@ -1,41 +0,0 @@ -import time - -import gradio as gr - -import modelscope_studio as mgr - -messages = { - 'en': { - "hello": "Hello" - }, - 'en-US': { - "hello": "Hello" - }, - 'zh-CN': { - "hello": "你好" - } -} - -default_lang = "en" - - -def mount(_lifecycle, _state): - lang = _lifecycle.language - if (lang in messages): - _state["current_lang"] = lang - yield 'Switch Language...', _state - time.sleep(2) - yield messages[lang]["hello"], _state - - -with gr.Blocks() as demo: - lifecycle = mgr.Lifecycle() - state = gr.State({"current_lang": default_lang}) - markdown = gr.Markdown(value=messages[default_lang]["hello"]) - - lifecycle.mount(fn=mount, - inputs=[lifecycle, state], - outputs=[markdown, state]) - -if __name__ == "__main__": - demo.queue().launch() diff --git a/components/Lifecycle/demos/theme_adaptation.py b/components/Lifecycle/demos/theme_adaptation.py deleted file mode 100644 index dc6a128738b73294bdc701cc44268fd12a741e7f..0000000000000000000000000000000000000000 --- a/components/Lifecycle/demos/theme_adaptation.py +++ /dev/null @@ -1,28 +0,0 @@ -import gradio as gr - -import modelscope_studio as mgr - - -def mount(_lifecycle, _state): - _state["theme"] = _lifecycle.theme - yield _state - - -def fn(_state): - theme = _state["theme"] - color = '000/fff' if theme == 'dark' else 'fff/000' - yield gr.update( - value=f"https://dummyimage.com/200x100/{color}.png&text={theme}") - - -with gr.Blocks() as demo: - lifecycle = mgr.Lifecycle() - state = gr.State({"theme": "light"}) - btn = gr.Button() - image = gr.Image() - - lifecycle.mount(fn=mount, inputs=[lifecycle, state], outputs=[state]) - btn.click(fn=fn, inputs=[state], outputs=[image]) - -if __name__ == "__main__": - demo.queue().launch() diff --git a/components/Markdown/README-zh_CN.md b/components/Markdown/README-zh_CN.md index 00b406acdd547c21cad85e58e07f416a34ca9e06..e95ff7fa6b18e2a0c1005ef4f32a93642ada89c4 100644 --- a/components/Markdown/README-zh_CN.md +++ b/components/Markdown/README-zh_CN.md @@ -2,9 +2,8 @@ 升级版的 gradio Markdown。 -- 支持输出多模态内容(音频、视频、图片、文本) -- 内置标签(chart、select-box、accordion) -- 支持自定义渲染组件,并与 Python 事件交互 +- 支持输出多模态内容(音频、视频、语音、文件、文本) +- 支持自定义渲染组件,并与 Python 侧事件交互 ## 如何使用 @@ -28,12 +27,6 @@ -### 支持图表展示 - -在返回的内容中加入 `chart` 标签,更多用法详见 chart - - - ### 自定义标签(高阶用法,需要了解前端知识) @@ -49,13 +42,13 @@ template只能做简单的变量替换,如果想要引入更多自定义的行 custom_select.js ```js - + ``` -#### 与 Python 交互 +#### 与 Python 侧交互 在 js 中可以使用`cc.dispatch`触发 Python 侧监听的`custom`事件,以前面的custom_select.js为例,我们在前端调用了`cc.dispatch(options[i])`,则会向 Python 侧同时发送通知。 @@ -67,15 +60,13 @@ custom_select.js ### props -| 属性 | 类型 | 默认值 | 描述 | -| ----------------------------- | --------------------------------------------------------------- | ------ | --------------------------------------------------------------------------- | -| enable_base64 | bool | False | 是否支持渲染的内容为 base64,因为直接渲染 base64 有安全问题,默认为 False。 | -| enable_latex | bool | True | 是否支持 Latex 公式渲染 | -| latex_single_dollar_delimiter | bool | True | 是否支持单`$`符号在 Latex 公式中渲染 | -| preview | bool | True | 是否开启图片预览功能 | -| custom_components | dict\[str, CustomComponentDict\] CustomComponentDict 定义见下方 | None | 支持用户定义自定义标签,并通过 js 控制标签渲染样式与触发 python 事件。 | +| 属性 | 类型 | 默认值 | 描述 | +| ----------------- | --------------------------------------------------------------- | ------ | --------------------------------------------------------------------------- | +| enable_base64 | bool | False | 是否支持渲染的内容为 base64,因为直接渲染 base64 有安全问题,默认为 False。 | +| preview | bool | True | 是否开启图片预览功能 | +| custom_components | dict\[str, CustomComponentDict\] CustomComponentDict 定义见下方 | None | 支持用户定义自定义标签,并通过 js 控制标签渲染样式与触发 python 事件。 | -**CustomComponentDict 定义如下** +**CustomComponent 定义如下** ```python class CustomComponentDict(TypedDict): @@ -88,10 +79,9 @@ class CustomComponentDict(TypedDict): - select-box - accordion -- chart ### event listeners -| 事件 | 描述 | -| ------------------------------ | ---------------------------------------------------------------------------------------------------------------- | -| `mgr.Markdown.custom(fn, ···)` | 自定义标签触发事件时触发,EventData 为:
- tag_index:当前触发标签的 index。
- value:自定义传入的值。 | +| 事件 | 描述 | +| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `mgr.Markdown.custom(fn, ···)` | 自定义标签触发事件时触发,EventData 为:
- index:当前 message 的 index tuple ([message index, user group(index 0) or bot group(index 1), user/bot group index])。
- tag:当前触发的标签。
- tag_index:当前触发标签的 index,此 index 在 mesage 的 index tuple 基础上重新计算。
- value:自定义传入的值。 | diff --git a/components/Markdown/README.md b/components/Markdown/README.md index 9a705158481c04a05043a751f081e737a64f9bea..14f01cc05a494b9a1f0dcd52cc5ba9cf4bfb6e05 100644 --- a/components/Markdown/README.md +++ b/components/Markdown/README.md @@ -2,9 +2,8 @@ Upgraded gradio Markdown. -- Supports output of multimodal content (audio, video, image, text) -- Built-in tags (chart, select-box, accordion) -- Supports custom rendering components and interaction with Python events +- Supports output of multimodal content (audio, video, voice, files, text) +- Supports custom rendering components and interaction with Python-side events ## How to Use @@ -18,24 +17,19 @@ Upgraded gradio Markdown. ### Support for Accordion Content Display -Include the `accordion` tag in the returned content. For more usage details, see accordion +Include the `accordion` tag in the returned content for more usage details, see accordion ### Support for User Selection Interaction -Include the `select-box` tag in the returned content. For more usage details, see select-box +Include the `select-box` tag in the returned content for more usage details, see select-box -### Support for Chart Display - -Include the `chart` tag in the returned content. For more usage details, see chart - - ### Custom Tags (Advanced Usage, Requires Frontend Knowledge) -#### Import JS +#### Importing js The template can only perform simple variable replacements. If you want to introduce more custom behaviors, such as conditional judgments, loop rendering, etc., please use js to control the element for processing. Here is a simple example: @@ -44,13 +38,13 @@ The template can only perform simple variable replacements. If you want to intro custom_select.js ```js - + ``` -#### Interaction with Python +#### Interaction with Python Side In js, you can use `cc.dispatch` to trigger the `custom` event listened to on the Python side. Taking the previous custom_select.js as an example, when we call `cc.dispatch(options[i])` on the frontend, a notification will be sent to the Python side simultaneously. @@ -61,14 +55,12 @@ The following APIs are additional extended parameters beyond the original gradio ### props -| Attribute | Type | Default Value | Description | -| ----------------------------- | ------------------------------------------------------------------- | ------------- | ---------------------------------------------------------------------------------------------------------- | -| enable_base64 | bool | False | Whether to support rendering content as base64, since rendering base64 is unsafe, the default is False. | -| preview | bool | True | Whether to enable image preview functionality. | -| enable_latex | bool | True | Whether to enable LaTeX rendering. | -| latex_single_dollar_delimiter | bool | True | Whe ther to enable single dollar delimiter `$` for LaTeX rendering. | -| custom_components | Dict[str, CustomComponentDict] CustomComponentDict definition below | None | Supports user-defined custom tags and controls tag rendering styles and triggers Python events through js. | -| | +| Attribute | Type | Default Value | Description | +| ----------------- | ------------------------------------------------------------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------- | +| enable_base64 | bool | False | Whether to support rendering content as base64, since rendering base64 directly can pose security issues, the default is False. | +| preview | bool | True | Whether to enable image preview functionality. | +| custom_components | dict[str, CustomComponentDict] CustomComponentDict definition below | None | Supports user-defined custom tags and controls tag rendering styles and triggers Python events through js. | +| | **CustomComponent definition is as follows:** @@ -83,10 +75,9 @@ class CustomComponentDict(TypedDict): - select-box - accordion -- chart ### Event Listeners -| Event | Description | -| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `mgr.Markdown.custom(fn, ···)` | Triggered when a custom tag event occurs. EventData is:
- tag: The current tag that triggered the event.
- tag_index: The index of the current triggered tag.
- value: The custom value passed in. | +| Event | Description | +| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `mgr.Markdown.custom(fn, ···)` | Triggered when a custom tag event occurs. EventData is:
- index: The index tuple of the current message ([message index, user group(index 0) or bot group(index 1), user/bot group index]).
- tag: The current tag that triggered the event.
- tag_index: The index of the current triggered tag, re-calculated based on the message’s index tuple.
- value: The custom value passed in. | diff --git a/components/Markdown/custom_tags/chart-zh_CN.md b/components/Markdown/custom_tags/chart-zh_CN.md deleted file mode 100644 index caca68a9e3ef4b4d7a83320cfef55fb48968ed9c..0000000000000000000000000000000000000000 --- a/components/Markdown/custom_tags/chart-zh_CN.md +++ /dev/null @@ -1,17 +0,0 @@ -# chart - -在 markdown 文本中添加图表。 - -## 如何使用 - -### 基本使用 - - - -## API 及参数列表 - -### props - -| 属性 | 类型 | 默认值 | 描述 | -| ------- | ------ | ------ | ----------------------------------------------------------------------------------------- | -| options | object | | `echarts`的 options 配置,详见:[echarts docs](https://echarts.apache.org/en/option.html) | diff --git a/components/Markdown/custom_tags/chart.md b/components/Markdown/custom_tags/chart.md deleted file mode 100644 index c5fa26a2d9dadf4be5c48cdeafb828cb6daa3f02..0000000000000000000000000000000000000000 --- a/components/Markdown/custom_tags/chart.md +++ /dev/null @@ -1,17 +0,0 @@ -# chart - -Add a chart to markdown text. - -## How to Use - -### Basic Usage - - - -## API and Parameter List - -### props - -| Attribute | Type | Default Value | Description | -| --------- | ------ | ------------- | --------------------------------------------------------------------------------- | -| options | object | | `echarts` options, see: [echarts docs](https://echarts.apache.org/en/option.html) | diff --git a/components/Markdown/demos/accordion.py b/components/Markdown/demos/accordion.py index 924b354830adb16e90c86d49003057c0fa3aa10a..c91634b0d7e87d905f84bec5323adbf28600e3b9 100644 --- a/components/Markdown/demos/accordion.py +++ b/components/Markdown/demos/accordion.py @@ -1,13 +1,12 @@ import gradio as gr - import modelscope_studio as mgr with gr.Blocks() as demo: - mgr.Markdown(""" + mgr.Markdown(f""" ```json -{"text": "glorious weather", "resolution": "1024*1024"} +{{"text": "glorious weather", "resolution": "1024*1024"}} ``` @@ -19,7 +18,7 @@ Use `::accordion-title` to support markdown: ::accordion-title[Using `tool`] ```json -{"text": "glorious weather", "resolution": "1024*1024"} +{{"text": "glorious weather", "resolution": "1024*1024"}} ``` """) diff --git a/components/Markdown/demos/basic.py b/components/Markdown/demos/basic.py index 2c423e26c64c6e003fdb4efce0284cc41d5140a2..2b9ab5b2dfc92d2dd6958fd715cc1e5c0008cbdd 100644 --- a/components/Markdown/demos/basic.py +++ b/components/Markdown/demos/basic.py @@ -1,5 +1,4 @@ import gradio as gr - import modelscope_studio as mgr with gr.Blocks() as demo: diff --git a/components/Markdown/demos/chart.py b/components/Markdown/demos/chart.py deleted file mode 100644 index e611b1598dfb936ee2c6bd6e6748e7008d5260f4..0000000000000000000000000000000000000000 --- a/components/Markdown/demos/chart.py +++ /dev/null @@ -1,31 +0,0 @@ -import json - -import gradio as gr - -import modelscope_studio as mgr - -# echarts options, see: https://echarts.apache.org/en/index.html -option1 = { - "xAxis": { - "type": 'category', - "data": ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], - }, - "yAxis": { - "type": 'value', - }, - "series": [ - { - "data": [150, 230, 224, 218, 135, 147, 260], - "type": 'line', - }, - ], -} - -with gr.Blocks() as demo: - mgr.Markdown(f""" -Chart: - -""") - -if __name__ == "__main__": - demo.queue().launch() diff --git a/components/Markdown/demos/custom-tag.py b/components/Markdown/demos/custom-tag.py index 530e7027d182e9b76026e815c60723c073ef6b7c..162dfa19643937b07f50027bbcd8b5849164f80b 100644 --- a/components/Markdown/demos/custom-tag.py +++ b/components/Markdown/demos/custom-tag.py @@ -1,10 +1,9 @@ import gradio as gr - import modelscope_studio as mgr with gr.Blocks() as demo: mgr.Markdown( - """ + f""" custom tag: """, custom_components={ diff --git a/components/Markdown/demos/custom-tag2.py b/components/Markdown/demos/custom-tag2.py index ecbcb4876f097f5713e5c0ed1643003f611959fc..890cf51bb303d4689e5e686e41acb4ed1c0c98de 100644 --- a/components/Markdown/demos/custom-tag2.py +++ b/components/Markdown/demos/custom-tag2.py @@ -1,10 +1,9 @@ import gradio as gr - import modelscope_studio as mgr with gr.Blocks() as demo: mgr.Markdown( - """ + f""" custom tag: """, custom_components={ @@ -15,29 +14,12 @@ custom tag: # The `js` property should be a string containing a JavaScript Function. "js": """ -(props, cc, { el, onMount, onUpdate }) => { - // `onMount` will be called after the template first rendered +(props, cc, { el, onMount }) => { + // `onMount` will be called after the template rendered onMount(() => { // `el` is the container element console.log(el) - - // the return function will be called when the component is being unmounted - return () => { - console.log('unmount') - } - }) - - // `onUpdate` will be called when the props changed - onUpdate(() => { - console.log(props) }) - onUpdate( - () => { - console.log(props, 'after mount') - }, - // By default, the callback will not be called when the component is being mounted. Set `callAfterMount` to true to enable it. - { callAfterMount: true } - ) console.log(props.children) // By default, `props` will be passed a property named `children`, which can get the content in the tag, such as 'xx' in 'xx'. // The return value will be merged with `props` and passed to the template. diff --git a/components/Markdown/demos/custom-tag3.py b/components/Markdown/demos/custom-tag3.py index c87a9e19360aed72656d26ce8293c9c9f8edfed8..6d6f1f94990dbc47eb1542901f7035ec827cbfb9 100644 --- a/components/Markdown/demos/custom-tag3.py +++ b/components/Markdown/demos/custom-tag3.py @@ -2,14 +2,13 @@ import json import os import gradio as gr - import modelscope_studio as mgr options = ["a", "b", "c"] def resolve_assets(relative_path): - return os.path.join(os.path.dirname(__file__), "../../resources", + return os.path.join(os.path.dirname(__file__), "../resources", relative_path) diff --git a/components/Markdown/demos/custom-tag4.py b/components/Markdown/demos/custom-tag4.py index 4f8e8a8159e85c1a711c0b3a37b29ec60763f3db..8fd5c5b9e991a315239d9b2f75bfbc698b3585d0 100644 --- a/components/Markdown/demos/custom-tag4.py +++ b/components/Markdown/demos/custom-tag4.py @@ -2,14 +2,13 @@ import json import os import gradio as gr - import modelscope_studio as mgr options = ["a", "b", "c"] def resolve_assets(relative_path): - return os.path.join(os.path.dirname(__file__), "../../resources", + return os.path.join(os.path.dirname(__file__), "../resources", relative_path) diff --git a/components/Markdown/demos/custom_tags/accordion/__pycache__/accordion-title.cpython-39.pyc b/components/Markdown/demos/custom_tags/accordion/__pycache__/accordion-title.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bd14c555f641b6ae8309a21e2e57310b21cc0733 Binary files /dev/null and b/components/Markdown/demos/custom_tags/accordion/__pycache__/accordion-title.cpython-39.pyc differ diff --git a/components/Markdown/demos/custom_tags/accordion/__pycache__/basic.cpython-39.pyc b/components/Markdown/demos/custom_tags/accordion/__pycache__/basic.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2ee445e3e71ea028b1e9ab00f6744f8966fbeae2 Binary files /dev/null and b/components/Markdown/demos/custom_tags/accordion/__pycache__/basic.cpython-39.pyc differ diff --git a/components/Markdown/demos/custom_tags/accordion/accordion-title.py b/components/Markdown/demos/custom_tags/accordion/accordion-title.py index 1b692f010c04d903c794f985541e23b884153345..7901cc99b5fd77e53336ab72664240de4dc134c7 100644 --- a/components/Markdown/demos/custom_tags/accordion/accordion-title.py +++ b/components/Markdown/demos/custom_tags/accordion/accordion-title.py @@ -1,15 +1,14 @@ import gradio as gr - import modelscope_studio as mgr with gr.Blocks() as demo: - mgr.Markdown(""" + mgr.Markdown(f""" ::accordion-title[Using `tool`] ```json -{"text": "glorious weather", "resolution": "1024*1024"} +{{"text": "glorious weather", "resolution": "1024*1024"}} ``` diff --git a/components/Markdown/demos/custom_tags/accordion/basic.py b/components/Markdown/demos/custom_tags/accordion/basic.py index 724b9f5ca0db2c40b91064129956ad2500dbae9c..239dfdb2f7e1a871808024ec4ec1d5940ca19216 100644 --- a/components/Markdown/demos/custom_tags/accordion/basic.py +++ b/components/Markdown/demos/custom_tags/accordion/basic.py @@ -1,13 +1,12 @@ import gradio as gr - import modelscope_studio as mgr with gr.Blocks() as demo: - mgr.Markdown(""" + mgr.Markdown(f""" ```json -{"text": "glorious weather", "resolution": "1024*1024"} +{{"text": "glorious weather", "resolution": "1024*1024"}} ``` diff --git a/components/Markdown/demos/custom_tags/chart/basic.py b/components/Markdown/demos/custom_tags/chart/basic.py deleted file mode 100644 index 53d5f7760ed2abce0bc491d5f71e6aa0a0c90c67..0000000000000000000000000000000000000000 --- a/components/Markdown/demos/custom_tags/chart/basic.py +++ /dev/null @@ -1,84 +0,0 @@ -import json - -import gradio as gr - -import modelscope_studio as mgr - -# echarts options, see: https://echarts.apache.org/en/index.html -option1 = { - "xAxis": { - "type": 'category', - "data": ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], - }, - "yAxis": { - "type": 'value', - }, - "series": [ - { - "data": [150, 230, 224, 218, 135, 147, 260], - "type": 'line', - }, - ], -} - -option2 = { - "tooltip": { - "trigger": 'item' - }, - "legend": { - "top": '5%', - "left": 'center' - }, - "series": [{ - "name": - 'Access From', - "type": - 'pie', - "radius": ['40%', '70%'], - "avoidLabelOverlap": - False, - "itemStyle": { - "borderRadius": 10, - "borderColor": '#fff', - "borderWidth": 2 - }, - "label": { - "show": False, - "position": 'center' - }, - "emphasis": { - "label": { - "show": True, - "fontSize": 40, - "fontWeight": 'bold' - } - }, - "labelLine": { - "show": False - }, - "data": [{ - "value": 1048, - "name": 'Search Engine' - }, { - "value": 735, - "name": 'Direct' - }, { - "value": 580, - "name": 'Email' - }, { - "value": 484, - "name": 'Union Ads' - }, { - "value": 300, - "name": 'Video Ads' - }] - }] -} - -with gr.Blocks() as demo: - chatbot = mgr.Markdown(f""" - - -""") -if __name__ == "__main__": - demo.queue().launch() diff --git a/components/Markdown/demos/custom_tags/select-box/__pycache__/basic.cpython-39.pyc b/components/Markdown/demos/custom_tags/select-box/__pycache__/basic.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8b37417e58d758fe5b0ee364cfa63e43df70d042 Binary files /dev/null and b/components/Markdown/demos/custom_tags/select-box/__pycache__/basic.cpython-39.pyc differ diff --git a/components/Markdown/demos/custom_tags/select-box/__pycache__/card_shape.cpython-39.pyc b/components/Markdown/demos/custom_tags/select-box/__pycache__/card_shape.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b50b449d8f582658710ec6d5a11835216878d724 Binary files /dev/null and b/components/Markdown/demos/custom_tags/select-box/__pycache__/card_shape.cpython-39.pyc differ diff --git a/components/Markdown/demos/custom_tags/select-box/__pycache__/card_shape_width_auto.cpython-39.pyc b/components/Markdown/demos/custom_tags/select-box/__pycache__/card_shape_width_auto.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..74f2749a5a32228d2414e17bee95546778928b0f Binary files /dev/null and b/components/Markdown/demos/custom_tags/select-box/__pycache__/card_shape_width_auto.cpython-39.pyc differ diff --git a/components/Markdown/demos/custom_tags/select-box/__pycache__/python_events.cpython-39.pyc b/components/Markdown/demos/custom_tags/select-box/__pycache__/python_events.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5b6e89295cf10f37c12596d58000e2c6215fe29f Binary files /dev/null and b/components/Markdown/demos/custom_tags/select-box/__pycache__/python_events.cpython-39.pyc differ diff --git a/components/Markdown/demos/custom_tags/select-box/basic.py b/components/Markdown/demos/custom_tags/select-box/basic.py index eb03c2fe925703f09c6f97b9cd20d12323b96ec4..52fea57ab46afeae1298946cd380395a8707c81f 100644 --- a/components/Markdown/demos/custom_tags/select-box/basic.py +++ b/components/Markdown/demos/custom_tags/select-box/basic.py @@ -1,7 +1,6 @@ import json import gradio as gr - import modelscope_studio as mgr options = [{"label": "A", "value": "a"}, "b", "c"] diff --git a/components/Markdown/demos/custom_tags/select-box/card_shape.py b/components/Markdown/demos/custom_tags/select-box/card_shape.py index b2813b85be31b8f4c111ab585a66f6fed984f275..40c7f83b8c7d59369ced2e2590a9a4965ab3a80f 100644 --- a/components/Markdown/demos/custom_tags/select-box/card_shape.py +++ b/components/Markdown/demos/custom_tags/select-box/card_shape.py @@ -2,7 +2,6 @@ import json import os import gradio as gr - import modelscope_studio as mgr # Card shape supports setting `imgSrc` as the cover. @@ -10,8 +9,7 @@ options = [{ "label": "A", "imgSrc": - os.path.join(os.path.dirname(__file__), - '../../../../resources/screen.jpeg'), + os.path.join(os.path.dirname(__file__), '../../../resources/screen.jpeg'), "value": "a" }, "b", "c", "d"] diff --git a/components/Markdown/demos/custom_tags/select-box/card_shape_width_auto.py b/components/Markdown/demos/custom_tags/select-box/card_shape_width_auto.py index 41e9f63bae4f21fc64127ae38c00ed2b434e20ec..f71f1fa0aa338d896e20b4f1334ccaf6ce8f9ed5 100644 --- a/components/Markdown/demos/custom_tags/select-box/card_shape_width_auto.py +++ b/components/Markdown/demos/custom_tags/select-box/card_shape_width_auto.py @@ -2,7 +2,6 @@ import json import os import gradio as gr - import modelscope_studio as mgr # Card shape supports setting `imgSrc` as the cover. @@ -10,8 +9,7 @@ options = [{ "label": "A", "imgSrc": - os.path.join(os.path.dirname(__file__), - '../../../../resources/screen.jpeg'), + os.path.join(os.path.dirname(__file__), '../../../resources/screen.jpeg'), "value": "a" }, "b", "c", "d"] diff --git a/components/Markdown/demos/custom_tags/select-box/python_events.py b/components/Markdown/demos/custom_tags/select-box/python_events.py index dd585e7ac9f17ed94553e518e1ca123e76607763..d77b89a4d97312456f8780e1e43a494036bcfb3c 100644 --- a/components/Markdown/demos/custom_tags/select-box/python_events.py +++ b/components/Markdown/demos/custom_tags/select-box/python_events.py @@ -1,7 +1,6 @@ import json import gradio as gr - import modelscope_studio as mgr options = [{"label": "A", "value": "a"}, "b", "c"] diff --git a/components/Markdown/demos/multimodal.py b/components/Markdown/demos/multimodal.py index ecc5928e3fd96cf79caf6102113670448e19ca99..f056314eb299226ce151af44fa110bddc50781dd 100644 --- a/components/Markdown/demos/multimodal.py +++ b/components/Markdown/demos/multimodal.py @@ -1,12 +1,11 @@ import os import gradio as gr - import modelscope_studio as mgr def resolve_assets(relative_path): - return os.path.join(os.path.dirname(__file__), "../../resources", + return os.path.join(os.path.dirname(__file__), "../resources", relative_path) diff --git a/components/Markdown/demos/select-box.py b/components/Markdown/demos/select-box.py index 9b69862bdf1d79dc6d36646449c0cf0c24c61a2f..7f5da713c7f13f7a1c09e6dbe61e658866e5005e 100644 --- a/components/Markdown/demos/select-box.py +++ b/components/Markdown/demos/select-box.py @@ -1,7 +1,6 @@ import json import gradio as gr - import modelscope_studio as mgr # `label` will display on the page, and `value` is the actual selected value. diff --git a/components/Markdown/resources/audio.wav b/components/Markdown/resources/audio.wav new file mode 100644 index 0000000000000000000000000000000000000000..105190ad88e2e177540361de340e54feb1587f3c Binary files /dev/null and b/components/Markdown/resources/audio.wav differ diff --git a/components/Markdown/resources/bot.jpeg b/components/Markdown/resources/bot.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..5fde8cc45f61b677c0581e6889b11e269c35be08 Binary files /dev/null and b/components/Markdown/resources/bot.jpeg differ diff --git a/components/Markdown/resources/custom_components/custom_select.js b/components/Markdown/resources/custom_components/custom_select.js new file mode 100644 index 0000000000000000000000000000000000000000..ca7e2ae712ca53eff775d1f5b22d9c004720db0b --- /dev/null +++ b/components/Markdown/resources/custom_components/custom_select.js @@ -0,0 +1,26 @@ +(props, cc, { el, onMount }) => { + const options = JSON.parse(props.options); + el.innerHTML = ` + ${options + .map((option) => { + return `
+ +
`; + }) + .join('')} + `; + onMount(() => { + const inputs = Array.from(el.getElementsByTagName('input')); + Array.from(el.getElementsByTagName('label')).forEach((label, i) => { + label.addEventListener('click', () => { + inputs.forEach((input) => { + input.checked = false; + }); + const input = label.getElementsByTagName('input')[0]; + input.checked = true; + // Use cc.dispatch to trigger events. + cc.dispatch(options[i]); + }); + }); + }); +}; diff --git a/components/Markdown/resources/dog.mp4 b/components/Markdown/resources/dog.mp4 new file mode 100644 index 0000000000000000000000000000000000000000..062b9c81317de43f392c56e9e03444bf8cc31d51 --- /dev/null +++ b/components/Markdown/resources/dog.mp4 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:39d086ce29e48cf76e5042d2f3f0611ee46575f70fa3dc0c40dd4cfffde3d933 +size 8626383 diff --git a/components/Markdown/resources/screen.jpeg b/components/Markdown/resources/screen.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..574735acb117e86c5c0850e2b5489b8f8efa20cc Binary files /dev/null and b/components/Markdown/resources/screen.jpeg differ diff --git a/components/Markdown/resources/user.jpeg b/components/Markdown/resources/user.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..536948b6bd19cb0b49c44b74e2790198301520e5 Binary files /dev/null and b/components/Markdown/resources/user.jpeg differ diff --git a/components/MultimodalInput/README.md b/components/MultimodalInput/README.md index e82c502fd4b3ae76deb07aeed336389461442102..b3e1441b24f985bd555561f1384680efcaae6ba5 100644 --- a/components/MultimodalInput/README.md +++ b/components/MultimodalInput/README.md @@ -43,7 +43,7 @@ class MultimodalInputData(GradioModel): | Attribute | Type | Default Value | Description | | ------------------- | ----------------------------------------------- | ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| sources | List[Literal['upload', 'microphone', 'webcam']] | ['upload'] | A list of types for uploading files. "upload" provides an upload file button. "microphone" supports user audio input. "webcam" supports user photography to generate images or videos. | +| sources | list[Literal['upload', 'microphone', 'webcam']] | ['upload'] | A list of types for uploading files. "upload" provides an upload file button. "microphone" supports user audio input. "webcam" supports user photography to generate images or videos. | | webcam_props | dict | None | webcam component properties, currently supports passing mirror_webcam(bool), include_audio(bool) | | upload_button_props | dict | None | Upload file button properties, same as gradio UploadButton | | submit_button_props | dict | None | Submit button properties, same as gradio Button | diff --git a/components/MultimodalInput/demos/basic.py b/components/MultimodalInput/demos/basic.py index 67d7470d29e8d017e88884a9b2783b529f1930d8..55249c4b3433c88a1575c13f6ab75910b8bab35b 100644 --- a/components/MultimodalInput/demos/basic.py +++ b/components/MultimodalInput/demos/basic.py @@ -1,5 +1,4 @@ import gradio as gr - import modelscope_studio as mgr diff --git a/components/MultimodalInput/demos/config_buttons.py b/components/MultimodalInput/demos/config_buttons.py index 493c59a64404a565102c57eb373d851a5702c04b..6b73382be2cc6dba792cd0275e8a668d08c21d05 100644 --- a/components/MultimodalInput/demos/config_buttons.py +++ b/components/MultimodalInput/demos/config_buttons.py @@ -1,5 +1,4 @@ import gradio as gr - import modelscope_studio as mgr diff --git a/components/MultimodalInput/demos/upload_sources.py b/components/MultimodalInput/demos/upload_sources.py index 2e9b5476fdce7d83ee4b9e2f47de91f18a7e42bd..e9caff69a0791dde1583d8cb6069765066c79955 100644 --- a/components/MultimodalInput/demos/upload_sources.py +++ b/components/MultimodalInput/demos/upload_sources.py @@ -1,5 +1,4 @@ import gradio as gr - import modelscope_studio as mgr diff --git a/components/MultimodalInput/demos/with_chatbot.py b/components/MultimodalInput/demos/with_chatbot.py index 6ad7784a434bb224edf30b0dcd4e668f43e7de4e..fe48acad1ea0cae316ce54468659e7c345f247fb 100644 --- a/components/MultimodalInput/demos/with_chatbot.py +++ b/components/MultimodalInput/demos/with_chatbot.py @@ -1,7 +1,6 @@ import time import gradio as gr - import modelscope_studio as mgr diff --git a/components/WaterfallGallery/README-zh_CN.md b/components/WaterfallGallery/README-zh_CN.md deleted file mode 100644 index 94552d6c36dc16a3717e9ff437ddb441bc7788dc..0000000000000000000000000000000000000000 --- a/components/WaterfallGallery/README-zh_CN.md +++ /dev/null @@ -1,71 +0,0 @@ -# WaterfallGallery - -瀑布流形式的 gradio Gallery。 - -- 支持瀑布流展示图片 -- 增加点赞按钮,支持图片额外绑定`like`事件 -- 增加 action 按钮,支持图片额外绑定`click`事件 -- 响应式 columns - -## 如何使用 - -### 基本使用 - - - -### 响应式 columns - - - -### 加载更多 - - - -### 点赞/点击反馈 - - - -## API 及参数列表 - -以下 API 均为在原有 gradio Gallery 外的额外拓展参数。 - -### value - -接口定义: - -```python -GalleryImageType = Union[np.ndarray, _Image.Image, FileData, Path, str] -CaptionedGalleryImageType = Tuple[GalleryImageType, str] - - -class GalleryImage(GradioModel): - image: Union[FileData, Path, str] - caption: Optional[str] = None - liked: Optional[bool] = None - # custom meta data - meta: Optional[Any] = None - - -class GalleryData(GradioRootModel): - root: List[GalleryImage] -``` - -### props - -| 属性 | 类型 | 默认值 | 描述 | -| ---------------------- | -------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| has_more | bool | None | 如果为 True,会显示 "加载更多" 按钮 | -| load_more_button_props | dict | None | ”加载更多“按钮属性,同 gradio Button | -| columns | int \| tuple \| dict | 2 | 展示在以下尺寸屏幕(<576px(xs)、<768px(sm)、<992px(md)、<1200px(lg)、<1600px(xl)、>1600px(xll))中在一行显示的图像数量。
- 如果传入 int, 则应用于所有尺寸屏幕;
- 如果传入 tuple, 当给出的断点少于 6 个, 则最后一个断点将用于所有后续断点;
- 如果传入 dict, 则可以以 [xs,sm,md,lg,xl,xll] 为键表示每个尺寸屏幕的图像数量。 | -| gap | tuple \| int | 8 | 图片之间的间隙 (px)。 如果传递一个元组,则第一个值是宽度的间隙,第二个值是高度的间隙。如果传递数字,则宽度和高度的间隙相同 | -| action_label | str | 'Click' | action 按钮的文案。当 `clickable`为 True 时才展示 | -| likeable | bool | None | 是否显示喜欢或不喜欢按钮。 可以通过显示绑定 `.like` 方法自动设置。 | -| clickable | bool | None | 是否显示 action 按钮。 可以通过显示绑定 `.click` 方法自动设置。 | - -### event listeners - -| 事件 | 描述 | -| ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `mgr.WaterfallGallery.load_more(fn, ···)` | “加载更多”按钮被点击时触发。 | -| `mgr.WaterfallGallery.like(fn, ···)` | 当点赞/点踩按钮被点击时触发,EventData 为:
- index:当前图片索引。
- value:当前图片信息。
- liked:当前图片的喜欢/不喜欢状态,可以为 None,代表用户取消操作。 | -| `mgr.WaterfallGallery.click(fn, ···)` | action 按钮被点击时触发,EventData 为:
- index:当前图片索引。
- value:当前图片信息。 | diff --git a/components/WaterfallGallery/README.md b/components/WaterfallGallery/README.md deleted file mode 100644 index 392fe320a45a75d44b8f0111deb73e4a1021da23..0000000000000000000000000000000000000000 --- a/components/WaterfallGallery/README.md +++ /dev/null @@ -1,71 +0,0 @@ -# WaterfallGallery - -gradio Gallery with waterfall flow. - -- Support waterfall flow display images -- Added a like button, support additional binding of `like` events to images -- Added an action button, support additional binding of `click` event to images -- Responsive columns - -## How to Use - -### Basic Usage - - - -### Responsive columns - - - -### Load More - - - -### Like/Click Feedback - - - -## API and Parameter List - -The following APIs are additional extended parameters beyond the original gradio Gallery. - -### value - -Interface definition: - -```python -GalleryImageType = Union[np.ndarray, _Image.Image, FileData, Path, str] -CaptionedGalleryImageType = Tuple[GalleryImageType, str] - - -class GalleryImage(GradioModel): - image: Union[FileData, Path, str] - caption: Optional[str] = None - liked: Optional[bool] = None - # custom meta data - meta: Optional[Any] = None - - -class GalleryData(GradioRootModel): - root: List[GalleryImage] -``` - -### props - -| Attribute | Type | Default Value | Description | -| ---------------------- | -------------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| has_more | bool | None | If True, will show the "Load More" button. | -| lode_more_button_props | dict | None | “Load More” button properties, same as gradio Button | -| columns | int \| tuple \| dict | 2 | Displays the number of images displayed in a row on the following screen sizes (<576px(xs), <768px(sm), <992px(md), <1200px(lg), <1600px(xl), >1600px(xll)).
- If int is passed in, it will apply to all screen sizes;
- If tuple is passed in, when less than 6 breakpoints are given, the last breakpoint will be used for all subsequent breakpoints ;
- If a dict is passed in, you can represents the number of images for each size screen with [xs,sm,md,lg,xl,xll] as the key. | -| gap | tuple \| int | 8 | The gap (px) between images. If a tuple is passed, the first value is the gap for width and the second value is the gap for height.If a number is passed, the gap will be the same for width and height. | -| action_label | str | 'Click' | The label for the action button. Only displayed if `clickable` is set to True. | -| likeable | bool | None | Whether the gallery image display a like or dislike button. Set automatically by the .like method but has to be present in the signature for it to show up in the config. | -| clickable | bool | None | Whether the gallery image display an action button. Set automatically by the .click method but has to be present in the signature for it to show up in the config. | - -### Event Listeners - -| Event | Description | -| ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `mgr.WaterfallGallery.load_more(fn, ···)` | Triggered when the "Load More" button is clicked. | -| `mgr.WaterfallGallery.like(fn, ···)` | Triggered when the Like/Dislike button is clicked. EventData is:
- index: current image index.
- value: current image info.
- liked: like/dislike status of the current image, which can be None, indicating that the user cancels the operation. | -| `mgr.WaterfallGallery.click(fn, ···)` | Triggered when the action button is clicked, EventData is:
- index: current image index.
- value: current image info. | diff --git a/components/WaterfallGallery/app.py b/components/WaterfallGallery/app.py deleted file mode 100644 index 77372ef291165f2cf77a8944f3f8b18773972190..0000000000000000000000000000000000000000 --- a/components/WaterfallGallery/app.py +++ /dev/null @@ -1,6 +0,0 @@ -from components.Docs import Docs - -docs = Docs(__file__) - -if __name__ == "__main__": - docs.render().queue().launch() diff --git a/components/WaterfallGallery/demos/basic.py b/components/WaterfallGallery/demos/basic.py deleted file mode 100644 index 7f1c2760d3fe8fa1ac7c0adaa2cfa9997ccf9656..0000000000000000000000000000000000000000 --- a/components/WaterfallGallery/demos/basic.py +++ /dev/null @@ -1,30 +0,0 @@ -import os - -import gradio as gr - -import modelscope_studio as mgr - - -def resolve_assets(relative_path): - return os.path.join(os.path.dirname(__file__), "../../resources", - relative_path) - - -with gr.Blocks() as demo: - mgr.WaterfallGallery( - value=[ - resolve_assets('modelscope.svg'), - # pass a tuple - [resolve_assets('bot.jpeg'), 'bot'], - # pass a dict - { - "image": resolve_assets('user.jpeg'), - "caption": "user", - }, - resolve_assets('screen.jpeg'), - ], - columns=2, - height=600) - -if __name__ == "__main__": - demo.queue().launch() diff --git a/components/WaterfallGallery/demos/like_click_feedback.py b/components/WaterfallGallery/demos/like_click_feedback.py deleted file mode 100644 index 10e2c37d48039530b76de3b689b1439dc34d25d8..0000000000000000000000000000000000000000 --- a/components/WaterfallGallery/demos/like_click_feedback.py +++ /dev/null @@ -1,37 +0,0 @@ -import os - -import gradio as gr - -import modelscope_studio as mgr - - -def resolve_assets(relative_path): - return os.path.join(os.path.dirname(__file__), "../../resources", - relative_path) - - -def fn(data: gr.EventData): - print(data._data) - - -with gr.Blocks() as demo: - gallery = mgr.WaterfallGallery( - value=[ - resolve_assets('modelscope.svg'), - # pass a tuple - [resolve_assets('bot.jpeg'), 'bot'], - # pass a dict - { - "image": resolve_assets('user.jpeg'), - "caption": "user", - }, - resolve_assets('screen.jpeg'), - ], - action_label="Click Me!", - columns=2, - height=600) - gallery.like(fn=fn) - gallery.click(fn=fn) - -if __name__ == "__main__": - demo.queue().launch() diff --git a/components/WaterfallGallery/demos/load_more.py b/components/WaterfallGallery/demos/load_more.py deleted file mode 100644 index a6a23e7814d11138ff3b1a03843ac0fe31cd77f5..0000000000000000000000000000000000000000 --- a/components/WaterfallGallery/demos/load_more.py +++ /dev/null @@ -1,45 +0,0 @@ -import os -import time - -import gradio as gr - -import modelscope_studio as mgr - - -def resolve_assets(relative_path): - return os.path.join(os.path.dirname(__file__), "../../resources", - relative_path) - - -def load_more(_gallery): - time.sleep(1) - _gallery.append(resolve_assets('modelscope.svg')) - _gallery.append(resolve_assets('bot.jpeg')) - _gallery.append(resolve_assets('user.jpeg')) - _gallery.append(resolve_assets('screen.jpeg')) - has_more = True - if (len(_gallery) > 10): - has_more = False - return gr.update(value=_gallery, has_more=has_more) - - -with gr.Blocks() as demo: - gallery = mgr.WaterfallGallery( - value=[ - resolve_assets('modelscope.svg'), - # pass a tuple - [resolve_assets('bot.jpeg'), 'bot'], - # pass a dict - { - "image": resolve_assets('user.jpeg'), - "caption": "user", - }, - resolve_assets('screen.jpeg'), - ], - has_more=True, - columns=2, - height=600) - gallery.load_more(fn=load_more, inputs=[gallery], outputs=[gallery]) - -if __name__ == "__main__": - demo.queue().launch() diff --git a/components/WaterfallGallery/demos/responsive_columns.py b/components/WaterfallGallery/demos/responsive_columns.py deleted file mode 100644 index f6bded307dc9568f0ecb169ac28d2c2a37b6cdd1..0000000000000000000000000000000000000000 --- a/components/WaterfallGallery/demos/responsive_columns.py +++ /dev/null @@ -1,35 +0,0 @@ -import os - -import gradio as gr - -import modelscope_studio as mgr - - -def resolve_assets(relative_path): - return os.path.join(os.path.dirname(__file__), "../../resources", - relative_path) - - -def fn(): - return gr.update(columns={"xs": 2, "lg": 3}) - - -with gr.Blocks() as demo: - gallery = mgr.WaterfallGallery( - value=[ - resolve_assets('modelscope.svg'), - # pass a tuple - [resolve_assets('bot.jpeg'), 'bot'], - # pass a dict - { - "image": resolve_assets('user.jpeg'), - "caption": "user", - }, - resolve_assets('screen.jpeg'), - ], - columns=[2, 3, 4], - height=600) - gr.Button("Update Columns").click(fn=fn, outputs=[gallery]) - -if __name__ == "__main__": - demo.queue().launch() diff --git a/components/parse_markdown.py b/components/parse_markdown.py index 56074f51585def881aa974994f2fa944c335c8ac..7f2bc78d3b0f241ecb930d43e6f787c8e6a14413 100644 --- a/components/parse_markdown.py +++ b/components/parse_markdown.py @@ -42,16 +42,10 @@ class MarkdownParser(HTMLParser): return if tag == "demo": self.value.append({ - "type": - "demo", - "code_position": - dict(attrs).get("code-position", 'left'), - "name": - dict(attrs)["name"], - "prefix": - "", - "suffix": - "" + "type": "demo", + "name": dict(attrs)["name"], + "prefix": "", + "suffix": "" }) elif tag == "file": content = self.read_file(dict(attrs)["src"]) diff --git a/components/resources/custom_components/custom_select.js b/components/resources/custom_components/custom_select.js deleted file mode 100644 index f4a1cb405ae5efb33e31990018b2beac5ac26aa3..0000000000000000000000000000000000000000 --- a/components/resources/custom_components/custom_select.js +++ /dev/null @@ -1,29 +0,0 @@ -(props, cc, { el, onUpdate }) => { - const options = JSON.parse(props.options); - el.innerHTML = ` - ${options - .map((option) => { - return `
- -
`; - }) - .join('')} - `; - onUpdate( - () => { - const inputs = Array.from(el.getElementsByTagName('input')); - Array.from(el.getElementsByTagName('label')).forEach((label, i) => { - label.addEventListener('click', () => { - inputs.forEach((input) => { - input.checked = false; - }); - const input = label.getElementsByTagName('input')[0]; - input.checked = true; - // Use cc.dispatch to trigger events. - cc.dispatch(options[i]); - }); - }); - }, - { callAfterMount: true } - ); -}; diff --git a/components/resources/modelscope.svg b/components/resources/modelscope.svg deleted file mode 100644 index 093ba6fe2a55a9b6c5f5105af9f3544d60429e7b..0000000000000000000000000000000000000000 --- a/components/resources/modelscope.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/modelscope_gradio_components-0.0.1b8-py3-none-any.whl b/modelscope_gradio_components-0.0.1b8-py3-none-any.whl new file mode 100644 index 0000000000000000000000000000000000000000..9c3d9ef66b7f3a2ba4ec3cfd3b857652a085bc38 --- /dev/null +++ b/modelscope_gradio_components-0.0.1b8-py3-none-any.whl @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:315cf0dc047cec535dc3b57706891c404620cdff32fe8feb4b013e771e72e512 +size 6260465 diff --git a/modelscope_studio-0.4.0-py3-none-any.whl b/modelscope_studio-0.4.0-py3-none-any.whl deleted file mode 100644 index ccb59b4d59e5b0ea55c7964f1274c03d53ada899..0000000000000000000000000000000000000000 --- a/modelscope_studio-0.4.0-py3-none-any.whl +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4ea6dc30b6a751eff8b0e7e99554af09ad2b6d13841e8896e5e5af544d9425b7 -size 10995416 diff --git a/requirements.txt b/requirements.txt index b4f81f0ed622406099117d2b1b10d1cefd1cb6ba..dfb99a6639e934d38ae5936d16c84f2cd69e6ab3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1 @@ modelscope_studio -modelscope_studio-0.4.0-py3-none-any.whl diff --git a/src/pyproject.toml b/src/pyproject.toml index 016557687e30cf6dd83ea619b814ee3c44d301a6..c83b7c0f722fe53f85a4119337e1f431a3f35a6b 100644 --- a/src/pyproject.toml +++ b/src/pyproject.toml @@ -8,15 +8,15 @@ build-backend = "hatchling.build" [project] name = "modelscope_studio" -version = "0.1.7" -description = "A set of extension component, inluding components for conversational input and display in multimodal scenarios, as well as more components for vertical scenarios." +version = "0.0.1-beta.8" +description = "A set of extension component libraries based on gradio 4.x, mainly focuses on enhancing conversational scenarios, supporting multimodal contexts, and providing assistance for various other specialized scenarios." readme = "README.md" license = "Apache-2.0" requires-python = ">=3.8" authors = [{ name = "YOUR NAME", email = "YOUREMAIL@domain.com" }] keywords = [ - "gradio-custom-component", - "modelscope-studio", + "gradio-custom-component", + "modelscope-gradio-components", "gradio-template-Chatbot", ] # Add dependencies here @@ -41,17 +41,16 @@ dev = ["build", "twine"] [tool.hatch.build] artifacts = [ - "*.pyi", - "backend/modelscope_studio/components/Chatbot/templates", - "backend/modelscope_studio/components/MultimodalInput/templates", - "backend/modelscope_studio/components/Markdown/templates", - "backend/modelscope_studio/components/WaterfallGallery/templates", + "backend/modelscope_gradio_components/components/Chatbot/templates", + "backend/modelscope_gradio_components/components/MultimodalInput/templates", + "backend/modelscope_gradio_components/components/Markdown/templates", + "backend/modelscope_gradio_components/components/Chatbot/templates", + "backend/modelscope_gradio_components/components/Markdown/templates", + "backend/modelscope_gradio_components/components/MultimodalInput/templates", ] [tool.hatch.build.targets.sdist] -exclude = ["__pycache__"] -include = ["/backend/modelscope_studio"] +include = ["/backend/modelscope_gradio_components"] [tool.hatch.build.targets.wheel] -packages = ["/backend/modelscope_studio"] -exclude = ["__pycache__"] +packages = ["/backend/modelscope_gradio_components"]