@agentscope-ai/chat 1.1.59 → 1.1.60
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/starter_webui/README.md +75 -0
- package/bin/starter_webui/eslint.config.js +28 -0
- package/bin/starter_webui/index.html +12 -0
- package/bin/starter_webui/package.json +34 -0
- package/bin/starter_webui/src/App.tsx +20 -0
- package/bin/starter_webui/src/components/Chat/OptionsPanel/FormItem.tsx +37 -0
- package/bin/starter_webui/src/components/Chat/OptionsPanel/OptionsEditor.tsx +160 -0
- package/bin/starter_webui/src/components/Chat/OptionsPanel/defaultConfig.ts +41 -0
- package/bin/starter_webui/src/components/Chat/OptionsPanel/index.tsx +27 -0
- package/bin/starter_webui/src/components/Chat/index.tsx +45 -0
- package/bin/starter_webui/src/components/Chat/sessionApi/index.ts +53 -0
- package/bin/starter_webui/src/main.tsx +9 -0
- package/bin/starter_webui/src/vite-env.d.ts +4 -0
- package/bin/starter_webui/tsconfig.app.json +24 -0
- package/bin/starter_webui/tsconfig.json +7 -0
- package/bin/starter_webui/tsconfig.node.json +22 -0
- package/bin/starter_webui/vite.config.ts +11 -0
- package/components/AgentScopeRuntimeWebUI/bailian-high-code-webui/README.md +75 -0
- package/components/AgentScopeRuntimeWebUI/bailian-high-code-webui/eslint.config.js +28 -0
- package/components/AgentScopeRuntimeWebUI/bailian-high-code-webui/index.html +12 -0
- package/components/AgentScopeRuntimeWebUI/bailian-high-code-webui/package.json +34 -0
- package/components/AgentScopeRuntimeWebUI/bailian-high-code-webui/src/App.tsx +20 -0
- package/components/AgentScopeRuntimeWebUI/bailian-high-code-webui/src/components/Cards/Weather.tsx +234 -0
- package/components/AgentScopeRuntimeWebUI/bailian-high-code-webui/src/components/Chat/defaultConfig.ts +54 -0
- package/components/AgentScopeRuntimeWebUI/bailian-high-code-webui/src/components/Chat/index.tsx +11 -0
- package/components/AgentScopeRuntimeWebUI/bailian-high-code-webui/src/main.tsx +9 -0
- package/components/AgentScopeRuntimeWebUI/bailian-high-code-webui/src/vite-env.d.ts +4 -0
- package/components/AgentScopeRuntimeWebUI/bailian-high-code-webui/tsconfig.app.json +24 -0
- package/components/AgentScopeRuntimeWebUI/bailian-high-code-webui/tsconfig.json +7 -0
- package/components/AgentScopeRuntimeWebUI/bailian-high-code-webui/tsconfig.node.json +22 -0
- package/components/AgentScopeRuntimeWebUI/bailian-high-code-webui/vite.config.ts +7 -0
- package/components/AgentScopeRuntimeWebUI/core/Context/defaultSessionApi.ts +8 -3
- package/lib/AgentScopeRuntimeWebUI/core/Context/defaultSessionApi.js +8 -3
- package/package.json +1 -1
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# agentscope-runtime-starter-webui
|
|
2
|
+
|
|
3
|
+
## node version
|
|
4
|
+
|
|
5
|
+
> =22
|
|
6
|
+
|
|
7
|
+
## install
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
$ npm run install
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## dev
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
$ npm run dev
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## build
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
$ npm run build
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Core Code
|
|
26
|
+
```tsx
|
|
27
|
+
import { AgentScopeRuntimeWebUI } from '@agentscope-ai/chat';
|
|
28
|
+
|
|
29
|
+
const options = {
|
|
30
|
+
theme: {
|
|
31
|
+
colorPrimary: '#615CED',
|
|
32
|
+
darkMode: true,
|
|
33
|
+
prefix: 'agentscope-runtime-webui',
|
|
34
|
+
leftHeader: {
|
|
35
|
+
logo: 'https://img.alicdn.com/imgextra/i2/O1CN01lmoGYn1kjoXATy4PX_!!6000000004720-2-tps-200-200.png',
|
|
36
|
+
title: 'Runtime WebUI',
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
sender: {
|
|
40
|
+
maxLength: 10000,
|
|
41
|
+
disclaimer:
|
|
42
|
+
'AI can also make mistakes, so please check carefully and use it with caution',
|
|
43
|
+
},
|
|
44
|
+
|
|
45
|
+
welcome: {
|
|
46
|
+
greeting: 'Hello, how can I help you today?',
|
|
47
|
+
description:
|
|
48
|
+
'I am a helpful assistant that can help you with your questions.',
|
|
49
|
+
avatar:
|
|
50
|
+
'https://img.alicdn.com/imgextra/i2/O1CN01lmoGYn1kjoXATy4PX_!!6000000004720-2-tps-200-200.png',
|
|
51
|
+
prompts: [
|
|
52
|
+
{
|
|
53
|
+
value: 'Hello',
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
value: 'How are you?',
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
value: 'What can you do?',
|
|
60
|
+
},
|
|
61
|
+
],
|
|
62
|
+
},
|
|
63
|
+
api: {
|
|
64
|
+
baseURL: 'YOUR_API_URL',
|
|
65
|
+
token: 'YOUR_API_TOKEN', // is not required
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
<AgentScopeRuntimeWebUI
|
|
71
|
+
options={options}
|
|
72
|
+
/>
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
```
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import js from '@eslint/js'
|
|
2
|
+
import globals from 'globals'
|
|
3
|
+
import reactHooks from 'eslint-plugin-react-hooks'
|
|
4
|
+
import reactRefresh from 'eslint-plugin-react-refresh'
|
|
5
|
+
import tseslint from 'typescript-eslint'
|
|
6
|
+
|
|
7
|
+
export default tseslint.config(
|
|
8
|
+
{ ignores: ['dist'] },
|
|
9
|
+
{
|
|
10
|
+
extends: [js.configs.recommended, ...tseslint.configs.recommended],
|
|
11
|
+
files: ['**/*.{ts,tsx}'],
|
|
12
|
+
languageOptions: {
|
|
13
|
+
ecmaVersion: 2020,
|
|
14
|
+
globals: globals.browser,
|
|
15
|
+
},
|
|
16
|
+
plugins: {
|
|
17
|
+
'react-hooks': reactHooks,
|
|
18
|
+
'react-refresh': reactRefresh,
|
|
19
|
+
},
|
|
20
|
+
rules: {
|
|
21
|
+
...reactHooks.configs.recommended.rules,
|
|
22
|
+
'react-refresh/only-export-components': [
|
|
23
|
+
'warn',
|
|
24
|
+
{ allowConstantExport: true },
|
|
25
|
+
],
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
)
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>AgentScope Runtime Starter WebUI</title>
|
|
7
|
+
</head>
|
|
8
|
+
<body>
|
|
9
|
+
<div id="root"></div>
|
|
10
|
+
<script type="module" src="/src/main.tsx"></script>
|
|
11
|
+
</body>
|
|
12
|
+
</html>
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "agentscope-runtime-starter-webui",
|
|
3
|
+
"private": true,
|
|
4
|
+
"version": "0.0.0",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "vite --host",
|
|
8
|
+
"build": "tsc -b && vite build",
|
|
9
|
+
"lint": "eslint .",
|
|
10
|
+
"preview": "vite preview"
|
|
11
|
+
},
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"@agentscope-ai/icons": "^1.0.46",
|
|
14
|
+
"@agentscope-ai/chat": "^1.1.44",
|
|
15
|
+
"@agentscope-ai/design": "^1.0.19",
|
|
16
|
+
"antd": "^5.29.1",
|
|
17
|
+
"antd-style": "^3.7.1",
|
|
18
|
+
"react": "^18",
|
|
19
|
+
"react-dom": "^18"
|
|
20
|
+
},
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"@eslint/js": "^9.25.0",
|
|
23
|
+
"@types/react": "^18",
|
|
24
|
+
"@types/react-dom": "^18",
|
|
25
|
+
"@vitejs/plugin-react": "^4.4.1",
|
|
26
|
+
"eslint": "^9.25.0",
|
|
27
|
+
"eslint-plugin-react-hooks": "^5.2.0",
|
|
28
|
+
"eslint-plugin-react-refresh": "^0.4.19",
|
|
29
|
+
"globals": "^16.0.0",
|
|
30
|
+
"typescript": "~5.8.3",
|
|
31
|
+
"typescript-eslint": "^8.30.1",
|
|
32
|
+
"vite": "^6.3.5"
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import Chat from './components/Chat';
|
|
2
|
+
|
|
3
|
+
import { createGlobalStyle } from 'antd-style';
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
const GlobalStyle = createGlobalStyle`
|
|
7
|
+
* {
|
|
8
|
+
margin: 0;
|
|
9
|
+
box-sizing: border-box;
|
|
10
|
+
}
|
|
11
|
+
`;
|
|
12
|
+
|
|
13
|
+
function App() {
|
|
14
|
+
return <>
|
|
15
|
+
<GlobalStyle />
|
|
16
|
+
<Chat />
|
|
17
|
+
</>
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export default App
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Form } from 'antd';
|
|
2
|
+
import { createStyles } from 'antd-style';
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
interface FormItemProps {
|
|
6
|
+
name: string | string[];
|
|
7
|
+
label: string;
|
|
8
|
+
isList?: boolean;
|
|
9
|
+
children: any;
|
|
10
|
+
normalize?: (value: any) => any;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
const useStyles = createStyles(({ token }) => ({
|
|
15
|
+
label: {
|
|
16
|
+
marginBottom: 6,
|
|
17
|
+
fontSize: 12,
|
|
18
|
+
color: token.colorTextSecondary,
|
|
19
|
+
},
|
|
20
|
+
|
|
21
|
+
}));
|
|
22
|
+
|
|
23
|
+
export default function FormItem(props: FormItemProps) {
|
|
24
|
+
const { styles } = useStyles();
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
const node = props.isList ?
|
|
28
|
+
<Form.List name={props.name}>{props.children}</Form.List> :
|
|
29
|
+
<Form.Item name={props.name} normalize={props.normalize}>{props.children}</Form.Item>;
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
return <div>
|
|
33
|
+
{props.label && <div className={styles.label}>{props.label}</div>}
|
|
34
|
+
{node}
|
|
35
|
+
</div>
|
|
36
|
+
|
|
37
|
+
}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Form, Input, ColorPicker, Flex, Divider, InputNumber } from 'antd';
|
|
3
|
+
import { createStyles } from 'antd-style';
|
|
4
|
+
import { Button, IconButton, Switch } from '@agentscope-ai/design'
|
|
5
|
+
import { SparkDeleteLine, SparkPlusLine } from '@agentscope-ai/icons';
|
|
6
|
+
import FormItem from './FormItem';
|
|
7
|
+
import defaultConfig from './defaultConfig';
|
|
8
|
+
|
|
9
|
+
const useStyles = createStyles(({ token }) => ({
|
|
10
|
+
container: {
|
|
11
|
+
height: '100%',
|
|
12
|
+
display: 'flex',
|
|
13
|
+
flexDirection: 'column',
|
|
14
|
+
},
|
|
15
|
+
|
|
16
|
+
form: {
|
|
17
|
+
height: 0,
|
|
18
|
+
flex: 1,
|
|
19
|
+
padding: '8px 16px 16px 16px',
|
|
20
|
+
overflow: 'auto',
|
|
21
|
+
},
|
|
22
|
+
actions: {
|
|
23
|
+
padding: 16,
|
|
24
|
+
display: 'flex',
|
|
25
|
+
borderTop: `1px solid ${token.colorBorderSecondary}`,
|
|
26
|
+
justifyContent: 'flex-end',
|
|
27
|
+
gap: 16,
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
}));
|
|
31
|
+
|
|
32
|
+
interface OptionsEditorProps {
|
|
33
|
+
value?: any;
|
|
34
|
+
onChange?: any;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const OptionsEditor: React.FC<OptionsEditorProps> = ({
|
|
38
|
+
value,
|
|
39
|
+
onChange,
|
|
40
|
+
}) => {
|
|
41
|
+
const { styles } = useStyles();
|
|
42
|
+
const [form] = Form.useForm();
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
const handleSave = () => {
|
|
46
|
+
form.validateFields().then((values) => {
|
|
47
|
+
onChange(values);
|
|
48
|
+
});
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const handleReset = () => {
|
|
52
|
+
form.setFieldsValue(defaultConfig);
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
return (
|
|
56
|
+
<div className={styles.container}>
|
|
57
|
+
<Form
|
|
58
|
+
className={styles.form}
|
|
59
|
+
form={form}
|
|
60
|
+
layout="vertical"
|
|
61
|
+
initialValues={value}
|
|
62
|
+
>
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
<Divider orientation="left">Theme</Divider>
|
|
66
|
+
|
|
67
|
+
<FormItem name={['theme', 'colorPrimary']} label="colorPrimary" normalize={value => value.toHexString()}>
|
|
68
|
+
<ColorPicker />
|
|
69
|
+
</FormItem>
|
|
70
|
+
|
|
71
|
+
<FormItem name={['theme', 'colorBgBase']} label="colorBgBase" normalize={value => value.toHexString()}>
|
|
72
|
+
<ColorPicker />
|
|
73
|
+
</FormItem>
|
|
74
|
+
|
|
75
|
+
<FormItem name={['theme', 'colorTextBase']} label="colorTextBase" normalize={value => value.toHexString()}>
|
|
76
|
+
<ColorPicker />
|
|
77
|
+
</FormItem>
|
|
78
|
+
|
|
79
|
+
<FormItem name={['theme', 'darkMode']} label="darkMode" >
|
|
80
|
+
<Switch />
|
|
81
|
+
</FormItem>
|
|
82
|
+
|
|
83
|
+
<FormItem name={['theme', 'leftHeader', 'logo']} label="leftHeader.logo" >
|
|
84
|
+
<Input />
|
|
85
|
+
</FormItem>
|
|
86
|
+
|
|
87
|
+
<FormItem name={['theme', 'leftHeader', 'title']} label="leftHeader.title" >
|
|
88
|
+
<Input />
|
|
89
|
+
</FormItem>
|
|
90
|
+
|
|
91
|
+
<Divider orientation="left">Sender</Divider>
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
<FormItem name={['sender', 'disclaimer']} label="disclaimer" >
|
|
95
|
+
<Input />
|
|
96
|
+
</FormItem>
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
<FormItem name={['sender', 'maxLength']} label="maxLength" >
|
|
102
|
+
<InputNumber min={1000} />
|
|
103
|
+
</FormItem>
|
|
104
|
+
|
|
105
|
+
<Divider orientation="left">Welcome</Divider>
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
<FormItem name={['welcome', 'greeting']} label="greeting" >
|
|
109
|
+
<Input />
|
|
110
|
+
</FormItem>
|
|
111
|
+
|
|
112
|
+
<FormItem name={['welcome', 'description']} label="description" >
|
|
113
|
+
<Input />
|
|
114
|
+
</FormItem>
|
|
115
|
+
|
|
116
|
+
<FormItem name={['welcome', 'avatar']} label="avatar" >
|
|
117
|
+
<Input />
|
|
118
|
+
</FormItem>
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
<FormItem name={['welcome', 'prompts']} isList label="prompts" >
|
|
122
|
+
{(fields: { key: string, name: string }[], { add, remove }: { add: (item: any) => void, remove: (name: string) => void }) => {
|
|
123
|
+
return <div>
|
|
124
|
+
{fields.map(field => {
|
|
125
|
+
return <Flex key={field.key} gap={6}>
|
|
126
|
+
<Form.Item style={{ flex: 1 }} key={field.key} name={[field.name, 'value']}>
|
|
127
|
+
<Input />
|
|
128
|
+
</Form.Item>
|
|
129
|
+
<IconButton icon={<SparkPlusLine />} onClick={() => add({})}></IconButton>
|
|
130
|
+
<IconButton icon={<SparkDeleteLine />} onClick={() => remove(field.name)}></IconButton>
|
|
131
|
+
</Flex>
|
|
132
|
+
})}
|
|
133
|
+
</div>
|
|
134
|
+
}}
|
|
135
|
+
</FormItem>
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
<Divider orientation="left">API</Divider>
|
|
139
|
+
|
|
140
|
+
<FormItem name={['api', 'baseURL']} label="baseURL" >
|
|
141
|
+
<Input />
|
|
142
|
+
</FormItem>
|
|
143
|
+
|
|
144
|
+
<FormItem name={['api', 'token']} label="token" >
|
|
145
|
+
<Input />
|
|
146
|
+
</FormItem>
|
|
147
|
+
</Form>
|
|
148
|
+
|
|
149
|
+
<div className={styles.actions}>
|
|
150
|
+
<Button onClick={handleReset}>Reset</Button>
|
|
151
|
+
<Button type="primary" onClick={handleSave}>
|
|
152
|
+
Save & Copy
|
|
153
|
+
</Button>
|
|
154
|
+
</div>
|
|
155
|
+
</div>
|
|
156
|
+
);
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
export default OptionsEditor;
|
|
160
|
+
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
theme: {
|
|
3
|
+
colorPrimary: '#615CED',
|
|
4
|
+
darkMode: true,
|
|
5
|
+
prefix: 'agentscope-runtime-webui',
|
|
6
|
+
leftHeader: {
|
|
7
|
+
logo: 'https://img.alicdn.com/imgextra/i2/O1CN01lmoGYn1kjoXATy4PX_!!6000000004720-2-tps-200-200.png',
|
|
8
|
+
title: 'Runtime WebUI',
|
|
9
|
+
},
|
|
10
|
+
},
|
|
11
|
+
sender: {
|
|
12
|
+
attachments: false,
|
|
13
|
+
maxLength: 10000,
|
|
14
|
+
disclaimer:
|
|
15
|
+
'AI can also make mistakes, so please check carefully and use it with caution',
|
|
16
|
+
},
|
|
17
|
+
|
|
18
|
+
welcome: {
|
|
19
|
+
greeting: 'Hello, how can I help you today?',
|
|
20
|
+
description:
|
|
21
|
+
'I am a helpful assistant that can help you with your questions.',
|
|
22
|
+
avatar:
|
|
23
|
+
'https://img.alicdn.com/imgextra/i2/O1CN01lmoGYn1kjoXATy4PX_!!6000000004720-2-tps-200-200.png',
|
|
24
|
+
prompts: [
|
|
25
|
+
{
|
|
26
|
+
value: 'Hello',
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
value: 'How are you?',
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
value: 'What can you do?',
|
|
33
|
+
},
|
|
34
|
+
],
|
|
35
|
+
},
|
|
36
|
+
api: {
|
|
37
|
+
baseURL: BASE_URL,
|
|
38
|
+
token: TOKEN,
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { SparkSettingLine } from "@agentscope-ai/icons";
|
|
2
|
+
import { IconButton, Drawer } from "@agentscope-ai/design";
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
import OptionsEditor from "./OptionsEditor";
|
|
5
|
+
|
|
6
|
+
interface OptionsPanelProps {
|
|
7
|
+
value?: any;
|
|
8
|
+
onChange?: any;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export default function OptionsPanel(props: OptionsPanelProps) {
|
|
12
|
+
const [open, setOpen] = useState(false);
|
|
13
|
+
|
|
14
|
+
return <>
|
|
15
|
+
<IconButton onClick={() => setOpen(true)} icon={<SparkSettingLine />} bordered={false} />
|
|
16
|
+
<Drawer
|
|
17
|
+
destroyOnHidden
|
|
18
|
+
open={open}
|
|
19
|
+
onClose={() => setOpen(false)}
|
|
20
|
+
styles={{ body: { padding: 0 }, header: { padding: 8 } }}>
|
|
21
|
+
<OptionsEditor value={props.value} onChange={(v: typeof props.value) => {
|
|
22
|
+
setOpen(false);
|
|
23
|
+
props.onChange(v);
|
|
24
|
+
}} />
|
|
25
|
+
</Drawer>
|
|
26
|
+
</>
|
|
27
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { AgentScopeRuntimeWebUI, IAgentScopeRuntimeWebUIOptions } from '@agentscope-ai/chat';
|
|
2
|
+
import OptionsPanel from './OptionsPanel';
|
|
3
|
+
import { useMemo } from 'react';
|
|
4
|
+
import sessionApi from './sessionApi';
|
|
5
|
+
import { useLocalStorageState } from 'ahooks';
|
|
6
|
+
import defaultConfig from './OptionsPanel/defaultConfig';
|
|
7
|
+
|
|
8
|
+
export default function () {
|
|
9
|
+
const [optionsConfig, setOptionsConfig] = useLocalStorageState('agent-scope-runtime-webui-options', {
|
|
10
|
+
defaultValue: defaultConfig,
|
|
11
|
+
listenStorageChange: true,
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
const options = useMemo(() => {
|
|
15
|
+
const rightHeader = <OptionsPanel value={optionsConfig} onChange={(v: typeof optionsConfig) => {
|
|
16
|
+
setOptionsConfig(prev => ({
|
|
17
|
+
...prev,
|
|
18
|
+
...v,
|
|
19
|
+
}));
|
|
20
|
+
}} />;
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
return {
|
|
25
|
+
...optionsConfig,
|
|
26
|
+
session: {
|
|
27
|
+
multiple: true,
|
|
28
|
+
api: sessionApi,
|
|
29
|
+
},
|
|
30
|
+
theme: {
|
|
31
|
+
...optionsConfig.theme,
|
|
32
|
+
rightHeader,
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
}, [optionsConfig]);
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
return <div style={{ height: '100vh' }}>
|
|
41
|
+
<AgentScopeRuntimeWebUI
|
|
42
|
+
options={options as unknown as IAgentScopeRuntimeWebUIOptions}
|
|
43
|
+
/>
|
|
44
|
+
</div>;
|
|
45
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import {
|
|
2
|
+
IAgentScopeRuntimeWebUISession,
|
|
3
|
+
IAgentScopeRuntimeWebUISessionAPI,
|
|
4
|
+
} from '@agentscope-ai/chat';
|
|
5
|
+
|
|
6
|
+
class SessionApi implements IAgentScopeRuntimeWebUISessionAPI {
|
|
7
|
+
private lsKey: string;
|
|
8
|
+
private sessionList: IAgentScopeRuntimeWebUISession[];
|
|
9
|
+
|
|
10
|
+
constructor() {
|
|
11
|
+
this.lsKey = 'agent-scope-runtime-webui-sessions';
|
|
12
|
+
this.sessionList = [];
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
async getSessionList() {
|
|
16
|
+
this.sessionList = JSON.parse(localStorage.getItem(this.lsKey) || '[]');
|
|
17
|
+
return [...this.sessionList];
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async getSession(sessionId: string) {
|
|
21
|
+
return this.sessionList.find((session) => session.id === sessionId) as IAgentScopeRuntimeWebUISession;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async updateSession(session: Partial<IAgentScopeRuntimeWebUISession>) {
|
|
25
|
+
const index = this.sessionList.findIndex((item) => item.id === session.id);
|
|
26
|
+
if (index > -1) {
|
|
27
|
+
this.sessionList[index] = {
|
|
28
|
+
...this.sessionList[index],
|
|
29
|
+
...session,
|
|
30
|
+
};
|
|
31
|
+
localStorage.setItem(this.lsKey, JSON.stringify(this.sessionList));
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return [...this.sessionList];
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
async createSession(session: Partial<IAgentScopeRuntimeWebUISession>) {
|
|
38
|
+
session.id = Date.now().toString();
|
|
39
|
+
this.sessionList.unshift(session as IAgentScopeRuntimeWebUISession);
|
|
40
|
+
localStorage.setItem(this.lsKey, JSON.stringify(this.sessionList));
|
|
41
|
+
return [...this.sessionList];
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
async removeSession(session: Partial<IAgentScopeRuntimeWebUISession>) {
|
|
45
|
+
this.sessionList = this.sessionList.filter(
|
|
46
|
+
(item) => item.id !== session.id,
|
|
47
|
+
);
|
|
48
|
+
localStorage.setItem(this.lsKey, JSON.stringify(this.sessionList));
|
|
49
|
+
return [...this.sessionList];
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export default new SessionApi();
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
|
4
|
+
"target": "ES2020",
|
|
5
|
+
"useDefineForClassFields": true,
|
|
6
|
+
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
|
7
|
+
"module": "ESNext",
|
|
8
|
+
"skipLibCheck": true,
|
|
9
|
+
|
|
10
|
+
"moduleResolution": "bundler",
|
|
11
|
+
"allowImportingTsExtensions": true,
|
|
12
|
+
"moduleDetection": "force",
|
|
13
|
+
"noEmit": true,
|
|
14
|
+
"jsx": "react-jsx",
|
|
15
|
+
|
|
16
|
+
"strict": true,
|
|
17
|
+
"noUnusedLocals": true,
|
|
18
|
+
"noUnusedParameters": true,
|
|
19
|
+
"erasableSyntaxOnly": true,
|
|
20
|
+
"noFallthroughCasesInSwitch": true,
|
|
21
|
+
"noUncheckedSideEffectImports": true
|
|
22
|
+
},
|
|
23
|
+
"include": ["src"]
|
|
24
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
|
|
4
|
+
"target": "ES2022",
|
|
5
|
+
"lib": ["ES2023"],
|
|
6
|
+
"module": "ESNext",
|
|
7
|
+
"skipLibCheck": true,
|
|
8
|
+
|
|
9
|
+
"moduleResolution": "bundler",
|
|
10
|
+
"allowImportingTsExtensions": true,
|
|
11
|
+
"moduleDetection": "force",
|
|
12
|
+
"noEmit": true,
|
|
13
|
+
|
|
14
|
+
"strict": true,
|
|
15
|
+
"noUnusedLocals": true,
|
|
16
|
+
"noUnusedParameters": true,
|
|
17
|
+
"erasableSyntaxOnly": true,
|
|
18
|
+
"noFallthroughCasesInSwitch": true,
|
|
19
|
+
"noUncheckedSideEffectImports": true
|
|
20
|
+
},
|
|
21
|
+
"include": ["vite.config.ts"]
|
|
22
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { defineConfig } from 'vite'
|
|
2
|
+
import react from '@vitejs/plugin-react'
|
|
3
|
+
|
|
4
|
+
export default defineConfig({
|
|
5
|
+
define: {
|
|
6
|
+
BASE_URL: JSON.stringify(process.env.BASE_URL || ''),
|
|
7
|
+
TOKEN: JSON.stringify(process.env.TOKEN || ''),
|
|
8
|
+
MOBILE: false,
|
|
9
|
+
},
|
|
10
|
+
plugins: [react()],
|
|
11
|
+
})
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# agentscope-runtime-starter-webui
|
|
2
|
+
|
|
3
|
+
## node version
|
|
4
|
+
|
|
5
|
+
> =22
|
|
6
|
+
|
|
7
|
+
## install
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
$ npm run install
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## dev
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
$ npm run dev
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## build
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
$ npm run build
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Core Code
|
|
26
|
+
```tsx
|
|
27
|
+
import { AgentScopeRuntimeWebUI } from '@agentscope-ai/chat';
|
|
28
|
+
|
|
29
|
+
const options = {
|
|
30
|
+
theme: {
|
|
31
|
+
colorPrimary: '#615CED',
|
|
32
|
+
darkMode: true,
|
|
33
|
+
prefix: 'agentscope-runtime-webui',
|
|
34
|
+
leftHeader: {
|
|
35
|
+
logo: 'https://img.alicdn.com/imgextra/i2/O1CN01lmoGYn1kjoXATy4PX_!!6000000004720-2-tps-200-200.png',
|
|
36
|
+
title: 'Runtime WebUI',
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
sender: {
|
|
40
|
+
maxLength: 10000,
|
|
41
|
+
disclaimer:
|
|
42
|
+
'AI can also make mistakes, so please check carefully and use it with caution',
|
|
43
|
+
},
|
|
44
|
+
|
|
45
|
+
welcome: {
|
|
46
|
+
greeting: 'Hello, how can I help you today?',
|
|
47
|
+
description:
|
|
48
|
+
'I am a helpful assistant that can help you with your questions.',
|
|
49
|
+
avatar:
|
|
50
|
+
'https://img.alicdn.com/imgextra/i2/O1CN01lmoGYn1kjoXATy4PX_!!6000000004720-2-tps-200-200.png',
|
|
51
|
+
prompts: [
|
|
52
|
+
{
|
|
53
|
+
value: 'Hello',
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
value: 'How are you?',
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
value: 'What can you do?',
|
|
60
|
+
},
|
|
61
|
+
],
|
|
62
|
+
},
|
|
63
|
+
api: {
|
|
64
|
+
baseURL: 'YOUR_API_URL',
|
|
65
|
+
token: 'YOUR_API_TOKEN', // is not required
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
<AgentScopeRuntimeWebUI
|
|
71
|
+
options={options}
|
|
72
|
+
/>
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
```
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import js from '@eslint/js'
|
|
2
|
+
import globals from 'globals'
|
|
3
|
+
import reactHooks from 'eslint-plugin-react-hooks'
|
|
4
|
+
import reactRefresh from 'eslint-plugin-react-refresh'
|
|
5
|
+
import tseslint from 'typescript-eslint'
|
|
6
|
+
|
|
7
|
+
export default tseslint.config(
|
|
8
|
+
{ ignores: ['dist'] },
|
|
9
|
+
{
|
|
10
|
+
extends: [js.configs.recommended, ...tseslint.configs.recommended],
|
|
11
|
+
files: ['**/*.{ts,tsx}'],
|
|
12
|
+
languageOptions: {
|
|
13
|
+
ecmaVersion: 2020,
|
|
14
|
+
globals: globals.browser,
|
|
15
|
+
},
|
|
16
|
+
plugins: {
|
|
17
|
+
'react-hooks': reactHooks,
|
|
18
|
+
'react-refresh': reactRefresh,
|
|
19
|
+
},
|
|
20
|
+
rules: {
|
|
21
|
+
...reactHooks.configs.recommended.rules,
|
|
22
|
+
'react-refresh/only-export-components': [
|
|
23
|
+
'warn',
|
|
24
|
+
{ allowConstantExport: true },
|
|
25
|
+
],
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
)
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>AgentScope Runtime Starter WebUI</title>
|
|
7
|
+
</head>
|
|
8
|
+
<body>
|
|
9
|
+
<div id="root"></div>
|
|
10
|
+
<script type="module" src="/src/main.tsx"></script>
|
|
11
|
+
</body>
|
|
12
|
+
</html>
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "agentscope-runtime-starter-webui",
|
|
3
|
+
"private": true,
|
|
4
|
+
"version": "0.0.0",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "vite --host",
|
|
8
|
+
"build": "tsc -b && vite build",
|
|
9
|
+
"lint": "eslint .",
|
|
10
|
+
"preview": "vite preview"
|
|
11
|
+
},
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"@agentscope-ai/icons": "^1.0.46",
|
|
14
|
+
"@agentscope-ai/chat": "1.1.59-beta.1775119922876",
|
|
15
|
+
"@agentscope-ai/design": "^1.0.19",
|
|
16
|
+
"antd": "^5.29.1",
|
|
17
|
+
"antd-style": "^3.7.1",
|
|
18
|
+
"react": "^18",
|
|
19
|
+
"react-dom": "^18"
|
|
20
|
+
},
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"@eslint/js": "^9.25.0",
|
|
23
|
+
"@types/react": "^18",
|
|
24
|
+
"@types/react-dom": "^18",
|
|
25
|
+
"@vitejs/plugin-react": "^4.4.1",
|
|
26
|
+
"eslint": "^9.25.0",
|
|
27
|
+
"eslint-plugin-react-hooks": "^5.2.0",
|
|
28
|
+
"eslint-plugin-react-refresh": "^0.4.19",
|
|
29
|
+
"globals": "^16.0.0",
|
|
30
|
+
"typescript": "~5.8.3",
|
|
31
|
+
"typescript-eslint": "^8.30.1",
|
|
32
|
+
"vite": "^6.3.5"
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import Chat from './components/Chat';
|
|
2
|
+
|
|
3
|
+
import { createGlobalStyle } from 'antd-style';
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
const GlobalStyle = createGlobalStyle`
|
|
7
|
+
* {
|
|
8
|
+
margin: 0;
|
|
9
|
+
box-sizing: border-box;
|
|
10
|
+
}
|
|
11
|
+
`;
|
|
12
|
+
|
|
13
|
+
function App() {
|
|
14
|
+
return <>
|
|
15
|
+
<GlobalStyle />
|
|
16
|
+
<Chat />
|
|
17
|
+
</>
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export default App
|
package/components/AgentScopeRuntimeWebUI/bailian-high-code-webui/src/components/Cards/Weather.tsx
ADDED
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
import { createStyles } from 'antd-style';
|
|
2
|
+
|
|
3
|
+
interface IToolContentItem {
|
|
4
|
+
type: string;
|
|
5
|
+
object?: string;
|
|
6
|
+
status: string;
|
|
7
|
+
delta?: boolean | null;
|
|
8
|
+
msg_id?: string;
|
|
9
|
+
index?: number;
|
|
10
|
+
error?: unknown;
|
|
11
|
+
sequence_number?: number | null;
|
|
12
|
+
data: {
|
|
13
|
+
name: string;
|
|
14
|
+
arguments?: string;
|
|
15
|
+
output?: string;
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
interface IToolMessage {
|
|
20
|
+
id: string;
|
|
21
|
+
object?: string;
|
|
22
|
+
type: string;
|
|
23
|
+
role: string;
|
|
24
|
+
status: string;
|
|
25
|
+
content: IToolContentItem[];
|
|
26
|
+
code?: string | null;
|
|
27
|
+
message?: string | null;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface IWeatherItem {
|
|
31
|
+
location: string;
|
|
32
|
+
weather: string;
|
|
33
|
+
temperature: number;
|
|
34
|
+
date: string;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function parseOutput(data: IToolMessage): IWeatherItem[] {
|
|
38
|
+
const outputContent = data.content[1]?.data;
|
|
39
|
+
try {
|
|
40
|
+
// @ts-ignore
|
|
41
|
+
return JSON.parse(JSON.parse(outputContent.output));
|
|
42
|
+
} catch {
|
|
43
|
+
return [];
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const weatherIcons: Record<string, string> = {
|
|
48
|
+
sunny: '☀️',
|
|
49
|
+
cloudy: '☁️',
|
|
50
|
+
rainy: '🌧️',
|
|
51
|
+
snowy: '❄️',
|
|
52
|
+
stormy: '⛈️',
|
|
53
|
+
windy: '💨',
|
|
54
|
+
foggy: '🌫️',
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const weatherLabels: Record<string, string> = {
|
|
58
|
+
sunny: '晴',
|
|
59
|
+
cloudy: '多云',
|
|
60
|
+
rainy: '雨',
|
|
61
|
+
snowy: '雪',
|
|
62
|
+
stormy: '暴风雨',
|
|
63
|
+
windy: '大风',
|
|
64
|
+
foggy: '雾',
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
function formatDate(dateStr: string) {
|
|
68
|
+
const d = new Date(dateStr);
|
|
69
|
+
const weekdays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
|
|
70
|
+
const month = d.getMonth() + 1;
|
|
71
|
+
const day = d.getDate();
|
|
72
|
+
const today = new Date();
|
|
73
|
+
const isToday =
|
|
74
|
+
d.getFullYear() === today.getFullYear() &&
|
|
75
|
+
d.getMonth() === today.getMonth() &&
|
|
76
|
+
d.getDate() === today.getDate();
|
|
77
|
+
return {
|
|
78
|
+
weekday: isToday ? '今天' : weekdays[d.getDay()],
|
|
79
|
+
date: `${month}/${day}`,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const useStyles = createStyles(({ token, css }) => ({
|
|
84
|
+
wrapper: css`
|
|
85
|
+
border-radius: 12px;
|
|
86
|
+
border: 1px solid ${token.colorBorderSecondary};
|
|
87
|
+
background: ${token.colorBgElevated};
|
|
88
|
+
overflow: hidden;
|
|
89
|
+
`,
|
|
90
|
+
header: css`
|
|
91
|
+
display: flex;
|
|
92
|
+
align-items: center;
|
|
93
|
+
justify-content: space-between;
|
|
94
|
+
padding: 14px 16px;
|
|
95
|
+
border-bottom: 1px solid ${token.colorBorderSecondary};
|
|
96
|
+
`,
|
|
97
|
+
locationRow: css`
|
|
98
|
+
display: flex;
|
|
99
|
+
align-items: center;
|
|
100
|
+
gap: 6px;
|
|
101
|
+
`,
|
|
102
|
+
locationIcon: css`
|
|
103
|
+
font-size: 16px;
|
|
104
|
+
line-height: 1;
|
|
105
|
+
`,
|
|
106
|
+
locationText: css`
|
|
107
|
+
font-size: 14px;
|
|
108
|
+
font-weight: 600;
|
|
109
|
+
color: ${token.colorText};
|
|
110
|
+
`,
|
|
111
|
+
todayTemp: css`
|
|
112
|
+
font-size: 22px;
|
|
113
|
+
font-weight: 700;
|
|
114
|
+
color: ${token.colorText};
|
|
115
|
+
display: flex;
|
|
116
|
+
align-items: center;
|
|
117
|
+
gap: 6px;
|
|
118
|
+
`,
|
|
119
|
+
todayWeather: css`
|
|
120
|
+
font-size: 13px;
|
|
121
|
+
font-weight: 400;
|
|
122
|
+
color: ${token.colorTextSecondary};
|
|
123
|
+
`,
|
|
124
|
+
container: css`
|
|
125
|
+
display: flex;
|
|
126
|
+
overflow-x: auto;
|
|
127
|
+
padding: 14px 12px;
|
|
128
|
+
`,
|
|
129
|
+
card: css`
|
|
130
|
+
flex: 1;
|
|
131
|
+
flex-shrink: 0;
|
|
132
|
+
display: flex;
|
|
133
|
+
flex-direction: column;
|
|
134
|
+
align-items: center;
|
|
135
|
+
gap: 8px;
|
|
136
|
+
padding: 10px 12px;
|
|
137
|
+
border-radius: 10px;
|
|
138
|
+
min-width: 72px;
|
|
139
|
+
transition: background 0.2s;
|
|
140
|
+
cursor: default;
|
|
141
|
+
&:hover {
|
|
142
|
+
background: ${token.colorFillQuaternary};
|
|
143
|
+
}
|
|
144
|
+
`,
|
|
145
|
+
todayCard: css`
|
|
146
|
+
background: ${token.colorPrimaryBg};
|
|
147
|
+
&:hover {
|
|
148
|
+
background: ${token.colorPrimaryBgHover};
|
|
149
|
+
}
|
|
150
|
+
`,
|
|
151
|
+
weekday: css`
|
|
152
|
+
font-size: 12px;
|
|
153
|
+
font-weight: 500;
|
|
154
|
+
color: ${token.colorTextSecondary};
|
|
155
|
+
line-height: 1;
|
|
156
|
+
`,
|
|
157
|
+
todayWeekday: css`
|
|
158
|
+
color: ${token.colorPrimary};
|
|
159
|
+
font-weight: 600;
|
|
160
|
+
`,
|
|
161
|
+
date: css`
|
|
162
|
+
font-size: 11px;
|
|
163
|
+
color: ${token.colorTextQuaternary};
|
|
164
|
+
line-height: 1;
|
|
165
|
+
`,
|
|
166
|
+
icon: css`
|
|
167
|
+
font-size: 26px;
|
|
168
|
+
line-height: 1;
|
|
169
|
+
`,
|
|
170
|
+
temp: css`
|
|
171
|
+
font-size: 15px;
|
|
172
|
+
font-weight: 600;
|
|
173
|
+
color: ${token.colorText};
|
|
174
|
+
line-height: 1;
|
|
175
|
+
`,
|
|
176
|
+
label: css`
|
|
177
|
+
font-size: 11px;
|
|
178
|
+
color: ${token.colorTextTertiary};
|
|
179
|
+
line-height: 1;
|
|
180
|
+
`,
|
|
181
|
+
}));
|
|
182
|
+
|
|
183
|
+
export default function Weather(props: { data: IToolMessage }) {
|
|
184
|
+
const items = parseOutput(props.data);
|
|
185
|
+
const { styles, cx } = useStyles();
|
|
186
|
+
|
|
187
|
+
if (!items.length) return null;
|
|
188
|
+
|
|
189
|
+
const todayItem = items.find((_, i) => {
|
|
190
|
+
const { weekday } = formatDate(items[i].date);
|
|
191
|
+
return weekday === '今天';
|
|
192
|
+
}) || items[0];
|
|
193
|
+
|
|
194
|
+
return (
|
|
195
|
+
<div className={styles.wrapper}>
|
|
196
|
+
<div className={styles.header}>
|
|
197
|
+
<div className={styles.locationRow}>
|
|
198
|
+
<span className={styles.locationIcon}>📍</span>
|
|
199
|
+
<span className={styles.locationText}>{items[0].location}</span>
|
|
200
|
+
</div>
|
|
201
|
+
<div className={styles.todayTemp}>
|
|
202
|
+
{weatherIcons[todayItem.weather] || '🌤️'} {todayItem.temperature}°
|
|
203
|
+
<span className={styles.todayWeather}>
|
|
204
|
+
{weatherLabels[todayItem.weather] || todayItem.weather}
|
|
205
|
+
</span>
|
|
206
|
+
</div>
|
|
207
|
+
</div>
|
|
208
|
+
<div className={styles.container}>
|
|
209
|
+
{items.map((item) => {
|
|
210
|
+
const { weekday, date } = formatDate(item.date);
|
|
211
|
+
const isToday = weekday === '今天';
|
|
212
|
+
return (
|
|
213
|
+
<div
|
|
214
|
+
key={item.date}
|
|
215
|
+
className={cx(styles.card, isToday && styles.todayCard)}
|
|
216
|
+
>
|
|
217
|
+
<span className={cx(styles.weekday, isToday && styles.todayWeekday)}>
|
|
218
|
+
{weekday}
|
|
219
|
+
</span>
|
|
220
|
+
<span className={styles.date}>{date}</span>
|
|
221
|
+
<span className={styles.icon}>
|
|
222
|
+
{weatherIcons[item.weather] || '🌤️'}
|
|
223
|
+
</span>
|
|
224
|
+
<span className={styles.temp}>{item.temperature}°</span>
|
|
225
|
+
<span className={styles.label}>
|
|
226
|
+
{weatherLabels[item.weather] || item.weather}
|
|
227
|
+
</span>
|
|
228
|
+
</div>
|
|
229
|
+
);
|
|
230
|
+
})}
|
|
231
|
+
</div>
|
|
232
|
+
</div>
|
|
233
|
+
);
|
|
234
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { IAgentScopeRuntimeWebUIOptions } from '@agentscope-ai/chat';
|
|
2
|
+
import Weather from '../Cards/Weather';
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
const config: IAgentScopeRuntimeWebUIOptions = {
|
|
6
|
+
customToolRenderConfig: {
|
|
7
|
+
'weather search mock': Weather,
|
|
8
|
+
},
|
|
9
|
+
theme: {
|
|
10
|
+
colorPrimary: '#615CED',
|
|
11
|
+
darkMode: true,
|
|
12
|
+
prefix: 'agentscope-runtime-webui',
|
|
13
|
+
leftHeader: {
|
|
14
|
+
logo: 'https://img.alicdn.com/imgextra/i2/O1CN01lmoGYn1kjoXATy4PX_!!6000000004720-2-tps-200-200.png',
|
|
15
|
+
title: 'Runtime WebUI',
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
sender: {
|
|
19
|
+
maxLength: 10000,
|
|
20
|
+
disclaimer:
|
|
21
|
+
'AI can also make mistakes, so please check carefully and use it with caution',
|
|
22
|
+
},
|
|
23
|
+
session: {
|
|
24
|
+
multiple: false,
|
|
25
|
+
},
|
|
26
|
+
|
|
27
|
+
welcome: {
|
|
28
|
+
greeting: 'Hello, how can I help you today?',
|
|
29
|
+
description:
|
|
30
|
+
'I am a helpful assistant that can help you with your questions.',
|
|
31
|
+
avatar:
|
|
32
|
+
'https://img.alicdn.com/imgextra/i2/O1CN01lmoGYn1kjoXATy4PX_!!6000000004720-2-tps-200-200.png',
|
|
33
|
+
prompts: [
|
|
34
|
+
{
|
|
35
|
+
value: 'Hello',
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
value: 'How are you?',
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
value: 'What can you do?',
|
|
42
|
+
},
|
|
43
|
+
],
|
|
44
|
+
},
|
|
45
|
+
api: {
|
|
46
|
+
baseURL: 'https://highcodnvvwbdks-ptzchpamaz.cn-beijing.fcapp.run/process',
|
|
47
|
+
token: '32a3e4da-528a-462d-a270-74b10cb21d75',
|
|
48
|
+
enableHistoryMessages: true,
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
export default config
|
package/components/AgentScopeRuntimeWebUI/bailian-high-code-webui/src/components/Chat/index.tsx
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { AgentScopeRuntimeWebUI, IAgentScopeRuntimeWebUIOptions } from '@agentscope-ai/chat';
|
|
2
|
+
import defaultConfig from './defaultConfig';
|
|
3
|
+
|
|
4
|
+
export default function () {
|
|
5
|
+
|
|
6
|
+
return <div style={{ height: '100vh' }}>
|
|
7
|
+
<AgentScopeRuntimeWebUI
|
|
8
|
+
options={defaultConfig as unknown as IAgentScopeRuntimeWebUIOptions}
|
|
9
|
+
/>
|
|
10
|
+
</div>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
|
4
|
+
"target": "ES2020",
|
|
5
|
+
"useDefineForClassFields": true,
|
|
6
|
+
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
|
7
|
+
"module": "ESNext",
|
|
8
|
+
"skipLibCheck": true,
|
|
9
|
+
|
|
10
|
+
"moduleResolution": "bundler",
|
|
11
|
+
"allowImportingTsExtensions": true,
|
|
12
|
+
"moduleDetection": "force",
|
|
13
|
+
"noEmit": true,
|
|
14
|
+
"jsx": "react-jsx",
|
|
15
|
+
|
|
16
|
+
"strict": true,
|
|
17
|
+
"noUnusedLocals": true,
|
|
18
|
+
"noUnusedParameters": true,
|
|
19
|
+
"erasableSyntaxOnly": true,
|
|
20
|
+
"noFallthroughCasesInSwitch": true,
|
|
21
|
+
"noUncheckedSideEffectImports": true
|
|
22
|
+
},
|
|
23
|
+
"include": ["src"]
|
|
24
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
|
|
4
|
+
"target": "ES2022",
|
|
5
|
+
"lib": ["ES2023"],
|
|
6
|
+
"module": "ESNext",
|
|
7
|
+
"skipLibCheck": true,
|
|
8
|
+
|
|
9
|
+
"moduleResolution": "bundler",
|
|
10
|
+
"allowImportingTsExtensions": true,
|
|
11
|
+
"moduleDetection": "force",
|
|
12
|
+
"noEmit": true,
|
|
13
|
+
|
|
14
|
+
"strict": true,
|
|
15
|
+
"noUnusedLocals": true,
|
|
16
|
+
"noUnusedParameters": true,
|
|
17
|
+
"erasableSyntaxOnly": true,
|
|
18
|
+
"noFallthroughCasesInSwitch": true,
|
|
19
|
+
"noUncheckedSideEffectImports": true
|
|
20
|
+
},
|
|
21
|
+
"include": ["vite.config.ts"]
|
|
22
|
+
}
|
|
@@ -48,9 +48,14 @@ function createStorageSessionStore(multiple: boolean) {
|
|
|
48
48
|
return {
|
|
49
49
|
async getSessionList() {
|
|
50
50
|
load();
|
|
51
|
-
if (!multiple
|
|
52
|
-
sessionList
|
|
53
|
-
|
|
51
|
+
if (!multiple) {
|
|
52
|
+
if (sessionList.length === 0) {
|
|
53
|
+
sessionList = [normalizeSession({})];
|
|
54
|
+
persist();
|
|
55
|
+
} else if (sessionList.length > 1) {
|
|
56
|
+
sessionList = sessionList.slice(0, 1);
|
|
57
|
+
persist();
|
|
58
|
+
}
|
|
54
59
|
}
|
|
55
60
|
return [...sessionList];
|
|
56
61
|
},
|
|
@@ -52,9 +52,14 @@ function createStorageSessionStore(multiple) {
|
|
|
52
52
|
while (1) switch (_context.prev = _context.next) {
|
|
53
53
|
case 0:
|
|
54
54
|
load();
|
|
55
|
-
if (!multiple
|
|
56
|
-
sessionList
|
|
57
|
-
|
|
55
|
+
if (!multiple) {
|
|
56
|
+
if (sessionList.length === 0) {
|
|
57
|
+
sessionList = [normalizeSession({})];
|
|
58
|
+
persist();
|
|
59
|
+
} else if (sessionList.length > 1) {
|
|
60
|
+
sessionList = sessionList.slice(0, 1);
|
|
61
|
+
persist();
|
|
62
|
+
}
|
|
58
63
|
}
|
|
59
64
|
return _context.abrupt("return", _toConsumableArray(sessionList));
|
|
60
65
|
case 3:
|