Skip to content

Commit 81711b5

Browse files
committed
feat: Enhance Robot plugin AI model configuration and refine API endpoint paths.
1 parent 315138e commit 81711b5

File tree

10 files changed

+87
-32
lines changed

10 files changed

+87
-32
lines changed

packages/plugins/materials/src/composable/useMaterial.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -509,7 +509,7 @@ const getComponentDetail = (name) => {
509509
if (!data) return null
510510

511511
const props = data.schema.properties
512-
.map((item) => {
512+
?.map((item) => {
513513
return item.content.map((content) => {
514514
return {
515515
property: content.property,

packages/plugins/robot/src/Main.vue

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@
7979
<script setup lang="ts">
8080
import { computed, h, onMounted, ref, watch } from 'vue'
8181
import { ToolbarBase } from '@opentiny/tiny-engine-common'
82-
import { META_APP, useLayout, useNotify } from '@opentiny/tiny-engine-meta-register'
82+
import { META_APP, META_SERVICE, getMetaApi, useLayout, useNotify } from '@opentiny/tiny-engine-meta-register'
8383
import { type PopupConfig, type PromptProps, TrIconButton } from '@opentiny/tiny-robot'
8484
import { IconThink, IconNewSession } from '@opentiny/tiny-robot-svgs'
8585
import RobotChat from './components/chat/RobotChat.vue'
@@ -189,7 +189,7 @@ const isToolsModel = computed(() => {
189189
robotSettingState.defaultModel.serviceId,
190190
robotSettingState.defaultModel.modelName
191191
)
192-
return modelCapabilities?.toolCalling !== false
192+
return modelCapabilities?.toolCalling || false
193193
})
194194
195195
const handleChatModeChange = (type: string) => {
@@ -248,6 +248,8 @@ const bubbleRenderers = { 'agent-content': AgentRenderer, 'agent-loading': Agent
248248
249249
const handleFileSelected = async (formData: FormData, updateAttachment: (resourceUrl: string) => void) => {
250250
try {
251+
const appId = getMetaApi(META_SERVICE.GlobalService).getBaseInfo().id
252+
formData.append('appId', appId)
251253
const { resourceUrl } = await apiService.uploadFile(formData)
252254
updateAttachment(resourceUrl)
253255
if (!inputMessage.value) {

packages/plugins/robot/src/composables/modes/useAgentMode.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ export default function useAgentMode(): ModeHooks {
6161
const { getSelectedModelInfo } = useModelConfig()
6262

6363
// ========== 配置方法 ==========
64-
const getApiUrl = () => '/app-center/api/ai/chat'
64+
const getApiUrl = () => 'app-center/api/ai/chat'
6565

6666
const getContentType = () => 'agent-content'
6767

@@ -112,11 +112,6 @@ export default function useAgentMode(): ModeHooks {
112112

113113
const { baseUrl, model, config, capabilities } = getSelectedModelInfo()
114114

115-
// Agent 模式默认使用 JSON 对象格式
116-
if (!config?.enableThinking) {
117-
Object.assign(requestParams, { response_format: { type: 'json_object' } })
118-
}
119-
120115
requestParams.baseUrl = baseUrl
121116
requestParams.model = model
122117

@@ -129,6 +124,11 @@ export default function useAgentMode(): ModeHooks {
129124
}
130125
}
131126

127+
// Agent 模式默认使用 JSON 对象格式
128+
if (capabilities?.jsonOutput?.extraBody?.enable) {
129+
Object.assign(requestParams, capabilities.jsonOutput.extraBody.enable)
130+
}
131+
132132
return requestParams
133133
}
134134

@@ -204,14 +204,16 @@ export default function useAgentMode(): ModeHooks {
204204
if (capabilities?.reasoning?.extraBody?.disable) {
205205
Object.assign(requestParams, capabilities.reasoning.extraBody.disable)
206206
}
207+
if (capabilities?.jsonOutput?.extraBody?.enable) {
208+
Object.assign(requestParams, capabilities.jsonOutput.extraBody.enable)
209+
}
207210
Object.assign(requestParams, {
208-
response_format: { type: 'json_object' },
209211
model,
210212
baseUrl
211213
})
212214
return requestParams
213215
}
214-
const apiUrl = '/app-center/api/chat/completions'
216+
const apiUrl = 'app-center/api/chat/completions'
215217
lastMessage.renderContent.at(-1).status = 'fix'
216218
const fixedResponse = await client.chat({
217219
messages: [{ role: 'user', content: getJsonFixPrompt(content, jsonValidResult.error) }],

packages/plugins/robot/src/composables/modes/useChatMode.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ export default function useChatMode(): ModeHooks {
5454
const { getSelectedModelInfo } = useModelConfig()
5555

5656
// ========== 配置方法 ==========
57-
const getApiUrl = () => '/app-center/api/chat/completions'
57+
const getApiUrl = () => 'app-center/api/chat/completions'
5858

5959
const getContentType = () => 'markdown'
6060

packages/plugins/robot/src/composables/useChat.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,14 @@ const handleFinishRequest = async (
9797
delete abortControllerMap.main
9898
await onRequestEnd(finishReason, lastMessage.content, messages) // 本次请求结束
9999

100-
if (finishReason === 'tool_calls' && lastMessage.tool_calls?.length) {
100+
// 部分模型返回格式不太标准,例如finishReason没有返回tool_calls而是stop,这里做下兼容
101+
if (['tool_calls', 'stop'].includes(finishReason) && lastMessage.tool_calls?.length) {
102+
lastMessage!.tool_calls.forEach((toolCall) => {
103+
if (toolCall.type !== 'function') {
104+
// 修复,兼容部分场景返回格式不标准,流式中多次返回type字段
105+
toolCall.type = 'function'
106+
}
107+
})
101108
await handleToolCall(lastMessage.tool_calls, messages, contextMessages) // eslint-disable-line
102109
}
103110

packages/plugins/robot/src/constants/model-config.ts

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,23 @@ const reasoningExtraBody = {
88
}
99
}
1010

11+
const jsonOutputExtraBody = {
12+
extraBody: {
13+
enable: { response_format: { type: 'json_object' } },
14+
disable: null
15+
}
16+
}
17+
18+
const bailianJsonOutputExtraBody = {
19+
extraBody: {
20+
enable: {
21+
response_format: { type: 'json_object' },
22+
enable_thinking: false // 千问模型不支持思考模式下输出json
23+
},
24+
disable: null
25+
}
26+
}
27+
1128
export const DEFAULT_LLM_MODELS = [
1229
{
1330
provider: 'bailian',
@@ -21,7 +38,8 @@ export const DEFAULT_LLM_MODELS = [
2138
name: 'qwen-plus',
2239
capabilities: {
2340
toolCalling: true,
24-
reasoning: reasoningExtraBody
41+
reasoning: reasoningExtraBody,
42+
jsonOutput: bailianJsonOutputExtraBody
2543
}
2644
},
2745
// 备注:千问多模态模型不支持工具调用;
@@ -30,23 +48,26 @@ export const DEFAULT_LLM_MODELS = [
3048
name: 'qwen3-vl-plus',
3149
capabilities: {
3250
vision: true,
33-
reasoning: reasoningExtraBody
51+
reasoning: reasoningExtraBody,
52+
jsonOutput: bailianJsonOutputExtraBody
3453
}
3554
},
3655
{
3756
label: 'Qwen Coder编程模型(PLUS)',
3857
name: 'qwen3-coder-plus',
3958
capabilities: {
4059
toolCalling: true,
41-
reasoning: reasoningExtraBody
60+
reasoning: reasoningExtraBody,
61+
jsonOutput: bailianJsonOutputExtraBody
4262
}
4363
},
4464
{
4565
label: 'DeepSeek(v3.2)',
4666
name: 'deepseek-v3.2-exp',
4767
capabilities: {
4868
toolCalling: true,
49-
reasoning: reasoningExtraBody
69+
reasoning: reasoningExtraBody,
70+
jsonOutput: bailianJsonOutputExtraBody
5071
}
5172
},
5273
// 小参数模型
@@ -55,19 +76,29 @@ export const DEFAULT_LLM_MODELS = [
5576
name: 'qwen-flash',
5677
capabilities: {
5778
toolCalling: true,
58-
compact: true
79+
compact: true,
80+
jsonOutput: bailianJsonOutputExtraBody
5981
}
6082
},
6183
{
6284
label: 'Qwen Coder编程模型(Flash)',
6385
name: 'qwen3-coder-flash',
6486
capabilities: {
6587
toolCalling: true,
66-
compact: true
88+
compact: true,
89+
jsonOutput: bailianJsonOutputExtraBody
6790
}
6891
},
69-
{ label: 'Qwen3(14b)', name: 'qwen3-14b', capabilities: { compact: true, toolCalling: true } },
70-
{ label: 'Qwen3(8b)', name: 'qwen3-8b', capabilities: { compact: true, toolCalling: true } }
92+
{
93+
label: 'Qwen3(14b)',
94+
name: 'qwen3-14b',
95+
capabilities: { compact: true, toolCalling: true, jsonOutput: bailianJsonOutputExtraBody }
96+
},
97+
{
98+
label: 'Qwen3(8b)',
99+
name: 'qwen3-8b',
100+
capabilities: { compact: true, toolCalling: true, jsonOutput: bailianJsonOutputExtraBody }
101+
}
71102
]
72103
},
73104
{
@@ -86,7 +117,8 @@ export const DEFAULT_LLM_MODELS = [
86117
enable: { model: 'deepseek-reasoner' },
87118
disable: { model: 'deepseek-chat' }
88119
}
89-
}
120+
},
121+
jsonOutput: jsonOutputExtraBody
90122
}
91123
}
92124
]

packages/plugins/robot/src/constants/prompts/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ export const formatComponents = (snippets: any[], getComponent: (name: string) =
8888
.filter((item: any) => !ignoreGroups.includes(item.group))
8989
.map((group) => group.children)
9090
.flat()
91-
.filter((item: any) => !ignoreComponents.includes(item.snippetName))
91+
.filter((item: any) => item.snippetName && !ignoreComponents.includes(item.snippetName))
9292
.map((child) => {
9393
const component: ComponentMaterial = getComponent(toPascalCase(child.snippetName))
9494
const schema: any = {}

packages/plugins/robot/src/services/OpenAICompatibleProvider.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,9 @@ export class OpenAICompatibleProvider extends BaseModelProvider {
163163
// 构建完整URL
164164
let url = config.url
165165
if (!url.startsWith('http') && config.baseURL) {
166-
url = new URL(url, config.baseURL).href
166+
const baseURL =
167+
config.baseURL.startsWith('http') && !config.baseURL.endsWith('/') ? `${config.baseURL}/` : config.baseURL
168+
url = new URL(url, baseURL).href
167169
}
168170

169171
try {

packages/plugins/robot/src/services/api.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export const aiChatApi = {
2323
* @param options 请求选项
2424
*/
2525
chatCompletions: (body: LLMRequestBody, options: RequestOptions = {}) => {
26-
return getMetaApi(META_SERVICE.Http).post(options?.url || '/app-center/api/chat/completions', body, {
26+
return getMetaApi(META_SERVICE.Http).post(options?.url || 'app-center/api/chat/completions', body, {
2727
headers: {
2828
'Content-Type': 'application/json',
2929
...options?.headers
@@ -37,7 +37,7 @@ export const aiChatApi = {
3737
* @param options 请求选项
3838
*/
3939
agentChat: (body: LLMRequestBody, options: RequestOptions = {}) => {
40-
return getMetaApi(META_SERVICE.Http).post('/app-center/api/ai/chat', body, {
40+
return getMetaApi(META_SERVICE.Http).post('app-center/api/ai/chat', body, {
4141
headers: {
4242
'Content-Type': 'application/json',
4343
...options?.headers
@@ -50,7 +50,7 @@ export const aiChatApi = {
5050
* @param content 搜索内容
5151
*/
5252
aiSearch: (content: string): Promise<Array<{ score: number; content: string; doc_name: string }>> => {
53-
return getMetaApi(META_SERVICE.Http).post('/app-center/api/ai/search', { content })
53+
return getMetaApi(META_SERVICE.Http).post('app-center/api/ai/search', { content })
5454
}
5555
}
5656

@@ -82,7 +82,7 @@ export const resourceApi = {
8282
* @param formData 文件表单数据
8383
*/
8484
uploadFile: (formData: FormData): Promise<Resource> => {
85-
return getMetaApi(META_SERVICE.Http).post('/material-center/api/resource/upload', formData, {
85+
return getMetaApi(META_SERVICE.Http).post('material-center/api/resource/upload', formData, {
8686
headers: {
8787
'Content-Type': 'multipart/form-data'
8888
}
@@ -94,15 +94,15 @@ export const resourceApi = {
9494
* @param appId 应用ID
9595
*/
9696
getResourceList: (appId: string): Promise<ResourceGroupList> => {
97-
return getMetaApi(META_SERVICE.Http).get(`/material-center/api/resource-group/${appId}`)
97+
return getMetaApi(META_SERVICE.Http).get(`material-center/api/resource-group/${appId}`)
9898
},
9999

100100
/**
101101
* 获取资源列表
102102
* @param groupId 组ID
103103
*/
104104
getResourceListByGroup: (groupId: string): Promise<ResourceGroup> => {
105-
return getMetaApi(META_SERVICE.Http).get(`/material-center/api/resource/find/${groupId}`)
105+
return getMetaApi(META_SERVICE.Http).get(`material-center/api/resource/find/${groupId}`)
106106
}
107107
}
108108

@@ -120,7 +120,7 @@ export const httpApi = {
120120

121121
export const encryptApi = {
122122
encryptKey: (apiKey: string): Promise<{ token: string }> =>
123-
getMetaApi(META_SERVICE.Http).post('/app-center/api/encrypt-key', { apiKey })
123+
getMetaApi(META_SERVICE.Http).post('app-center/api/encrypt-key', { apiKey })
124124
}
125125

126126
export const apiService = {

packages/plugins/robot/src/types/setting.types.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,24 @@
1313
/**
1414
* 模型配置接口
1515
*/
16+
17+
export interface Capability {
18+
extraBody: {
19+
enable: any
20+
disable: any
21+
}
22+
[key: string]: any
23+
}
24+
1625
export interface ModelConfig {
1726
name: string
1827
label: string
1928
capabilities?: {
2029
toolCalling?: boolean
2130
vision?: boolean
22-
reasoning?: boolean | object
31+
reasoning?: boolean | Capability
2332
compact?: boolean
33+
jsonOutput?: boolean | Capability
2434
}
2535
}
2636

0 commit comments

Comments
 (0)