Coloring commited on
Commit
f18a2c3
·
1 Parent(s): 43a5013

feat: add layout template `coder_artifacts`

Browse files
Files changed (39) hide show
  1. app.py +77 -7
  2. components/antd/table/demos/custom_columns.py +1 -0
  3. components/antdx/bubble/README-zh_CN.md +12 -0
  4. components/antdx/bubble/README.md +12 -0
  5. components/antdx/bubble/app.py +6 -0
  6. components/antdx/bubble/demos/basic.py +90 -0
  7. components/antdx/bubble/demos/bubble_list.py +83 -0
  8. components/antdx/bubble/demos/chatbot.py +149 -0
  9. components/antdx/bubble/demos/custom_list_content.py +118 -0
  10. components/antdx/bubble/demos/typing_effect.py +41 -0
  11. components/antdx/bubble/demos/variant.py +56 -0
  12. components/antdx/conversations/README-zh_CN.md +9 -0
  13. components/antdx/conversations/README.md +9 -0
  14. components/antdx/conversations/app.py +6 -0
  15. components/antdx/conversations/demos/basic.py +49 -0
  16. components/antdx/conversations/demos/group.py +30 -0
  17. components/antdx/conversations/demos/operations.py +46 -0
  18. components/antdx/overview/README-zh_CN.md +20 -0
  19. components/antdx/overview/README.md +20 -0
  20. components/antdx/overview/app.py +6 -0
  21. components/antdx/overview/demos/quick_start.py +17 -0
  22. components/antdx/prompts/README-zh_CN.md +8 -0
  23. components/antdx/prompts/README.md +8 -0
  24. components/antdx/prompts/app.py +6 -0
  25. components/antdx/prompts/demos/basic.py +81 -0
  26. components/antdx/prompts/demos/nest_usage.py +86 -0
  27. components/antdx/welcome/README-zh_CN.md +7 -0
  28. components/antdx/welcome/README.md +7 -0
  29. components/antdx/welcome/app.py +6 -0
  30. components/antdx/welcome/demos/basic.py +36 -0
  31. helper/Docs.py +52 -29
  32. helper/Site.py +6 -1
  33. helper/parse_markdown.py +2 -0
  34. layout_templates/coder_artifacts/README-zh_CN.md +7 -0
  35. layout_templates/coder_artifacts/README.md +7 -0
  36. layout_templates/coder_artifacts/app.py +6 -0
  37. layout_templates/coder_artifacts/demos/app.py +446 -0
  38. requirements.txt +2 -1
  39. src/pyproject.toml +4 -1
app.py CHANGED
@@ -15,11 +15,11 @@ def get_text(text: str, cn_text: str):
15
  return text
16
 
17
 
18
- def get_docs(file_path: str, type: Literal["antd", "base"]):
19
  import importlib.util
20
 
21
  components = []
22
- components_dir = os.path.join(os.path.dirname(file_path), "components",
23
  type)
24
  for dir in os.listdir(components_dir):
25
  abs_dir = os.path.join(components_dir, dir)
@@ -38,15 +38,49 @@ def get_docs(file_path: str, type: Literal["antd", "base"]):
38
  return docs
39
 
40
 
41
- index_docs = {"modelscope_studio": Docs(__file__)}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
 
43
- base_docs = get_docs(__file__, "base")
44
- antd_docs = get_docs(__file__, "antd")
 
 
 
45
 
46
  default_active_tab = "index"
47
  index_menu_items = [{
48
  "label": get_text("ModelScope-Studio", "ModelScope-Studio"),
49
- "key": "modelscope_studio"
 
 
 
 
 
 
 
 
 
50
  }]
51
 
52
  base_menu_items = [{
@@ -350,6 +384,35 @@ antd_menu_items = [{
350
  }]
351
  }]
352
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
353
 
354
  def logo():
355
  with antd.Flex(align='center', gap=8):
@@ -386,7 +449,7 @@ tabs = [
386
  {
387
  "label": get_text("Overview", "概览"),
388
  "key": "index",
389
- "default_active_key": "modelscope_studio",
390
  "menus": index_menu_items
391
  },
392
  {
@@ -402,6 +465,12 @@ tabs = [
402
  "menus": antd_menu_items,
403
  "extra_menu_footer": more_components
404
  },
 
 
 
 
 
 
405
  {
406
  "label": get_text("Version 0.x", "0.x 版本"),
407
  "key": "legacy",
@@ -415,6 +484,7 @@ site = Site(
415
  # match the key of tabs
416
  "index": index_docs,
417
  "antd": antd_docs,
 
418
  "base": base_docs
419
  },
420
  default_active_tab=default_active_tab,
 
15
  return text
16
 
17
 
18
+ def get_docs(type: Literal["antd", "antdx", "base"]):
19
  import importlib.util
20
 
21
  components = []
22
+ components_dir = os.path.join(os.path.dirname(__file__), "components",
23
  type)
24
  for dir in os.listdir(components_dir):
25
  abs_dir = os.path.join(components_dir, dir)
 
38
  return docs
39
 
40
 
41
+ def get_layout_templates():
42
+ import importlib.util
43
+
44
+ templates = []
45
+ templates_dir = os.path.join(os.path.dirname(__file__), "layout_templates")
46
+ for dir in os.listdir(templates_dir):
47
+ abs_dir = os.path.join(templates_dir, dir)
48
+ if os.path.isdir(abs_dir):
49
+ app_file = os.path.join(abs_dir, "app.py")
50
+ if os.path.exists(app_file):
51
+ templates.append(dir)
52
+
53
+ docs = {}
54
+ for template in templates:
55
+ spec = importlib.util.spec_from_file_location(
56
+ "doc", os.path.join(templates_dir, template, "app.py"))
57
+ module = importlib.util.module_from_spec(spec)
58
+ spec.loader.exec_module(module)
59
+ docs[template] = module.docs
60
+ return docs
61
+
62
+
63
+ layout_templates = get_layout_templates()
64
 
65
+ index_docs = {"overview": Docs(__file__), **layout_templates}
66
+
67
+ base_docs = get_docs("base")
68
+ antd_docs = get_docs("antd")
69
+ # antdx_docs = get_docs("antdx")
70
 
71
  default_active_tab = "index"
72
  index_menu_items = [{
73
  "label": get_text("ModelScope-Studio", "ModelScope-Studio"),
74
+ "key": "overview"
75
+ }, {
76
+ "label":
77
+ get_text("Layout Templates", "布局模板"),
78
+ "type":
79
+ "group",
80
+ "children": [{
81
+ "label": get_text("Coder-Artifacts", "Coder-Artifacts"),
82
+ "key": "coder_artifacts"
83
+ }]
84
  }]
85
 
86
  base_menu_items = [{
 
384
  }]
385
  }]
386
 
387
+ antdx_menu_items = [{
388
+ "label": get_text("Overview", "概览"),
389
+ "key": "overview"
390
+ }, {
391
+ "label":
392
+ get_text("Common", "通用"),
393
+ "type":
394
+ "group",
395
+ "children": [{
396
+ "label": get_text("Bubble", "Bubble 对话气泡"),
397
+ "key": "bubble"
398
+ }, {
399
+ "label": get_text("Conversations", "Conversations 管理对话"),
400
+ "key": "conversations"
401
+ }]
402
+ }, {
403
+ "label":
404
+ get_text("Wake", "唤醒"),
405
+ "type":
406
+ "group",
407
+ "children": [{
408
+ "label": get_text("Welcome", "Welcome 欢迎"),
409
+ "key": "welcome"
410
+ }, {
411
+ "label": get_text("Prompts", "Prompts 提示集"),
412
+ "key": "prompts"
413
+ }]
414
+ }]
415
+
416
 
417
  def logo():
418
  with antd.Flex(align='center', gap=8):
 
449
  {
450
  "label": get_text("Overview", "概览"),
451
  "key": "index",
452
+ "default_active_key": "overview",
453
  "menus": index_menu_items
454
  },
455
  {
 
465
  "menus": antd_menu_items,
466
  "extra_menu_footer": more_components
467
  },
468
+ # {
469
+ # "label": get_text("Antdx Components", "Antdx 组件"),
470
+ # "key": "antdx",
471
+ # "default_active_key": "overview",
472
+ # "menus": antdx_menu_items,
473
+ # },
474
  {
475
  "label": get_text("Version 0.x", "0.x 版本"),
476
  "key": "legacy",
 
484
  # match the key of tabs
485
  "index": index_docs,
486
  "antd": antd_docs,
487
+ # "antdx": antdx_docs,
488
  "base": base_docs
489
  },
490
  default_active_tab=default_active_tab,
components/antd/table/demos/custom_columns.py CHANGED
@@ -69,6 +69,7 @@ with gr.Blocks() as demo:
69
  ):
70
  with ms.Slot(
71
  "render",
 
72
  "(_, record, index) => ({ invite: { value: 'Invite ' + record.name, index }, delete: { index }})"
73
  ):
74
  with antd.Space(size="middle"):
 
69
  ):
70
  with ms.Slot(
71
  "render",
72
+ params_mapping=
73
  "(_, record, index) => ({ invite: { value: 'Invite ' + record.name, index }, delete: { index }})"
74
  ):
75
  with antd.Space(size="middle"):
components/antdx/bubble/README-zh_CN.md ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Bubble
2
+
3
+ A bubble component for chat. See [Ant Design X](https://x.ant.design/components/bubble/) for more information.
4
+
5
+ ## Examples
6
+
7
+ <demo name="basic" position="bottom" collapsible="true"></demo>
8
+ <demo name="typing_effect" title="Typing Effect"></demo>
9
+ <demo name="variant" title="Variant"></demo>
10
+ <demo name="bubble_list" title="Bubble List"></demo>
11
+ <demo name="custom_list_content" title="Custom List Content"></demo>
12
+ <demo name="chatbot" title="Chatbot" position="bottom" collapsible="true"></demo>
components/antdx/bubble/README.md ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Bubble
2
+
3
+ A bubble component for chat. See [Ant Design X](https://x.ant.design/components/bubble/) for more information.
4
+
5
+ ## Examples
6
+
7
+ <demo name="basic" position="bottom" collapsible="true"></demo>
8
+ <demo name="typing_effect" title="Typing Effect"></demo>
9
+ <demo name="variant" title="Variant"></demo>
10
+ <demo name="bubble_list" title="Bubble List"></demo>
11
+ <demo name="custom_list_content" title="Custom List Content"></demo>
12
+ <demo name="chatbot" title="Chatbot" position="bottom" collapsible="true"></demo>
components/antdx/bubble/app.py ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ from helper.Docs import Docs
2
+
3
+ docs = Docs(__file__)
4
+
5
+ if __name__ == "__main__":
6
+ docs.render().queue().launch()
components/antdx/bubble/demos/basic.py ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import modelscope_studio.components.antd as antd
3
+ import modelscope_studio.components.antdx as antdx
4
+ import modelscope_studio.components.base as ms
5
+
6
+ fooAvatar = {
7
+ "color": '#f56a00',
8
+ "backgroundColor": '#fde3cf',
9
+ }
10
+
11
+ barAvatar = {
12
+ "color": '#fff',
13
+ "backgroundColor": '#87d068',
14
+ }
15
+
16
+ hideAvatar = {
17
+ "visibility": 'hidden',
18
+ }
19
+
20
+ with gr.Blocks() as demo:
21
+ with ms.Application():
22
+ with antdx.XProvider():
23
+
24
+ antdx.Bubble("Hello World!")
25
+
26
+ antd.Divider("Placement and avatar")
27
+ with antd.Flex(gap="middle", vertical=True):
28
+ with antdx.Bubble(placement="start",
29
+ content="Good morning, how are you?"):
30
+ with ms.Slot("avatar"):
31
+ with antd.Avatar(elem_style=fooAvatar):
32
+ with ms.Slot("icon"):
33
+ antd.Icon("UserOutlined")
34
+ antdx.Bubble(placement="start",
35
+ content="What a beautiful day!",
36
+ avatar=dict(),
37
+ styles={"avatar": hideAvatar})
38
+ with antdx.Bubble(placement="end",
39
+ content="Hi, good morning, I'm fine!"):
40
+ with ms.Slot("avatar"):
41
+ with antd.Avatar(elem_style=barAvatar):
42
+ with ms.Slot("icon"):
43
+ antd.Icon("UserOutlined")
44
+ antdx.Bubble(placement="end",
45
+ content="Thank you!",
46
+ avatar=dict(),
47
+ styles={"avatar": hideAvatar})
48
+
49
+ antd.Divider("Header and footer")
50
+
51
+ with antdx.Bubble(
52
+ "Hello, welcome to use Ant Design X! Just ask if you have any questions.",
53
+ header="Ant Design X"):
54
+ with ms.Slot("avatar.icon"):
55
+ antd.Icon("UserOutlined")
56
+ with ms.Slot("footer"):
57
+ with antd.Space(size="small"):
58
+ with antd.Button(value=None,
59
+ color="default",
60
+ variant="text",
61
+ size="small"):
62
+ with ms.Slot("icon"):
63
+ antd.Icon("SyncOutlined")
64
+ with antd.Button(value=None,
65
+ color="default",
66
+ variant="text",
67
+ size="small"):
68
+ with ms.Slot("icon"):
69
+ antd.Icon("CopyOutlined")
70
+
71
+ antd.Divider("Loading")
72
+ with antd.Space():
73
+ ms.Span("Loading State")
74
+ loading_switch = antd.Switch(value=False)
75
+ with antdx.Bubble("hello world !") as loading_bubble:
76
+ with ms.Slot("avatar.icon"):
77
+ antd.Icon("UserOutlined")
78
+
79
+ loading_switch.change(fn=lambda x: gr.update(loading=x),
80
+ inputs=[loading_switch],
81
+ outputs=[loading_bubble])
82
+ antd.Divider("Markdown")
83
+ with antdx.Bubble():
84
+ with ms.Slot("avatar.icon"):
85
+ antd.Icon("UserOutlined")
86
+ with ms.Slot("content"):
87
+ ms.Markdown("Hello `Markdown`!")
88
+
89
+ if __name__ == "__main__":
90
+ demo.queue().launch()
components/antdx/bubble/demos/bubble_list.py ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import modelscope_studio.components.antd as antd
3
+ import modelscope_studio.components.antdx as antdx
4
+ import modelscope_studio.components.base as ms
5
+
6
+
7
+ def get_bubble_items(count):
8
+ result = []
9
+ for i in range(count):
10
+ is_ai = i % 2 != 0
11
+ content = 'Mock AI content. ' * 20 if is_ai else f'Mock User content `{i}`.'
12
+ result.append({
13
+ "role": "ai" if is_ai else "user",
14
+ "content": content,
15
+ "key": i - 1
16
+ })
17
+ return result
18
+
19
+
20
+ def add_bubble(state_value):
21
+ state_value["history_count"] = state_value["history_count"] + 1
22
+ return gr.update(value=state_value), gr.update(
23
+ items=get_bubble_items(state_value["history_count"]))
24
+
25
+
26
+ with gr.Blocks() as demo:
27
+
28
+ with ms.Application():
29
+ state = gr.State({"history_count": 3})
30
+ with antdx.XProvider():
31
+ antd.Typography.Paragraph(
32
+ "Preset Bubble list. Support auto scroll. Use roles to set default properties of Bubble."
33
+ )
34
+ with antd.Flex(gap="small", vertical=True):
35
+ with antd.Flex(gap="small",
36
+ elem_style=dict(alignSelf="flex-end")):
37
+ add_bubble_btn = antd.Button("Add Bubble")
38
+ scroll_btn = antd.Button("Scroll To First")
39
+ with antdx.Bubble.List(items=get_bubble_items(3),
40
+ elem_style=dict(maxHeight=300),
41
+ elem_id="bubble-list") as bubble_list:
42
+ # Define Roles
43
+ with ms.Slot("roles"):
44
+ with antdx.Bubble.List.Role(
45
+ role="ai",
46
+ placement="start",
47
+ typing=dict(step=5, interval=20),
48
+ elem_style=dict(maxWidth=600)):
49
+ with ms.Slot("avatar"):
50
+ with antd.Avatar(elem_style=dict(
51
+ backgroundColor="#fde3cf")):
52
+ with ms.Slot("icon"):
53
+ antd.Icon("UserOutlined")
54
+ # use messageRender to render markdown content
55
+ with ms.Slot(
56
+ "messageRender",
57
+ params_mapping="""content => content"""):
58
+ ms.Markdown()
59
+
60
+ with antdx.Bubble.List.Role(
61
+ role="user",
62
+ placement="end",
63
+ ):
64
+ with ms.Slot("avatar"):
65
+ with antd.Avatar(elem_style=dict(
66
+ backgroundColor="#87d068")):
67
+ with ms.Slot("icon"):
68
+ antd.Icon("UserOutlined")
69
+ with ms.Slot(
70
+ "messageRender",
71
+ params_mapping="(content) => content"):
72
+ ms.Markdown()
73
+ add_bubble_btn.click(fn=add_bubble,
74
+ inputs=[state],
75
+ outputs=[state, bubble_list])
76
+ scroll_btn.click(fn=None,
77
+ js="""() => {
78
+ const bubbleList = document.getElementById("bubble-list");
79
+ bubbleList.scrollTo({ top:0, behavior:'smooth' });
80
+ }""")
81
+
82
+ if __name__ == "__main__":
83
+ demo.queue().launch()
components/antdx/bubble/demos/chatbot.py ADDED
@@ -0,0 +1,149 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import modelscope_studio.components.antd as antd
3
+ import modelscope_studio.components.antdx as antdx
4
+ import modelscope_studio.components.base as ms
5
+
6
+
7
+ def create_bubble_item(i: int):
8
+ is_ai = i % 2 != 0
9
+ content = 'Mock AI content. ' * 20 if is_ai else f'Mock User content `{i}`.'
10
+ return {
11
+ "role": "ai" if is_ai else "user",
12
+ "content": content,
13
+ "key": i - 1
14
+ }
15
+
16
+
17
+ def add_bubble(state_value):
18
+ history_len = len(state_value["history"])
19
+ state_value["history"].append(create_bubble_item(history_len + 1))
20
+ return gr.update(value=state_value), gr.update(
21
+ items=state_value["history"])
22
+
23
+
24
+ def refresh(state_value, e: gr.EventData):
25
+ clicked_key = e._data["component"]["key"]
26
+ gr.Info(f"You clicked refresh button, item {clicked_key}")
27
+ state_value["history"][clicked_key]["content"] = "Refreshed"
28
+ return gr.update(value=state_value), gr.update(
29
+ items=state_value["history"])
30
+
31
+
32
+ def like(state_value, e: gr.EventData):
33
+ clicked_key = e._data["component"]["key"]
34
+ gr.Info(f"You clicked like button, item {clicked_key}")
35
+ state_value["history"][clicked_key]["meta"] = {
36
+ "action": "like",
37
+ }
38
+ return gr.update(value=state_value), gr.update(
39
+ items=state_value["history"])
40
+
41
+
42
+ def dislike(state_value, e: gr.EventData):
43
+ clicked_key = e._data["component"]["key"]
44
+ gr.Info(f"You clicked dislike button, item {clicked_key}")
45
+ state_value["history"][clicked_key]["meta"] = {
46
+ "action": "dislike",
47
+ }
48
+ return gr.update(value=state_value), gr.update(
49
+ items=state_value["history"])
50
+
51
+
52
+ default_history = [
53
+ create_bubble_item(1),
54
+ create_bubble_item(2),
55
+ create_bubble_item(3)
56
+ ]
57
+
58
+ with gr.Blocks() as demo:
59
+
60
+ with ms.Application():
61
+ state = gr.State({"history": default_history})
62
+ with antdx.XProvider():
63
+ with antd.Flex(gap="small", vertical=True):
64
+ with antd.Flex(gap="small",
65
+ elem_style=dict(alignSelf="flex-end")):
66
+ add_bubble_btn = antd.Button("Add Bubble")
67
+ scroll_btn = antd.Button("Scroll To First")
68
+ with antdx.Bubble.List(items=default_history,
69
+ elem_style=dict(maxHeight=500),
70
+ elem_id="bubble-list") as bubble_list:
71
+ # Define Roles
72
+ with ms.Slot("roles"):
73
+ with antdx.Bubble.List.Role(
74
+ role="ai",
75
+ placement="start",
76
+ typing=dict(step=5, interval=20),
77
+ styles=dict(footer=dict(width="100%")),
78
+ elem_style=dict(maxWidth=600)):
79
+ with ms.Slot("avatar"):
80
+ with antd.Avatar(elem_style=dict(
81
+ backgroundColor="#fde3cf")):
82
+ with ms.Slot("icon"):
83
+ antd.Icon("UserOutlined")
84
+ # use messageRender to render markdown content
85
+ with ms.Slot(
86
+ "messageRender",
87
+ params_mapping="""content => content"""):
88
+ ms.Markdown()
89
+
90
+ # render footer
91
+ with ms.Slot("footer",
92
+ params_mapping="""(item) => {
93
+ return { refresh: { key: item.key }, like: { key: item.key, color: item.meta?.action === "like" ? 'primary' : 'default' }, dislike: { key: item.key, color: item.meta?.action === "dislike" ? 'primary' : 'default' } }
94
+ }"""):
95
+ with antd.Button(
96
+ value=None,
97
+ size="small",
98
+ color="default",
99
+ variant="text",
100
+ as_item="refresh") as refresh_btn:
101
+ with ms.Slot("icon"):
102
+ antd.Icon("SyncOutlined")
103
+ refresh_btn.click(fn=refresh,
104
+ inputs=[state],
105
+ outputs=[state, bubble_list])
106
+ with antd.Button(value=None,
107
+ size="small",
108
+ variant="text",
109
+ as_item="like") as like_btn:
110
+ with ms.Slot("icon"):
111
+ antd.Icon("SmileOutlined")
112
+ like_btn.click(fn=like,
113
+ inputs=[state],
114
+ outputs=[state, bubble_list])
115
+ with antd.Button(
116
+ value=None,
117
+ size="small",
118
+ variant="text",
119
+ as_item="dislike") as dislike_btn:
120
+ with ms.Slot("icon"):
121
+ antd.Icon("FrownOutlined")
122
+ dislike_btn.click(fn=dislike,
123
+ inputs=[state],
124
+ outputs=[state, bubble_list])
125
+
126
+ with antdx.Bubble.List.Role(
127
+ role="user",
128
+ placement="end",
129
+ ):
130
+ with ms.Slot("avatar"):
131
+ with antd.Avatar(elem_style=dict(
132
+ backgroundColor="#87d068")):
133
+ with ms.Slot("icon"):
134
+ antd.Icon("UserOutlined")
135
+ with ms.Slot(
136
+ "messageRender",
137
+ params_mapping="(content) => content"):
138
+ ms.Markdown()
139
+ add_bubble_btn.click(fn=add_bubble,
140
+ inputs=[state],
141
+ outputs=[state, bubble_list])
142
+ scroll_btn.click(fn=None,
143
+ js="""() => {
144
+ const bubbleList = document.getElementById("bubble-list");
145
+ bubbleList.scrollTo({ top:0, behavior:'smooth' });
146
+ }""")
147
+
148
+ if __name__ == "__main__":
149
+ demo.queue().launch()
components/antdx/bubble/demos/custom_list_content.py ADDED
@@ -0,0 +1,118 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import modelscope_studio.components.antd as antd
3
+ import modelscope_studio.components.antdx as antdx
4
+ import modelscope_studio.components.base as ms
5
+
6
+ items = [
7
+ {
8
+ "key": '1',
9
+ "role": "ai-markdown",
10
+ "content": "`Hello, world!`"
11
+ },
12
+ {
13
+ "key": '2',
14
+ "role": "ai-error-message",
15
+ "content": "Error message"
16
+ },
17
+ {
18
+ "key":
19
+ '3',
20
+ "role":
21
+ 'ai-suggestion',
22
+ "content": [
23
+ {
24
+ "key": '1',
25
+ "description":
26
+ 'How to rest effectively after long hours of work?',
27
+ },
28
+ {
29
+ "key":
30
+ '2',
31
+ "description":
32
+ 'What are the secrets to maintaining a positive mindset?',
33
+ },
34
+ {
35
+ "key": '3',
36
+ "description": 'How to stay calm under immense pressure?',
37
+ },
38
+ ],
39
+ },
40
+ {
41
+ "key":
42
+ '4',
43
+ "role":
44
+ 'ai-file',
45
+ "content": [
46
+ {
47
+ "uid": '1',
48
+ "name": 'excel-file.xlsx',
49
+ "size": 111111,
50
+ "description": 'Checking the data',
51
+ },
52
+ {
53
+ "uid": '2',
54
+ "name": 'word-file.docx',
55
+ "size": 222222,
56
+ "status": 'uploading',
57
+ "percent": 23,
58
+ },
59
+ ],
60
+ },
61
+ ]
62
+
63
+ with gr.Blocks() as demo:
64
+
65
+ with ms.Application():
66
+ with antdx.XProvider():
67
+ antd.Typography.Paragraph(
68
+ "Customize the content of the bubble list, which is very useful for personalized customization scenarios."
69
+ )
70
+ with antdx.Bubble.List(items=items) as bubble_list:
71
+ # Define Roles
72
+ with ms.Slot("roles"):
73
+ with antdx.Bubble.List.Role(role="ai-markdown",
74
+ placement="start"):
75
+ with ms.Slot("avatar"):
76
+ with antd.Avatar(elem_style=dict(
77
+ backgroundColor="#fde3cf")):
78
+ with ms.Slot("icon"):
79
+ antd.Icon("UserOutlined")
80
+ with ms.Slot("messageRender",
81
+ params_mapping="(content) => content"):
82
+ ms.Markdown()
83
+ with antdx.Bubble.List.Role(role="ai-error-message",
84
+ placement="start"):
85
+ with ms.Slot("avatar"):
86
+ with antd.Avatar(elem_style=dict(
87
+ backgroundColor="#fde3cf")):
88
+ with ms.Slot("icon"):
89
+ antd.Icon("UserOutlined")
90
+ with ms.Slot("messageRender",
91
+ params_mapping="(content) => content"):
92
+ antd.Typography.Text(type="danger")
93
+ with antdx.Bubble.List.Role(
94
+ role="ai-suggestion",
95
+ placement="start",
96
+ variant="borderless",
97
+ avatar=dict(style=dict(visibility='hidden'))):
98
+ with ms.Slot("messageRender",
99
+ params_mapping="(items) => ({ items })"):
100
+ prompts = antdx.Prompts(vertical=True)
101
+
102
+ with antdx.Bubble.List.Role(
103
+ role="ai-file",
104
+ placement="start",
105
+ variant="borderless",
106
+ avatar=dict(style=dict(visibility='hidden'))):
107
+ with ms.Slot("messageRender",
108
+ params_mapping="""(content) => {
109
+ return {
110
+ each: content?.map(item => ({ item }))
111
+ }
112
+ }"""):
113
+ with antd.Flex(vertical=True, gap="middle"):
114
+ with ms.Each(as_item="each"):
115
+ antdx.Attachments.FileCard()
116
+
117
+ if __name__ == "__main__":
118
+ demo.queue().launch()
components/antdx/bubble/demos/typing_effect.py ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import modelscope_studio.components.antd as antd
3
+ import modelscope_studio.components.antdx as antdx
4
+ import modelscope_studio.components.base as ms
5
+
6
+ text = "Ant Design X love you! "
7
+
8
+
9
+ def repeat(state_value):
10
+ if state_value["repeat"] < 5:
11
+ state_value["repeat"] = state_value["repeat"] + 1
12
+ else:
13
+ state_value["repeat"] = 1
14
+ return gr.update(value=state_value), gr.update(
15
+ value=f"Repeat {state_value["repeat"]} Times"), gr.update(
16
+ content=text * state_value["repeat"]), gr.update(content=text * state_value["repeat"])
17
+
18
+
19
+ with gr.Blocks() as demo:
20
+ state = gr.State({"repeat": 1})
21
+ with ms.Application():
22
+ with antdx.XProvider():
23
+ antd.Typography.Paragraph("Enable typing output by setting the typing prop. If the updated content is a subset of the previous content, it will continue to output, otherwise it will output again.")
24
+ with antd.Flex(vertical=True, gap="small"):
25
+ with antdx.Bubble(content=text,
26
+ typing=dict(step=2, interval=50)) as bubble1:
27
+ with ms.Slot("avatar.icon"):
28
+ antd.Icon("UserOutlined")
29
+ with antdx.Bubble(content=text,
30
+ typing=dict(step=2, interval=50,
31
+ suffix="💗")) as bubble2:
32
+ with ms.Slot("avatar.icon"):
33
+ antd.Icon("UserOutlined")
34
+ btn = antd.Button("Repeat 1 Times",
35
+ elem_style=dict(alignSelf="flex-end"))
36
+ btn.click(fn=repeat,
37
+ inputs=[state],
38
+ outputs=[state, btn, bubble1, bubble2])
39
+
40
+ if __name__ == "__main__":
41
+ demo.queue().launch()
components/antdx/bubble/demos/variant.py ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import modelscope_studio.components.antd as antd
3
+ import modelscope_studio.components.antdx as antdx
4
+ import modelscope_studio.components.base as ms
5
+
6
+ with gr.Blocks() as demo:
7
+ with ms.Application():
8
+ with antdx.XProvider():
9
+ antd.Typography.Paragraph(
10
+ "Set the style variant of the bubble through the variant property."
11
+ )
12
+ with antd.Flex(vertical=True, gap="middle"):
13
+ with antdx.Bubble(variant="filled", content="variant: filled"):
14
+ with ms.Slot("avatar.icon"):
15
+ antd.Icon("UserOutlined")
16
+ with antdx.Bubble(variant="outlined",
17
+ content="variant: outlined"):
18
+ with ms.Slot("avatar.icon"):
19
+ antd.Icon("UserOutlined")
20
+ with antdx.Bubble(variant="shadow", content="variant: shadow"):
21
+ with ms.Slot("avatar.icon"):
22
+ antd.Icon("UserOutlined")
23
+ with antdx.Bubble(variant="borderless"):
24
+ with ms.Slot("avatar.icon"):
25
+ antd.Icon("UserOutlined")
26
+ with ms.Slot("content"):
27
+ with antdx.Prompts(
28
+ vertical=True,
29
+ title="variant: borderless to customize"):
30
+ with antdx.Prompts.Item(
31
+ key='1',
32
+ description=
33
+ 'How to rest effectively after long hours of work?'
34
+ ):
35
+ with ms.Slot("icon"):
36
+ antd.Icon("CoffeeOutlined",
37
+ elem_style={"color": '#964B00'})
38
+ with antdx.Prompts.Item(
39
+ key='2',
40
+ description=
41
+ 'What are the secrets to maintaining a positive mindset?',
42
+ ):
43
+ with ms.Slot("icon"):
44
+ antd.Icon("SmileOutlined",
45
+ elem_style={"color": '#FAAD14'})
46
+ with antdx.Prompts.Item(
47
+ key='3',
48
+ description=
49
+ 'How to stay calm under immense pressure?',
50
+ ):
51
+ with ms.Slot("icon"):
52
+ antd.Icon("FireOutlined",
53
+ elem_style={"color": '#FF4D4F'})
54
+
55
+ if __name__ == "__main__":
56
+ demo.queue().launch()
components/antdx/conversations/README-zh_CN.md ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ # Conversations
2
+
3
+ Used to manage and view the conversation list. See [Ant Design X](https://x.ant.design/components/conversations/) for more information.
4
+
5
+ ## Examples
6
+
7
+ <demo name="basic"></demo>
8
+ <demo name="operations" title="Operations"></demo>
9
+ <demo name="group" title="Group"></demo>
components/antdx/conversations/README.md ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ # Conversations
2
+
3
+ Used to manage and view the conversation list. See [Ant Design X](https://x.ant.design/components/conversations/) for more information.
4
+
5
+ ## Examples
6
+
7
+ <demo name="basic"></demo>
8
+ <demo name="operations" title="Operations"></demo>
9
+ <demo name="group" title="Group"></demo>
components/antdx/conversations/app.py ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ from helper.Docs import Docs
2
+
3
+ docs = Docs(__file__)
4
+
5
+ if __name__ == "__main__":
6
+ docs.render().queue().launch()
components/antdx/conversations/demos/basic.py ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import modelscope_studio.components.antd as antd
3
+ import modelscope_studio.components.antdx as antdx
4
+ import modelscope_studio.components.base as ms
5
+
6
+
7
+ def active_change(e: gr.EventData):
8
+ print(e._data["payload"])
9
+
10
+
11
+ with gr.Blocks() as demo:
12
+ with ms.Application():
13
+ with antdx.XProvider():
14
+ conversations1 = antdx.Conversations(default_active_key="item1",
15
+ items=[{
16
+ "key": "item1",
17
+ "label": "Item1"
18
+ }, {
19
+ "key": "item2",
20
+ "label": "Item2",
21
+ }, {
22
+ "key": "item3",
23
+ "label": "Item3",
24
+ }, {
25
+ "key": "item4",
26
+ "label": "Item4",
27
+ "disabled": True
28
+ }])
29
+
30
+ antd.Divider("Customized Item")
31
+
32
+ with antdx.Conversations(
33
+ default_active_key="item1") as conversations2:
34
+ with antdx.Conversations.Item(key="item1"):
35
+ with ms.Slot("label"):
36
+ antd.Typography.Text("Item1", type="success")
37
+ with ms.Slot("icon"):
38
+ antd.Icon()
39
+
40
+ with antdx.Conversations.Item(key="item2"):
41
+ with ms.Slot("label"):
42
+ antd.Typography.Text("Item2", type="success")
43
+ with ms.Slot("icon"):
44
+ antd.Icon()
45
+ conversations1.active_change(fn=active_change)
46
+ conversations2.active_change(fn=active_change)
47
+
48
+ if __name__ == "__main__":
49
+ demo.queue().launch()
components/antdx/conversations/demos/group.py ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import modelscope_studio.components.antdx as antdx
3
+ import modelscope_studio.components.base as ms
4
+
5
+ with gr.Blocks() as demo:
6
+ with ms.Application():
7
+ with antdx.XProvider():
8
+ conversations1 = antdx.Conversations(default_active_key="item1",
9
+ groupable=True,
10
+ items=[{
11
+ "key": "item1",
12
+ "label": "Item1",
13
+ "group": "Group1"
14
+ }, {
15
+ "key": "item2",
16
+ "label": "Item2",
17
+ "group": "Group1"
18
+ }, {
19
+ "key": "item3",
20
+ "label": "Item3",
21
+ "group": "Group2"
22
+ }, {
23
+ "key": "item4",
24
+ "label": "Item4",
25
+ "group": "Group2",
26
+ "disabled": True
27
+ }])
28
+
29
+ if __name__ == "__main__":
30
+ demo.queue().launch()
components/antdx/conversations/demos/operations.py ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import modelscope_studio.components.antd as antd
3
+ import modelscope_studio.components.antdx as antdx
4
+ import modelscope_studio.components.base as ms
5
+
6
+
7
+ def menu_click(e: gr.EventData):
8
+ print(e._data["payload"])
9
+
10
+
11
+ with gr.Blocks() as demo:
12
+ with ms.Application():
13
+ with antdx.XProvider():
14
+ with antdx.Conversations(default_active_key="item1",
15
+ items=[{
16
+ "key": "item1",
17
+ "label": "Item1"
18
+ }, {
19
+ "key": "item2",
20
+ "label": "Item2",
21
+ }, {
22
+ "key": "item3",
23
+ "label": "Item3",
24
+ }, {
25
+ "key": "item4",
26
+ "label": "Item4",
27
+ "disabled": True
28
+ }]) as conversations:
29
+ with ms.Slot("menu.items"):
30
+ with antd.Menu.Item(label="Operation 1", key="o1"):
31
+ with ms.Slot("icon"):
32
+ antd.Icon("EditOutlined")
33
+ with antd.Menu.Item(label="Operation 2",
34
+ key="o2",
35
+ disabled=True):
36
+ with ms.Slot("icon"):
37
+ antd.Icon("StopOutlined")
38
+ with antd.Menu.Item(label="Operation 3",
39
+ key="o3",
40
+ danger=True):
41
+ with ms.Slot("icon"):
42
+ antd.Icon("DeleteOutlined")
43
+ conversations.menu_click(fn=menu_click)
44
+
45
+ if __name__ == "__main__":
46
+ demo.queue().launch()
components/antdx/overview/README-zh_CN.md ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 概览
2
+
3
+ `modelscope_studio`集成了 [Ant Design X](https://x.ant.design/) 的组件,并支持大部分的组件属性,您只需要引入`antdx`模块即可直接使用。
4
+
5
+ ```python
6
+ import modelscope_studio.components.antdx as antdx
7
+ ```
8
+
9
+ ## 快速开始
10
+
11
+ <demo name="quick_start"></demo>
12
+
13
+ 注意:其中`ms.Application`与`antdx.XProvider`(或者`antd.ConfigProvider`)是必须的。
14
+
15
+ - `Application` 包含了`modelscope_studio`中所有的组件依赖,请确保`modelscope_studio`所有导出的组件都被其包裹,否则页面将会无法成功预览。
16
+ - `XProvider`(`ConfigProvider`) 与 Ant Design X(Ant Design)中的功能一致,除此之外,我们还加了一些额外的适配来兼容 Gradio 的样式。因此,为了保证页面样式正常,所有的`antdx`组件需要包裹在该组件下。
17
+
18
+ ## 其他
19
+
20
+ 同`Antd`组件。
components/antdx/overview/README.md ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Overview
2
+
3
+ `modelscope_studio` integrates [Ant Design X](https://x.ant.design/) components and supports most component properties. You can use them directly by importing the `antdx` module.
4
+
5
+ ```python
6
+ import modelscope_studio.components.antdx as antdx
7
+ ```
8
+
9
+ ## Quick Start
10
+
11
+ <demo name="quick_start"></demo>
12
+
13
+ Note: Both `ms.Application` and `antdx.XProvider`(or `antd.ConfigProvider`) are required.
14
+
15
+ - `Application` contains all component dependencies in `modelscope_studio`. Please ensure that all components exported from `modelscope_studio` are wrapped by it, otherwise the page will not be successfully previewed.
16
+ - `XProvider`(`ConfigProvider`) functions the same as in Ant Design X(Ant Design). Additionally, we have added some extra adaptations to be compatible with Gradio's styles. Therefore, to ensure normal page styling, all `antdx` components need to be wrapped within this component.
17
+
18
+ ## Others
19
+
20
+ Same as `Antd` components.
components/antdx/overview/app.py ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ from helper.Docs import Docs
2
+
3
+ docs = Docs(__file__)
4
+
5
+ if __name__ == "__main__":
6
+ docs.render().queue().launch()
components/antdx/overview/demos/quick_start.py ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import modelscope_studio.components.antdx as antdx
3
+ import modelscope_studio.components.base as ms
4
+
5
+ with gr.Blocks() as demo:
6
+ with ms.Application():
7
+ with antdx.XProvider(): # or antd.ConfigProvider
8
+ antdx.Welcome(
9
+ icon=
10
+ "https://mdn.alipayobjects.com/huamei_iwk9zp/afts/img/A*s5sNRo5LjfQAAAAAAAAAAAAADgCCAQ/fmt.webp",
11
+ title="Hello, I'm Ant Design X",
12
+ description=
13
+ "Base on Ant Design, AGI product interface solution, create a better intelligent vision~"
14
+ )
15
+
16
+ if __name__ == "__main__":
17
+ demo.queue().launch()
components/antdx/prompts/README-zh_CN.md ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ # Prompts
2
+
3
+ Display a predefined set of questions or suggestion. See [Ant Design X](https://x.ant.design/components/prompts/) for more information.
4
+
5
+ ## Examples
6
+
7
+ <demo name="basic"></demo>
8
+ <demo name="nest_usage" title="Nest Usage"></demo>
components/antdx/prompts/README.md ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ # Prompts
2
+
3
+ Display a predefined set of questions or suggestion. See [Ant Design X](https://x.ant.design/components/prompts/) for more information.
4
+
5
+ ## Examples
6
+
7
+ <demo name="basic"></demo>
8
+ <demo name="nest_usage" title="Nest Usage"></demo>
components/antdx/prompts/app.py ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ from helper.Docs import Docs
2
+
3
+ docs = Docs(__file__)
4
+
5
+ if __name__ == "__main__":
6
+ docs.render().queue().launch()
components/antdx/prompts/demos/basic.py ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import modelscope_studio.components.antd as antd
3
+ import modelscope_studio.components.antdx as antdx
4
+ import modelscope_studio.components.base as ms
5
+
6
+
7
+ def item_click(e: gr.EventData):
8
+ payload = e._data["payload"]
9
+ gr.Info("You clicked on item " + payload[0]["data"]["key"])
10
+
11
+
12
+ default_vertical = False
13
+ default_wrap = False
14
+
15
+ with gr.Blocks() as demo:
16
+ with ms.Application():
17
+ with antdx.XProvider():
18
+ vertical = antd.Switch(value=default_vertical,
19
+ checked_children="Vertical",
20
+ un_checked_children="Horizontal")
21
+ wrap = antd.Switch(value=default_wrap,
22
+ checked_children="Wrap",
23
+ un_checked_children="No Wrap")
24
+ with antdx.Prompts(
25
+ title="✨ Inspirational Sparks and Marvelous Tips",
26
+ wrap=default_wrap,
27
+ vertical=default_vertical) as prompts:
28
+ with antdx.Prompts.Item(
29
+ key='1',
30
+ label='Ignite Your Creativity',
31
+ description='Got any sparks for a new project?',
32
+ disabled=True):
33
+ with ms.Slot("icon"):
34
+ antd.Icon("BulbOutlined",
35
+ elem_style={"color": '#FFD700'})
36
+ with antdx.Prompts.Item(
37
+ key='2',
38
+ label='Uncover Background Info',
39
+ description=
40
+ 'Help me understand the background of this topic.',
41
+ ):
42
+ with ms.Slot("icon"):
43
+ antd.Icon("InfoCircleOutlined",
44
+ elem_style={"color": '#1890FF'})
45
+ with antdx.Prompts.Item(
46
+ key='3',
47
+ label='Efficiency Boost Battle',
48
+ description='How can I work faster and better?',
49
+ ):
50
+ with ms.Slot("icon"):
51
+ antd.Icon("RocketOutlined",
52
+ elem_style={"color": '#722ED1'})
53
+ with antdx.Prompts.Item(
54
+ key='4',
55
+ label='Tell me a Joke',
56
+ description=
57
+ 'Why do not ants get sick? Because they have tiny ant-bodies!',
58
+ ):
59
+ with ms.Slot("icon"):
60
+ antd.Icon("SmileOutlined",
61
+ elem_style={"color": '#52C41A'})
62
+ with antdx.Prompts.Item(
63
+ key='5',
64
+ label='Common Issue Solutions',
65
+ description=
66
+ 'How to solve common issues? Share some tips!',
67
+ ):
68
+ with ms.Slot("icon"):
69
+ antd.Icon("WarningOutlined",
70
+ elem_style={"color": '#FF4D4F'})
71
+
72
+ prompts.item_click(fn=item_click)
73
+ vertical.change(fn=lambda x: gr.update(vertical=x),
74
+ inputs=[vertical],
75
+ outputs=[prompts])
76
+ wrap.change(fn=lambda x: gr.update(wrap=x),
77
+ inputs=[wrap],
78
+ outputs=[prompts])
79
+
80
+ if __name__ == "__main__":
81
+ demo.queue().launch()
components/antdx/prompts/demos/nest_usage.py ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import modelscope_studio.components.antd as antd
3
+ import modelscope_studio.components.antdx as antdx
4
+ import modelscope_studio.components.base as ms
5
+
6
+
7
+ def item_click(e: gr.EventData):
8
+ payload = e._data["payload"]
9
+ gr.Info("You clicked on item " + payload[0]["data"]["key"])
10
+
11
+
12
+ with gr.Blocks() as demo:
13
+ with ms.Application():
14
+ with antdx.XProvider(theme=dict(algorithm=dict(dark=False))):
15
+ with antd.Card(elem_style=dict(borderRadius=0, border=0)):
16
+ with antdx.Prompts(
17
+ title="Do you want?",
18
+ wrap=True,
19
+ styles=dict(item={
20
+ "flex": 'none',
21
+ "width": 'calc(30% - 6px)',
22
+ "backgroundImage":
23
+ "linear-gradient(137deg, #e5f4ff 0%, #efe7ff 100%)",
24
+ "border": 0,
25
+ },
26
+ subItem={
27
+ "background": 'rgba(255,255,255,0.45)',
28
+ "border": '1px solid #FFF',
29
+ })) as prompts:
30
+ with antdx.Prompts.Item(
31
+ key='1',
32
+ description='What are you interested in?',
33
+ ):
34
+ with ms.Slot("label"):
35
+ with antd.Space():
36
+ antd.Icon("FireOutlined",
37
+ elem_style={"color": '#FF4D4F'})
38
+ ms.Text("Hot Topics")
39
+ antdx.Prompts.Item(key="1-1",
40
+ description="What's new in X?")
41
+ antdx.Prompts.Item(key="1-2",
42
+ description="What's AGI?")
43
+ antdx.Prompts.Item(key="1-3",
44
+ description="Where is the doc?")
45
+ with antdx.Prompts.Item(
46
+ key='2',
47
+ description='How to design a good product?',
48
+ ):
49
+ with ms.Slot("label"):
50
+ with antd.Space():
51
+ antd.Icon("ReadOutlined",
52
+ elem_style={"color": '#1890FF'})
53
+ ms.Text("Design Guide")
54
+ with antdx.Prompts.Item(key="2-1",
55
+ description="Know the well"):
56
+ with ms.Slot("icon"):
57
+ antd.Icon("HeartOutlined")
58
+ with antdx.Prompts.Item(key="2-2",
59
+ description="Set the AI role"):
60
+ with ms.Slot("icon"):
61
+ antd.Icon("SmileOutlined")
62
+ with antdx.Prompts.Item(
63
+ key="2-3", description="Express the feeling"):
64
+ with ms.Slot("icon"):
65
+ antd.Icon("CommentOutlined")
66
+ with antdx.Prompts.Item(
67
+ key='3',
68
+ description='How to start a new project?',
69
+ ):
70
+ with ms.Slot("label"):
71
+ with antd.Space():
72
+ antd.Icon("RocketOutlined",
73
+ elem_style={"color": '#722ED1'})
74
+ ms.Text("Start Creating")
75
+ antdx.Prompts.Item(key="3-1",
76
+ label='Fast Start',
77
+ description="Install Ant Design X")
78
+ antdx.Prompts.Item(
79
+ key="3-2",
80
+ label='Online Playground',
81
+ description="Play on the web without installing")
82
+
83
+ prompts.item_click(fn=item_click)
84
+
85
+ if __name__ == "__main__":
86
+ demo.queue().launch()
components/antdx/welcome/README-zh_CN.md ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ # Welcome
2
+
3
+ Clearly convey the scope of intent and expected functionality to the user. See [Ant Design X](https://x.ant.design/components/welcome/) for more information.
4
+
5
+ ## Examples
6
+
7
+ <demo name="basic"></demo>
components/antdx/welcome/README.md ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ # Welcome
2
+
3
+ Clearly convey the scope of intent and expected functionality to the user. See [Ant Design X](https://x.ant.design/components/welcome/) for more information.
4
+
5
+ ## Examples
6
+
7
+ <demo name="basic"></demo>
components/antdx/welcome/app.py ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ from helper.Docs import Docs
2
+
3
+ docs = Docs(__file__)
4
+
5
+ if __name__ == "__main__":
6
+ docs.render().queue().launch()
components/antdx/welcome/demos/basic.py ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import modelscope_studio.components.antd as antd
3
+ import modelscope_studio.components.antdx as antdx
4
+ import modelscope_studio.components.base as ms
5
+
6
+ with gr.Blocks() as demo:
7
+ with ms.Application():
8
+ with antdx.XProvider():
9
+ antdx.Welcome(
10
+ icon=
11
+ "https://mdn.alipayobjects.com/huamei_iwk9zp/afts/img/A*s5sNRo5LjfQAAAAAAAAAAAAADgCCAQ/fmt.webp",
12
+ title="Hello, I'm Ant Design X",
13
+ description=
14
+ "Base on Ant Design, AGI product interface solution, create a better intelligent vision~"
15
+ )
16
+
17
+ antd.Divider("Borderless")
18
+
19
+ with antdx.Welcome(
20
+ icon=
21
+ "https://mdn.alipayobjects.com/huamei_iwk9zp/afts/img/A*s5sNRo5LjfQAAAAAAAAAAAAADgCCAQ/fmt.webp",
22
+ title="Hello, I'm Ant Design X",
23
+ description=
24
+ "Base on Ant Design, AGI product interface solution, create a better intelligent vision~",
25
+ variant="borderless"):
26
+ with ms.Slot("extra"):
27
+ with antd.Space():
28
+ with antd.Button(None):
29
+ with ms.Slot("icon"):
30
+ antd.Icon("ShareAltOutlined")
31
+ with antd.Button(None):
32
+ with ms.Slot("icon"):
33
+ antd.Icon("EllipsisOutlined")
34
+
35
+ if __name__ == "__main__":
36
+ demo.queue().launch()
helper/Docs.py CHANGED
@@ -78,6 +78,8 @@ class Docs:
78
  demo_name,
79
  prefix='',
80
  suffix='',
 
 
81
  fixed=False,
82
  title=''):
83
  content = self._read_file(f"./demos/{demo_name}.py")
@@ -87,38 +89,49 @@ class Docs:
87
  if title:
88
  with ms.Slot("title"):
89
  ms.Text(title)
90
- with antd.Row(align="stretch", wrap=True, gutter=8):
91
- with antd.Col(sm=dict(span=10, order=1),
 
92
  xs=dict(span=24, order=2)):
93
- with antd.Row(elem_style=dict(height='100%'),
94
- gutter=[8, 8]):
95
- with antd.Col(sm=0, xs=24):
96
- antd.Divider(type="horizontal",
97
- variant="dashed",
98
- elem_style=dict(width='100%',
99
- margin='8px 0 0'))
100
- with antd.Col(sm=23, xs=24):
101
- prefix = prefix + "\n" if prefix else ""
102
- suffix = "\n" + suffix if suffix else ""
103
- ms.Markdown(f"""{prefix}```python
104
- {content}
105
- ```{suffix}""",
106
- header_links=True)
107
-
108
- with antd.Col(sm=1,
109
- xs=0,
110
- elem_style=dict(height="100%")):
111
- with ms.Div(
112
- elem_style=dict(display="flex",
113
- justifyContent="center",
114
- width="100%",
115
- height="100%")):
116
- antd.Divider(type="vertical",
117
  variant="dashed",
118
- elem_style=dict(height='100%',
119
- margin=0))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
120
  with antd.Col(
121
- sm=dict(span=14, order=2),
 
122
  xs=dict(span=24, order=1),
123
  elem_style=dict(
124
  width='100%',
@@ -136,9 +149,19 @@ class Docs:
136
  self._render_demo(item["name"],
137
  prefix=item["prefix"],
138
  suffix=item["suffix"],
 
 
139
  fixed=item["fixed"],
140
  title=item["title"])
141
 
 
 
 
 
 
 
 
 
142
  def render(self):
143
  with gr.Blocks() as demo:
144
  self._render_markdown(self.markdown_files[0])
 
78
  demo_name,
79
  prefix='',
80
  suffix='',
81
+ position="left",
82
+ collapsible=False,
83
  fixed=False,
84
  title=''):
85
  content = self._read_file(f"./demos/{demo_name}.py")
 
89
  if title:
90
  with ms.Slot("title"):
91
  ms.Text(title)
92
+ with antd.Row(align="stretch", wrap=True, gutter=[8, 8]):
93
+ with antd.Col(sm=dict(span=24 if position == "bottom" else 10,
94
+ order=2 if position == "bottom" else 1),
95
  xs=dict(span=24, order=2)):
96
+
97
+ def render_code():
98
+ with antd.Row(elem_style=dict(height='100%'),
99
+ gutter=[8, 8]):
100
+ with antd.Col(sm=0, xs=24):
101
+ antd.Divider(type="horizontal",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  variant="dashed",
103
+ elem_style=dict(width='100%',
104
+ margin='8px 0 0'))
105
+ with antd.Col(sm=23, xs=24):
106
+ ms.Markdown(
107
+ f"""{prefix + "\n" if prefix else ""}```python
108
+ {content}
109
+ ```{"\n" + suffix if suffix else ""}""",
110
+ header_links=True)
111
+
112
+ with antd.Col(sm=1,
113
+ xs=0,
114
+ elem_style=dict(height="100%")):
115
+ with ms.Div(elem_style=dict(
116
+ display="flex",
117
+ justifyContent="center",
118
+ width="100%",
119
+ height="100%")):
120
+ antd.Divider(type="vertical",
121
+ variant="dashed",
122
+ elem_style=dict(height='100%',
123
+ margin=0))
124
+
125
+ if collapsible:
126
+ with antd.Collapse():
127
+ with antd.Collapse.Item(label="Show Code",
128
+ key="code"):
129
+ render_code()
130
+ else:
131
+ render_code()
132
  with antd.Col(
133
+ sm=dict(span=24 if position == "bottom" else 14,
134
+ order=1 if position == "bottom" else 2),
135
  xs=dict(span=24, order=1),
136
  elem_style=dict(
137
  width='100%',
 
149
  self._render_demo(item["name"],
150
  prefix=item["prefix"],
151
  suffix=item["suffix"],
152
+ position=item["position"],
153
+ collapsible=item["collapsible"],
154
  fixed=item["fixed"],
155
  title=item["title"])
156
 
157
+ def get_css(self):
158
+ css = ""
159
+ for demo_name in self.demo_modules:
160
+ module = self.demo_modules[demo_name]
161
+ if hasattr(module, "css"):
162
+ css += module.css
163
+ return css
164
+
165
  def render(self):
166
  with gr.Blocks() as demo:
167
  self._render_markdown(self.markdown_files[0])
helper/Site.py CHANGED
@@ -52,7 +52,12 @@ class Site:
52
  item: gr.update(visible=True)
53
  }
54
 
55
- with gr.Blocks(css="""
 
 
 
 
 
56
  .gradio-container {
57
  max-width: 100% !important;
58
  padding: 0 !important;
 
52
  item: gr.update(visible=True)
53
  }
54
 
55
+ # Css is not working in demo if there are multiple Blocks, so we need to add css from demos
56
+ css = ""
57
+ for category in self.docs:
58
+ for component in self.docs[category]:
59
+ css += self.docs[category][component].get_css()
60
+ with gr.Blocks(css=css + """
61
  .gradio-container {
62
  max-width: 100% !important;
63
  padding: 0 !important;
helper/parse_markdown.py CHANGED
@@ -47,6 +47,8 @@ class MarkdownParser(HTMLParser):
47
  "fixed": "fixed" in dict(attrs),
48
  "prefix": "",
49
  "suffix": "",
 
 
50
  "title": dict(attrs).get("title", "")
51
  })
52
  elif tag == "file":
 
47
  "fixed": "fixed" in dict(attrs),
48
  "prefix": "",
49
  "suffix": "",
50
+ "position": dict(attrs).get("position", "left"),
51
+ "collapsible": "collapsible" in dict(attrs),
52
  "title": dict(attrs).get("title", "")
53
  })
54
  elif tag == "file":
layout_templates/coder_artifacts/README-zh_CN.md ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ # Coder Artifacts
2
+
3
+ 用于构建代码生成界面的应用模板。
4
+
5
+ ## 示例
6
+
7
+ <demo name="app" position="bottom" collapsible="true"></demo>
layout_templates/coder_artifacts/README.md ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ # Coder Artifacts
2
+
3
+ Application template for building code generation interfaces.
4
+
5
+ ## Examples
6
+
7
+ <demo name="app" position="bottom" collapsible="true"></demo>
layout_templates/coder_artifacts/app.py ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ from helper.Docs import Docs
2
+
3
+ docs = Docs(__file__)
4
+
5
+ if __name__ == "__main__":
6
+ docs.render().queue().launch()
layout_templates/coder_artifacts/demos/app.py ADDED
@@ -0,0 +1,446 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import base64
2
+ import os
3
+ import re
4
+
5
+ import gradio as gr
6
+ import modelscope_studio.components.antd as antd
7
+ import modelscope_studio.components.base as ms
8
+ from openai import OpenAI
9
+
10
+ # =========== Configuration
11
+
12
+ # API KEY
13
+ MODELSCOPE_ACCESS_TOKEN = os.getenv('MODELSCOPE_ACCESS_TOKEN')
14
+
15
+ client = OpenAI(api_key=MODELSCOPE_ACCESS_TOKEN,
16
+ base_url="https://api-inference.modelscope.cn/v1")
17
+
18
+ # =========== Configuration
19
+
20
+ DEFAULT_SYSTEM_PROMPT = """You are a web development engineer, writing web pages according to the instructions below. You are a powerful code editing assistant capable of writing code and creating artifacts in conversations with users, or modifying and updating existing artifacts as requested by users.
21
+ All code is written in a single code block to form a complete code file for display, without separating HTML and JavaScript code. An artifact refers to a runnable complete code snippet, you prefer to integrate and output such complete runnable code rather than breaking it down into several code blocks. For certain types of code, they can render graphical interfaces in a UI window. After generation, please check the code execution again to ensure there are no errors in the output.
22
+ Output only the HTML, without any additional descriptive text."""
23
+
24
+ EXAMPLES = [
25
+ {
26
+ "title":
27
+ "Qwen,Start!",
28
+ "description":
29
+ "Help me design an interface with a purple button that says 'Qwen, Start!'. When the button is clicked, display a countdown from 5 in a very large font for 5 seconds.",
30
+ },
31
+ {
32
+ "title":
33
+ "Spam with emojis!",
34
+ "description":
35
+ "Write code in a single HTML file: Capture the click event, place a random number of emojis at the click position, and add gravity and collision effects to each emoji."
36
+ },
37
+ {
38
+ "title":
39
+ "TODO list",
40
+ "description":
41
+ "I want a TODO list that allows me to add tasks, delete tasks, and I would like the overall color theme to be purple."
42
+ },
43
+ ]
44
+
45
+ DEFAULT_LOCALE = 'en_US'
46
+
47
+ DEFAULT_THEME = {
48
+ "token": {
49
+ "colorPrimary": "#6A57FF",
50
+ }
51
+ }
52
+
53
+
54
+ class GradioEvents:
55
+
56
+ @staticmethod
57
+ def generate_code(input_value, system_prompt_input_value, state_value):
58
+ # Define your code here
59
+
60
+ def remove_code_block(text):
61
+ pattern = r'```html\n(.+?)\n```'
62
+ match = re.search(pattern, text, re.DOTALL)
63
+ if match:
64
+ return match.group(1).strip()
65
+ else:
66
+ return text.strip()
67
+
68
+ def send_to_sandbox(code):
69
+ encoded_html = base64.b64encode(
70
+ code.encode('utf-8')).decode('utf-8')
71
+ data_uri = f"data:text/html;charset=utf-8;base64,{encoded_html}"
72
+ return f"<iframe src=\"{data_uri}\" width=\"100%\" height=\"100%\"></iframe>"
73
+
74
+ yield {
75
+ output_loading: gr.update(spinning=True),
76
+ state_tab: gr.update(active_key="loading"),
77
+ output: gr.update(value=None)
78
+ }
79
+
80
+ if input_value is None:
81
+ input_value = ''
82
+
83
+ messages = [{
84
+ 'role': "system",
85
+ 'content': system_prompt_input_value
86
+ }] + state_value["history"]
87
+
88
+ messages.append({'role': "user", 'content': input_value})
89
+
90
+ generator = client.chat.completions.create(
91
+ model="Qwen/Qwen2.5-Coder-32B-Instruct",
92
+ messages=messages,
93
+ stream=True)
94
+ response = ""
95
+ for chunk in generator:
96
+ content = chunk.choices[0].delta.content
97
+ response += content
98
+ if chunk.choices[0].finish_reason == 'stop':
99
+ state_value["history"] = messages + [{
100
+ 'role': "assistant",
101
+ 'content': response
102
+ }]
103
+ # Completed
104
+ yield {
105
+ output:
106
+ gr.update(value=response),
107
+ download_content:
108
+ gr.update(value=remove_code_block(response)),
109
+ state_tab:
110
+ gr.update(active_key="render"),
111
+ output_loading:
112
+ gr.update(spinning=False),
113
+ sandbox:
114
+ gr.update(
115
+ value=send_to_sandbox(remove_code_block(response))),
116
+ state:
117
+ gr.update(value=state_value)
118
+ }
119
+
120
+ else:
121
+ # Generating
122
+ yield {
123
+ output: gr.update(value=response),
124
+ output_loading: gr.update(spinning=False),
125
+ }
126
+
127
+ @staticmethod
128
+ def select_example(example: dict):
129
+ return lambda: gr.update(value=example["description"])
130
+
131
+ @staticmethod
132
+ def close_modal():
133
+ return gr.update(open=False)
134
+
135
+ @staticmethod
136
+ def open_modal():
137
+ return gr.update(open=True)
138
+
139
+ @staticmethod
140
+ def disable_btns(btns: list):
141
+ return lambda: [gr.update(disabled=True) for _ in btns]
142
+
143
+ @staticmethod
144
+ def enable_btns(btns: list):
145
+ return lambda: [gr.update(disabled=False) for _ in btns]
146
+
147
+ @staticmethod
148
+ def update_system_prompt(system_prompt_input_value, state_value):
149
+ state_value["system_prompt"] = system_prompt_input_value
150
+ return gr.update(value=state_value)
151
+
152
+ @staticmethod
153
+ def reset_system_prompt(state_value):
154
+ return gr.update(value=state_value["system_prompt"])
155
+
156
+ @staticmethod
157
+ def render_history(state):
158
+ return gr.update(value=state["history"])
159
+
160
+ @staticmethod
161
+ def clear_history(e: gr.EventData, state_value):
162
+ item = e._data["payload"][0]["key"]
163
+ if item == "clear":
164
+ gr.Success("History Cleared.")
165
+ state_value["history"] = []
166
+ return gr.update(value=state_value)
167
+ return gr.skip()
168
+
169
+
170
+ css = """
171
+ #coder-artifacts .output-empty,.output-loading {
172
+ display: flex;
173
+ flex-direction: column;
174
+ align-items: center;
175
+ justify-content: center;
176
+ width: 100%;
177
+ min-height: 680px;
178
+ }
179
+
180
+ #coder-artifacts .output-html {
181
+ display: flex;
182
+ flex-direction: column;
183
+ width: 100%;
184
+ min-height: 680px;
185
+ }
186
+
187
+ #coder-artifacts .output-html > iframe {
188
+ flex: 1;
189
+ }
190
+
191
+ #code-artifacts-code-drawer .output-code {
192
+ flex:1;
193
+ }
194
+ #code-artifacts-code-drawer .output-code .ms-gr-ant-spin-nested-loading {
195
+ min-height: 100%;
196
+ }
197
+ """
198
+
199
+ with gr.Blocks(css=css) as demo:
200
+ # Global State
201
+ state = gr.State({"system_prompt": DEFAULT_SYSTEM_PROMPT, "history": []})
202
+ with ms.Application(elem_id="coder-artifacts") as app:
203
+ with antd.ConfigProvider(theme=DEFAULT_THEME, locale=DEFAULT_LOCALE):
204
+ # Header
205
+ with antd.Flex(justify="center", align="center", gap="middle"):
206
+ antd.Typography.Title("Coder-Artifacts",
207
+ level=1,
208
+ elem_style=dict(fontSize=24))
209
+ with ms.AutoLoading():
210
+ with antd.Row(gutter=[32, 12],
211
+ elem_style=dict(marginTop=20),
212
+ align="stretch"):
213
+ # Left Column
214
+ with antd.Col(span=24, md=8):
215
+ with antd.Flex(vertical=True, gap="middle", wrap=True):
216
+ # Input
217
+ input = antd.Input.Textarea(
218
+ size="large",
219
+ allow_clear=True,
220
+ auto_size=dict(minRows=2, maxRows=6),
221
+ placeholder=
222
+ "Describe the web application you want to create",
223
+ elem_id="input-container")
224
+ # Input Notes
225
+ with antd.Flex(align="center",
226
+ justify="space-between"):
227
+ antd.Typography.Text(
228
+ "Note: The model supports multi-round dialogue.",
229
+ strong=True,
230
+ type="warning")
231
+
232
+ tour_btn = antd.Button("Usage Tour",
233
+ variant="filled",
234
+ color="default")
235
+ # Submit Button
236
+ submit_btn = antd.Button("Submit",
237
+ type="primary",
238
+ block=True,
239
+ size="large",
240
+ elem_id="submit-btn")
241
+
242
+ antd.Divider("Settings")
243
+
244
+ # Settings Area
245
+ with antd.Space(size="small",
246
+ wrap=True,
247
+ elem_id="settings-area"):
248
+ system_prompt_btn = antd.Button(
249
+ "⚙️ Set System Prompt", type="default")
250
+ history_btn = antd.Dropdown.Button(
251
+ "📜 History",
252
+ type="default",
253
+ elem_id="history-btn",
254
+ menu=dict(items=[{
255
+ "key": "clear",
256
+ "label": "Clear History",
257
+ "danger": True
258
+ }]))
259
+
260
+ antd.Divider("Examples")
261
+
262
+ # Examples
263
+ with antd.Flex(gap="small", wrap=True):
264
+ for example in EXAMPLES:
265
+ with antd.Card(
266
+ hoverable=True) as example_card:
267
+ antd.Card.Meta(
268
+ title=example['title'],
269
+ description=example['description'])
270
+
271
+ example_card.click(
272
+ fn=GradioEvents.select_example(
273
+ example),
274
+ outputs=[input])
275
+
276
+ # Right Column
277
+ with antd.Col(span=24, md=16):
278
+ with antd.Card(title="Output",
279
+ elem_style=dict(height="100%"),
280
+ styles=dict(body=dict(height="100%")),
281
+ elem_id="output-container"):
282
+ # Output Container Extra
283
+ with ms.Slot("extra"):
284
+ with ms.Div(elem_id="output-container-extra"):
285
+ with antd.Button(
286
+ "Download HTML",
287
+ type="link",
288
+ href_target="_blank",
289
+ disabled=True,
290
+ ) as download_btn:
291
+ with ms.Slot("icon"):
292
+ antd.Icon("DownloadOutlined")
293
+ download_content = gr.Text(visible=False)
294
+
295
+ view_code_btn = antd.Button(
296
+ "🧑‍💻 View Code", type="primary")
297
+ # Output Content
298
+ with antd.Tabs(
299
+ active_key="empty",
300
+ render_tab_bar="() => null") as state_tab:
301
+ with antd.Tabs.Item(key="empty"):
302
+ antd.Empty(
303
+ description=
304
+ "Enter your request to generate code",
305
+ elem_classes="output-empty")
306
+ with antd.Tabs.Item(key="loading"):
307
+ with antd.Spin(
308
+ tip="Generating code...",
309
+ size="large",
310
+ elem_classes="output-loading"):
311
+ # placeholder
312
+ ms.Div()
313
+ with antd.Tabs.Item(key="render"):
314
+ sandbox = gr.HTML(
315
+ elem_classes="output-html")
316
+
317
+ # Modals and Drawers
318
+ with antd.Modal(open=False,
319
+ title="System Prompt",
320
+ width="800px") as system_prompt_modal:
321
+ system_prompt_input = antd.Input.Textarea(
322
+ DEFAULT_SYSTEM_PROMPT,
323
+ size="large",
324
+ placeholder="Enter your system prompt here",
325
+ allow_clear=True,
326
+ auto_size=dict(minRows=4, maxRows=14))
327
+
328
+ with antd.Drawer(
329
+ open=False,
330
+ title="Output Code",
331
+ placement="right",
332
+ get_container=
333
+ "() => document.querySelector('.gradio-container')",
334
+ elem_id="code-artifacts-code-drawer",
335
+ styles=dict(
336
+ body=dict(display="flex",
337
+ flexDirection="column-reverse")),
338
+ width="750px") as output_code_drawer:
339
+ with ms.Div(elem_classes="output-code"):
340
+ with antd.Spin(spinning=False) as output_loading:
341
+ output = ms.Markdown()
342
+
343
+ with antd.Drawer(
344
+ open=False,
345
+ title="Chat History",
346
+ placement="left",
347
+ get_container=
348
+ "() => document.querySelector('.gradio-container')",
349
+ width="750px") as history_drawer:
350
+ history_output = gr.Chatbot(
351
+ show_label=False,
352
+ type="messages",
353
+ height='100%',
354
+ elem_classes="history_chatbot")
355
+ # Tour
356
+ with antd.Tour(open=False) as usage_tour:
357
+ antd.Tour.Step(
358
+ title="Step 1",
359
+ description=
360
+ "Describe the web application you want to create.",
361
+ get_target=
362
+ "() => document.querySelector('#input-container')")
363
+ antd.Tour.Step(
364
+ title="Step 2",
365
+ description="Click the submit button.",
366
+ get_target=
367
+ "() => document.querySelector('#submit-btn')")
368
+ antd.Tour.Step(
369
+ title="Step 3",
370
+ description="Wait for the result.",
371
+ get_target=
372
+ "() => document.querySelector('#output-container')"
373
+ )
374
+ antd.Tour.Step(
375
+ title="Step 4",
376
+ description=
377
+ "Download the generated HTML here or view the code.",
378
+ get_target=
379
+ "() => document.querySelector('#output-container-extra')"
380
+ )
381
+ antd.Tour.Step(
382
+ title="Additional Settings",
383
+ description=
384
+ "You can change the system prompt or chat history here.",
385
+ get_target=
386
+ "() => document.querySelector('#settings-area')")
387
+ # Event Handler
388
+ gr.on(fn=GradioEvents.close_modal,
389
+ triggers=[usage_tour.close, usage_tour.finish],
390
+ outputs=[usage_tour])
391
+ tour_btn.click(fn=GradioEvents.open_modal, outputs=[usage_tour])
392
+
393
+ system_prompt_btn.click(fn=GradioEvents.open_modal,
394
+ outputs=[system_prompt_modal])
395
+
396
+ system_prompt_modal.ok(GradioEvents.update_system_prompt,
397
+ inputs=[system_prompt_input, state],
398
+ outputs=[state]).then(fn=GradioEvents.close_modal,
399
+ outputs=[system_prompt_modal])
400
+
401
+ system_prompt_modal.cancel(GradioEvents.close_modal,
402
+ outputs=[system_prompt_modal]).then(
403
+ fn=GradioEvents.reset_system_prompt,
404
+ inputs=[state],
405
+ outputs=[system_prompt_input])
406
+ output_code_drawer.close(fn=GradioEvents.close_modal,
407
+ outputs=[output_code_drawer])
408
+ history_btn.menu_click(fn=GradioEvents.clear_history,
409
+ inputs=[state],
410
+ outputs=[state])
411
+ history_btn.click(fn=GradioEvents.open_modal,
412
+ outputs=[history_drawer
413
+ ]).then(fn=GradioEvents.render_history,
414
+ inputs=[state],
415
+ outputs=[history_output])
416
+ history_drawer.close(fn=GradioEvents.close_modal, outputs=[history_drawer])
417
+
418
+ download_btn.click(fn=None,
419
+ inputs=[download_content],
420
+ js="""(content) => {
421
+ const blob = new Blob([content], { type: 'text/html' })
422
+ const url = URL.createObjectURL(blob)
423
+ const a = document.createElement('a')
424
+ a.href = url
425
+ a.download = 'output.html'
426
+ a.click()
427
+ }""")
428
+ view_code_btn.click(fn=GradioEvents.open_modal,
429
+ outputs=[output_code_drawer])
430
+ submit_btn.click(
431
+ fn=GradioEvents.open_modal,
432
+ outputs=[output_code_drawer],
433
+ ).then(fn=GradioEvents.disable_btns([submit_btn, download_btn]),
434
+ outputs=[submit_btn, download_btn]).then(
435
+ fn=GradioEvents.generate_code,
436
+ inputs=[input, system_prompt_input, state],
437
+ outputs=[
438
+ output, state_tab, sandbox, download_content,
439
+ output_loading, state
440
+ ]).then(fn=GradioEvents.enable_btns([submit_btn, download_btn]),
441
+ outputs=[submit_btn, download_btn
442
+ ]).then(fn=GradioEvents.close_modal,
443
+ outputs=[output_code_drawer])
444
+
445
+ if __name__ == "__main__":
446
+ demo.queue().launch(ssr_mode=False)
requirements.txt CHANGED
@@ -1 +1,2 @@
1
- modelscope_studio==1.1.0
 
 
1
+ modelscope_studio==1.1.1
2
+ openai
src/pyproject.toml CHANGED
@@ -8,7 +8,7 @@ build-backend = "hatchling.build"
8
 
9
  [project]
10
  name = "modelscope_studio"
11
- version = "1.1.0"
12
  description = "A third-party component library based on Gradio."
13
  readme = "README.md"
14
  license = "Apache-2.0"
@@ -226,6 +226,9 @@ artifacts = [
226
  "/backend/modelscope_studio/components/antdx/x_provider/templates",
227
  ]
228
 
 
 
 
229
  [tool.hatch.build.targets.sdist]
230
  exclude = ["__pycache__"]
231
  include = ["/backend/modelscope_studio"]
 
8
 
9
  [project]
10
  name = "modelscope_studio"
11
+ version = "1.1.1"
12
  description = "A third-party component library based on Gradio."
13
  readme = "README.md"
14
  license = "Apache-2.0"
 
226
  "/backend/modelscope_studio/components/antdx/x_provider/templates",
227
  ]
228
 
229
+ [tool.yapfignore]
230
+ ignore_patterns = ["node_modules/**", "__pycache__/**", "**/*.pyi"]
231
+
232
  [tool.hatch.build.targets.sdist]
233
  exclude = ["__pycache__"]
234
  include = ["/backend/modelscope_studio"]