Skip to content

Commit adeb2a7

Browse files
authored
Merge pull request #9231 from GuoLiBin6/feat/glb-to-4.0/src
feat: llm config
2 parents 4f4013b + 5c819b3 commit adeb2a7

File tree

13 files changed

+499
-38
lines changed

13 files changed

+499
-38
lines changed

containers/Ai/locales/en.json

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -334,5 +334,15 @@
334334
"aice.llm_network_type.hostlocal_default": "Auto schedule - host-local network",
335335
"aice.llm_network_type.guest": "Specify classic network",
336336
"aice.llm_network_type.hostlocal": "Specify host-local network",
337-
"aice.cpu": "CPU"
337+
"aice.cpu": "CPU",
338+
"aice.dify_api_image": "Dify API Image",
339+
"aice.dify_plugin_image": "Dify Plugin Image",
340+
"aice.dify_sandbox_image": "Dify Sandbox Image",
341+
"aice.dify_ssr_image": "Dify SSR Image",
342+
"aice.dify_weaviate_image": "Dify Weaviate Image",
343+
"aice.dify_web_image": "Dify Web Image",
344+
"aice.nginx_image": "Nginx Image",
345+
"aice.postgres_image": "Postgre Image",
346+
"aice.redis_image": "Redis Image",
347+
"aice.container_status": "Container Status"
338348
}

containers/Ai/locales/ja-JP.json

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -334,5 +334,15 @@
334334
"aice.llm_network_type.hostlocal_default": "自動スケジューリング-ホストローカルネットワーク",
335335
"aice.llm_network_type.guest": "クラシックネットワークを指定",
336336
"aice.llm_network_type.hostlocal": "ホストローカルネットワークを指定",
337-
"aice.cpu": "CPU"
337+
"aice.cpu": "CPU",
338+
"aice.dify_api_image": "Dify API Image",
339+
"aice.dify_plugin_image": "Dify Plugin Image",
340+
"aice.dify_sandbox_image": "Dify Sandbox Image",
341+
"aice.dify_ssr_image": "Dify SSR Image",
342+
"aice.dify_weaviate_image": "Dify Weaviate Image",
343+
"aice.dify_web_image": "Dify Web Image",
344+
"aice.nginx_image": "Nginx Image",
345+
"aice.postgres_image": "Postgre Image",
346+
"aice.redis_image": "Redis Image",
347+
"aice.container_status": "コンテナ状態"
338348
}

containers/Ai/locales/zh-CN.json

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -336,5 +336,15 @@
336336
"aice.login_password": "密码",
337337
"aice.login_extra": "额外信息",
338338
"aice.login_info": "登录信息",
339-
"aice.click_to_show": "点击显示"
339+
"aice.click_to_show": "点击显示",
340+
"aice.dify_api_image": "Dify API 镜像",
341+
"aice.dify_plugin_image": "Dify Plugin 镜像",
342+
"aice.dify_sandbox_image": "Dify Sandbox 镜像",
343+
"aice.dify_ssr_image": "Dify SSR 镜像",
344+
"aice.dify_weaviate_image": "Dify Weaviate 镜像",
345+
"aice.dify_web_image": "Dify Web 镜像",
346+
"aice.nginx_image": "Nginx 镜像",
347+
"aice.postgres_image": "Postgre 镜像",
348+
"aice.redis_image": "Redis 镜像",
349+
"aice.container_status": "容器状态"
340350
}

containers/Ai/views/llm-sku/create/Form.vue

Lines changed: 189 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,72 @@
2929
</a-radio-group>
3030
<a-label v-else>{{ llmTypeName }}</a-label>
3131
</a-form-item>
32-
<a-form-item :label="$t('aice.llm_image')">
32+
<template v-if="form.fd.llm_type === 'dify'">
33+
<a-form-item :label="$t('aice.dify_api_image')">
34+
<base-select
35+
v-decorator="decorators.dify_api_image_id"
36+
resource="llm_images"
37+
:params="{ ...appImageParams, $t: 'dify_api_image' }"
38+
:selectProps="{ placeholder: $t('common.tips.select', [$t('aice.dify_api_image')]) }" />
39+
</a-form-item>
40+
<a-form-item :label="$t('aice.dify_plugin_image')">
41+
<base-select
42+
v-decorator="decorators.dify_plugin_image_id"
43+
resource="llm_images"
44+
:params="{ ...appImageParams, $t: 'dify_plugin_image' }"
45+
:selectProps="{ placeholder: $t('common.tips.select', [$t('aice.dify_plugin_image')]) }" />
46+
</a-form-item>
47+
<a-form-item :label="$t('aice.dify_sandbox_image')">
48+
<base-select
49+
v-decorator="decorators.dify_sandbox_image_id"
50+
resource="llm_images"
51+
:params="{ ...appImageParams, $t: 'dify_sandbox_image' }"
52+
:selectProps="{ placeholder: $t('common.tips.select', [$t('aice.dify_sandbox_image')]) }" />
53+
</a-form-item>
54+
<a-form-item :label="$t('aice.dify_ssrf_image')">
55+
<base-select
56+
v-decorator="decorators.dify_ssrf_image_id"
57+
resource="llm_images"
58+
:params="{ ...appImageParams, $t: 'dify_ssr_image' }"
59+
:selectProps="{ placeholder: $t('common.tips.select', [$t('aice.dify_ssr_image')]) }" />
60+
</a-form-item>
61+
<a-form-item :label="$t('aice.dify_weaviate_image')">
62+
<base-select
63+
v-decorator="decorators.dify_weaviate_image_id"
64+
resource="llm_images"
65+
:params="{ ...appImageParams, $t: 'dify_weaviate_image' }"
66+
:selectProps="{ placeholder: $t('common.tips.select', [$t('aice.dify_weaviate_image')]) }" />
67+
</a-form-item>
68+
<a-form-item :label="$t('aice.dify_web_image')">
69+
<base-select
70+
v-decorator="decorators.dify_web_image_id"
71+
resource="llm_images"
72+
:params="{ ...appImageParams, $t: 'dify_web_image' }"
73+
:selectProps="{ placeholder: $t('common.tips.select', [$t('aice.dify_web_image')]) }" />
74+
</a-form-item>
75+
<a-form-item :label="$t('aice.nginx_image')">
76+
<base-select
77+
v-decorator="decorators.nginx_image_id"
78+
resource="llm_images"
79+
:params="{ ...appImageParams, $t: 'nginx_image' }"
80+
:selectProps="{ placeholder: $t('common.tips.select', [$t('aice.nginx_image')]) }" />
81+
</a-form-item>
82+
<a-form-item :label="$t('aice.postgres_image')">
83+
<base-select
84+
v-decorator="decorators.postgres_image_id"
85+
resource="llm_images"
86+
:params="{ ...appImageParams, $t: 'postgres_image' }"
87+
:selectProps="{ placeholder: $t('common.tips.select', [$t('aice.postgres_image')]) }" />
88+
</a-form-item>
89+
<a-form-item :label="$t('aice.redis_image')">
90+
<base-select
91+
v-decorator="decorators.redis_image_id"
92+
resource="llm_images"
93+
:params="{ ...appImageParams, $t: 'redis_image' }"
94+
:selectProps="{ placeholder: $t('common.tips.select', [$t('aice.redis_image')]) }" />
95+
</a-form-item>
96+
</template>
97+
<a-form-item v-else :label="$t('aice.llm_image')">
3398
<base-select
3499
v-decorator="decorators.llm_image_id"
35100
resource="llm_images"
@@ -146,10 +211,6 @@
146211
</a-row>
147212
</a-form-item>
148213
</a-form>
149-
<div class="form-footer">
150-
<a-button type="primary" @click="handleConfirm" :loading="loading">{{ $t('dialog.ok') }}</a-button>
151-
<a-button @click="handleCancel">{{ $t('dialog.cancel') }}</a-button>
152-
</div>
153214
</div>
154215
</template>
155216

@@ -214,6 +275,17 @@ export default {
214275
openclaw: openclawConf = {},
215276
port_mappings = [],
216277
} = data
278+
const {
279+
dify_api_image_id,
280+
dify_plugin_image_id,
281+
dify_sandbox_image_id,
282+
dify_ssrf_image_id,
283+
dify_weaviate_image_id,
284+
dify_web_image_id,
285+
nginx_image_id,
286+
postgres_image_id,
287+
redis_image_id,
288+
} = llmSpec?.dify || {}
217289
// openclaw 优先来自 llm_spec.openclaw,其次兼容旧的顶层 openclaw 字段
218290
let openclawConfObj = llmSpec?.openclaw ?? openclawConf
219291
if (typeof openclawConfObj === 'string') {
@@ -245,7 +317,8 @@ export default {
245317
},
246318
}),
247319
fd: {
248-
llm_type: rowLlmType || (LLM_TYPE_OPTIONS[0] && LLM_TYPE_OPTIONS[0].id) || 'openclaw',
320+
// 须与 decorators.llm_type.initialValue 一致,否则 currentTypeFields / v-if 与真实选中类型不同步,初始化不展示类型字段
321+
llm_type: rowLlmType || defaultLlmType,
249322
},
250323
},
251324
decorators: {
@@ -285,6 +358,42 @@ export default {
285358
],
286359
},
287360
],
361+
dify_api_image_id: [
362+
'dify_api_image_id',
363+
{
364+
initialValue: dify_api_image_id,
365+
rules: [
366+
{ required: true, message: this.$t('common.tips.select', [this.$t('aice.dify_api_image')]) },
367+
],
368+
},
369+
],
370+
dify_plugin_image_id: [
371+
'dify_plugin_image_id',
372+
{
373+
initialValue: dify_plugin_image_id,
374+
rules: [
375+
{ required: true, message: this.$t('common.tips.select', [this.$t('aice.dify_plugin_image')]) },
376+
],
377+
},
378+
],
379+
dify_sandbox_image_id: [
380+
'dify_sandbox_image_id',
381+
{
382+
initialValue: dify_sandbox_image_id,
383+
rules: [
384+
{ required: true, message: this.$t('common.tips.select', [this.$t('aice.dify_sandbox_image')]) },
385+
],
386+
},
387+
],
388+
dify_ssrf_image_id: [
389+
'dify_ssrf_image_id',
390+
{
391+
initialValue: dify_ssrf_image_id,
392+
rules: [
393+
{ required: true, message: this.$t('common.tips.select', [this.$t('aice.dify_ssr_image')]) },
394+
],
395+
},
396+
],
288397
llm_type: [
289398
'llm_type',
290399
{
@@ -294,6 +403,51 @@ export default {
294403
],
295404
},
296405
],
406+
dify_weaviate_image_id: [
407+
'dify_weaviate_image_id',
408+
{
409+
initialValue: dify_weaviate_image_id,
410+
rules: [
411+
{ required: true, message: this.$t('common.tips.select', [this.$t('aice.dify_weaviate_image')]) },
412+
],
413+
},
414+
],
415+
dify_web_image_id: [
416+
'dify_web_image_id',
417+
{
418+
initialValue: dify_web_image_id,
419+
rules: [
420+
{ required: true, message: this.$t('common.tips.select', [this.$t('aice.dify_web_image')]) },
421+
],
422+
},
423+
],
424+
nginx_image_id: [
425+
'nginx_image_id',
426+
{
427+
initialValue: nginx_image_id,
428+
rules: [
429+
{ required: true, message: this.$t('common.tips.select', [this.$t('aice.nginx_image')]) },
430+
],
431+
},
432+
],
433+
postgres_image_id: [
434+
'postgres_image_id',
435+
{
436+
initialValue: postgres_image_id,
437+
rules: [
438+
{ required: true, message: this.$t('common.tips.select', [this.$t('aice.postgres_image')]) },
439+
],
440+
},
441+
],
442+
redis_image_id: [
443+
'redis_image_id',
444+
{
445+
initialValue: redis_image_id,
446+
rules: [
447+
{ required: true, message: this.$t('common.tips.select', [this.$t('aice.redis_image')]) },
448+
],
449+
},
450+
],
297451
openclaw_agents_md: [
298452
'openclaw_agents_md',
299453
{
@@ -375,7 +529,7 @@ export default {
375529
device: [
376530
'device',
377531
{
378-
initialValue: devices && devices[0]?.model,
532+
initialValue: devices && devices.length > 0 ? devices.map(v => v.model) : [],
379533
rules: [
380534
{ required: true, message: this.$t('common.tips.select', [this.$t('aice.devices')]) },
381535
],
@@ -406,8 +560,8 @@ export default {
406560
},
407561
},
408562
formItemLayout: {
409-
wrapperCol: { span: 18 },
410-
labelCol: { span: 5 },
563+
wrapperCol: { span: 20 },
564+
labelCol: { span: 4 },
411565
},
412566
envVars,
413567
projectName: (project_domain != null && tenant != null) ? `${project_domain}/${tenant}` : '',
@@ -519,6 +673,15 @@ export default {
519673
phone_image,
520674
request_sync_image,
521675
llm_image_id,
676+
dify_api_image_id,
677+
dify_plugin_image_id,
678+
dify_sandbox_image_id,
679+
dify_ssrf_image_id,
680+
dify_weaviate_image_id,
681+
dify_web_image_id,
682+
nginx_image_id,
683+
postgres_image_id,
684+
redis_image_id,
522685
cpu,
523686
memory,
524687
volume_size,
@@ -577,7 +740,7 @@ export default {
577740
const v = pickTypeValues[key]
578741
if (v === undefined) return
579742
if (key === 'device') {
580-
data.devices = [{ model: v }]
743+
data.devices = v.map(k => ({ model: k }))
581744
} else {
582745
data[key] = v
583746
}
@@ -594,6 +757,22 @@ export default {
594757
data.llm_spec = { openclaw: { workspace_templates } }
595758
}
596759
}
760+
if (effectiveLlmType === 'dify') {
761+
data.llm_spec = {
762+
dify: {
763+
dify_api_image_id: dify_api_image_id,
764+
dify_plugin_image_id: dify_plugin_image_id,
765+
dify_sandbox_image_id: dify_sandbox_image_id,
766+
dify_ssrf_image_id: dify_ssrf_image_id,
767+
dify_weaviate_image_id: dify_weaviate_image_id,
768+
dify_web_image_id: dify_web_image_id,
769+
nginx_image_id: nginx_image_id,
770+
postgres_image_id: postgres_image_id,
771+
redis_image_id: redis_image_id,
772+
},
773+
}
774+
delete data.llm_image_id
775+
}
597776
if (this.mode === 'edit' && this.onManager && this.editData) {
598777
if (request_sync_image) data.request_sync_image = true
599778
await this.onManager('update', {

containers/Ai/views/llm-sku/create/index.vue

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,18 @@
33
<page-header :title="headerTitle" />
44
<page-body needMarginBottom>
55
<llm-sku-create-form
6+
ref="createForm"
67
mode="create"
8+
hide-footer
79
@success="onFormSuccess"
810
@cancel="onFormCancel" />
911
</page-body>
12+
<page-footer>
13+
<template v-slot:right>
14+
<a-button type="primary" :loading="submitLoading" @click="handleConfirm">{{ $t('common.create') }}</a-button>
15+
<a-button @click="handleCancel">{{ $t('common.cancel') }}</a-button>
16+
</template>
17+
</page-footer>
1018
</div>
1119
</template>
1220

@@ -18,6 +26,11 @@ export default {
1826
components: {
1927
LlmSkuCreateForm,
2028
},
29+
data () {
30+
return {
31+
submitLoading: false,
32+
}
33+
},
2134
computed: {
2235
isApplyType () {
2336
return this.$route.path.includes('app-llm')
@@ -27,8 +40,22 @@ export default {
2740
},
2841
},
2942
methods: {
43+
async handleConfirm () {
44+
const form = this.$refs.createForm
45+
if (!form) return
46+
this.submitLoading = true
47+
try {
48+
await form.handleConfirm()
49+
} catch (e) {
50+
// 校验失败等由表单处理
51+
} finally {
52+
this.submitLoading = false
53+
}
54+
},
55+
handleCancel () {
56+
this.$refs.createForm && this.$refs.createForm.handleCancel()
57+
},
3058
onFormSuccess () {
31-
this.$message.success(this.$t('common.success'))
3259
this.$router.push(this.isApplyType ? '/app-llm-sku' : '/llm-sku')
3360
},
3461
onFormCancel () {

0 commit comments

Comments
 (0)