diff --git a/examples/sites/demos/pc/app/grid/ai-agent/basic-usage.vue b/examples/sites/demos/pc/app/grid/ai-agent/basic-usage.vue
index d2ae337dd9..38306f2491 100644
--- a/examples/sites/demos/pc/app/grid/ai-agent/basic-usage.vue
+++ b/examples/sites/demos/pc/app/grid/ai-agent/basic-usage.vue
@@ -87,7 +87,7 @@ export default {
await client.connect(clientTransport)
const { sessionId } = await createSseProxy({
client,
- url: 'http://39.108.160.245/sse'
+ url: 'https://39.108.160.245/sse'
})
this.sessionID = sessionId
diff --git a/examples/sites/package.json b/examples/sites/package.json
index aea9628b96..9c6b8f1c79 100644
--- a/examples/sites/package.json
+++ b/examples/sites/package.json
@@ -29,9 +29,9 @@
"@docsearch/react": "npm:@docsearch/css",
"@modelcontextprotocol/sdk": "1.12.1",
"@opentiny/next": "0.1.2",
- "@opentiny/tiny-robot": "0.2.0-alpha.8",
- "@opentiny/tiny-robot-kit": "0.2.0-alpha.8",
- "@opentiny/tiny-robot-svgs": "0.2.0-alpha.8",
+ "@opentiny/tiny-robot": "0.2.1",
+ "@opentiny/tiny-robot-kit": "0.2.1",
+ "@opentiny/tiny-robot-svgs": "0.2.1",
"@opentiny/tiny-schema-renderer": "1.0.0-beta.5",
"@opentiny/tiny-vue-mcp": "0.0.1-beta.1",
"@opentiny/utils": "workspace:~",
diff --git a/examples/sites/src/tools/appData.js b/examples/sites/src/tools/appData.js
index dfb49b60ff..3163236e9b 100644
--- a/examples/sites/src/tools/appData.js
+++ b/examples/sites/src/tools/appData.js
@@ -1,4 +1,4 @@
-import { reactive, computed } from 'vue'
+import { reactive, computed, watch } from 'vue'
import { useAutoStore } from './storage'
import { useMediaQuery } from './useMediaQuery'
import { ZH_CN_LANG, EN_US_LANG, LANG_KEY, LANG_PATH_MAP } from '../const'
@@ -8,7 +8,8 @@ const enPath = LANG_PATH_MAP[EN_US_LANG]
const appData = reactive({
lang: useAutoStore('local', LANG_KEY, ZH_CN_LANG),
theme: useAutoStore('local', '_theme', 'light'),
- bpState: useMediaQuery([640, 1024, 1280]).matches // 3点4区间, bp0,bp1,bp2,bp3
+ bpState: useMediaQuery([640, 1024, 1280]).matches, // 3点4区间, bp0,bp1,bp2,bp3
+ showTinyRobot: false
})
const isZhCn = computed(() => appData.lang === ZH_CN_LANG)
const appFn = {
@@ -27,4 +28,12 @@ const appFn = {
}
// 为了和tiny-vue共享同一个响应变量
window.appData = appData
+
+watch(
+ () => appData.showTinyRobot,
+ (value) => {
+ document.body.classList.toggle('docs-on-robot-show', value)
+ }
+)
+
export { appData, appFn, isZhCn }
diff --git a/examples/sites/src/views/components-doc/common.vue b/examples/sites/src/views/components-doc/common.vue
index 207f41d9d1..b85ef176f3 100644
--- a/examples/sites/src/views/components-doc/common.vue
+++ b/examples/sites/src/views/components-doc/common.vue
@@ -90,7 +90,7 @@
-
+
diff --git a/examples/sites/src/views/components-doc/composition/DifyModelProvider.ts b/examples/sites/src/views/components-doc/composition/DifyModelProvider.ts
index e7309964f0..93ac9fdae3 100644
--- a/examples/sites/src/views/components-doc/composition/DifyModelProvider.ts
+++ b/examples/sites/src/views/components-doc/composition/DifyModelProvider.ts
@@ -3,7 +3,8 @@ import type { AIModelConfig } from '@opentiny/tiny-robot-kit'
import type { ChatCompletionResponse } from '@opentiny/tiny-robot-kit'
import type { StreamHandler } from '@opentiny/tiny-robot-kit'
import { BaseModelProvider } from '@opentiny/tiny-robot-kit'
-import { handleSSEStream } from './utils.js'
+import { globalConversation, handleSSEStream } from './utils.js'
+import type { Ref } from 'vue'
/**
* 对接AIClient的自定义 Dify 大模型服务
@@ -14,6 +15,8 @@ import { handleSSEStream } from './utils.js'
* });
*/
export class DifyModelProvider extends BaseModelProvider {
+ _messages: Ref = []
+
constructor(config: AIModelConfig) {
super(config)
}
@@ -45,11 +48,12 @@ export class DifyModelProvider extends BaseModelProvider {
response_mode: 'streaming',
inputs: {
sessionId: window.$sessionId
- }
+ },
+ conversation_id: globalConversation.id
})
})
- await handleSSEStream(response, handler, signal)
+ await handleSSEStream(response, handler, this._messages, signal)
} catch (error) {
if (signal && signal.aborted) {
console.warn('Request was aborted:', error)
diff --git a/examples/sites/src/views/components-doc/composition/useTinyRobot.ts b/examples/sites/src/views/components-doc/composition/useTinyRobot.ts
index 1f2777e61a..c3167d3dd8 100644
--- a/examples/sites/src/views/components-doc/composition/useTinyRobot.ts
+++ b/examples/sites/src/views/components-doc/composition/useTinyRobot.ts
@@ -1,7 +1,7 @@
import type { AIModelConfig } from '@opentiny/tiny-robot-kit'
import { AIClient, useConversation } from '@opentiny/tiny-robot-kit'
import { IconAi, IconUser } from '@opentiny/tiny-robot-svgs'
-import { h, nextTick, onMounted, reactive, ref, toRaw, watch } from 'vue'
+import { h, nextTick, onMounted, ref, watch } from 'vue'
import { DifyModelProvider } from './DifyModelProvider.js'
import type { SuggestionItem } from '@opentiny/tiny-robot'
@@ -11,8 +11,9 @@ const difyConfig: AIModelConfig = {
apiKey: 'app-H0VJI4LqZ4KskdcA5a07pjXf'
}
export function useTinyRobot() {
+ const difyModelProvider = new DifyModelProvider(difyConfig)
const client = new AIClient({
- providerImplementation: new DifyModelProvider(difyConfig),
+ providerImplementation: difyModelProvider,
...difyConfig
})
@@ -27,25 +28,21 @@ export function useTinyRobot() {
{
label: '识别网页的内容',
description: '公司人员表有多少列,有多少行数据,帮我统计一下!',
- icon: h('span', { style: { fontSize: '18px' } }, '🧠')
+ icon: h('span', { style: { fontSize: '18px' } }, '💡')
},
{
label: '智能操作网页',
- description: '请勾选公司人员表最后一行”!',
- icon: h('span', { style: { fontSize: '18px' } }, '🤔')
+ description: '请勾选公司人员表最后一行',
+ icon: h('span', { style: { fontSize: '18px' } }, '🕹')
}
]
const handlePromptItemClick = (ev, item) => {
sendMessage(item.description)
}
- const { messageManager, createConversation } = useConversation({ client })
-
- const randomId = () => Math.random().toString(36).substring(2, 15)
-
- const currentMessageId = ref('')
-
+ const { messageManager } = useConversation({ client })
const { messages, messageState, inputMessage, sendMessage, abortRequest } = messageManager
+ difyModelProvider._messages = messages
const roles = {
assistant: {
@@ -61,20 +58,17 @@ export function useTinyRobot() {
}
}
- const showHistory = ref(false)
- const historyData = reactive([])
-
// 建议按钮组,设置对话的模板
const suggestionPillItems = [
{
id: '1',
text: '公司人员表',
- icon: h('span', { style: { fontSize: '18px' } }, '🔍')
+ icon: h('span', { style: { fontSize: '18px' } }, '🏢')
},
{
id: '2',
text: '城市下拉框',
- icon: h('span', { style: { fontSize: '18px' } }, '🛠️')
+ icon: h('span', { style: { fontSize: '18px' } }, '🌐')
}
]
@@ -86,60 +80,11 @@ export function useTinyRobot() {
senderRef.value.setTemplate(templateText, currentInitialValue)
}
}
- watch(
- () => messages.value[messages.value.length - 1]?.content,
- () => {
- if (!messages.value.length) {
- return
- }
-
- if (messages.value.length === 1) {
- currentMessageId.value = randomId()
- }
-
- const allSessions = historyData.flatMap((item) => item.items)
- const currentSession = allSessions.find((item) => item.id === currentMessageId.value)
-
- const data = toRaw(messages.value)
- if (!currentSession) {
- const today = historyData.find((item) => item.group === '今天')
- if (today) {
- today.items.unshift({ title: messages.value[0].content, id: currentMessageId.value, data })
- } else {
- historyData.unshift({
- group: '今天',
- items: [{ title: messages.value[0].content, id: currentMessageId.value, data }]
- })
- }
- } else {
- currentSession.data = data
- }
- }
- )
-
- const handleHistorySelect = (item) => {
- currentMessageId.value = item.id
- messages.value = item.data
- showHistory.value = false
- }
const senderRef = ref(null)
const currentTemplate = ref('')
const suggestionOpen = ref(false)
- // 设置指令
- const handleFillTemplate = (templateText) => {
- setTimeout(() => {
- currentTemplate.value = templateText
- inputMessage.value = ''
-
- // 等待DOM更新后激活第一个字段
- setTimeout(() => {
- senderRef.value?.activateTemplateFirstField()
- }, 100)
- }, 300)
- }
-
// 清除当前指令
const clearTemplate = () => {
// 清空指令相关状态
@@ -207,23 +152,17 @@ export function useTinyRobot() {
promptItems,
messageManager,
- createConversation,
messages,
messageState,
inputMessage,
sendMessage,
abortRequest,
roles,
- showHistory,
- historyData,
- currentMessageId,
handlePromptItemClick,
- handleHistorySelect,
senderRef,
currentTemplate,
suggestionOpen,
- handleFillTemplate,
clearTemplate,
handleSendMessage,
handleMessageKeydown,
diff --git a/examples/sites/src/views/components-doc/composition/utils.ts b/examples/sites/src/views/components-doc/composition/utils.ts
index 879f1ad9bf..0844caf87c 100644
--- a/examples/sites/src/views/components-doc/composition/utils.ts
+++ b/examples/sites/src/views/components-doc/composition/utils.ts
@@ -4,13 +4,23 @@
*/
import type { ChatMessage, ChatCompletionResponse, StreamHandler } from '@opentiny/tiny-robot-kit'
+import type { ChatCompletionRequest } from '@opentiny/tiny-robot-kit'
+import type { Ref } from 'vue'
+export const globalConversation = {
+ id: ''
+}
/**
* 处理SSE流式响应
* @param response fetch响应对象
* @param handler 流处理器
*/
-export async function handleSSEStream(response: Response, handler: StreamHandler, signal?: AbortSignal): Promise {
+export async function handleSSEStream(
+ response: Response,
+ handler: StreamHandler,
+ message: Ref,
+ signal?: AbortSignal
+): Promise {
// 获取ReadableStream
const reader = response.body?.getReader()
if (!reader) {
@@ -64,6 +74,7 @@ export async function handleSSEStream(response: Response, handler: StreamHandler
if (!dataMatch) continue
const data = JSON.parse(dataMatch[1])
+ // console.log('SSE data:', data)
if (data?.event === 'workflow_started') {
handler.onData({
id: data.workflow_run_id,
@@ -73,7 +84,7 @@ export async function handleSSEStream(response: Response, handler: StreamHandler
index: messageIndex++,
delta: {
role: 'assistant',
- content: '**Workflow started** \r\n'
+ content: ' '
},
finish_reason: null
}
@@ -81,6 +92,10 @@ export async function handleSSEStream(response: Response, handler: StreamHandler
object: '',
model: ''
})
+ message.value.slice(-1)[0].loading = true
+ if (!globalConversation.id) {
+ globalConversation.id = data.conversation_id
+ }
}
if (data?.event === 'message' && data?.answer) {
@@ -100,6 +115,7 @@ export async function handleSSEStream(response: Response, handler: StreamHandler
object: '',
model: ''
})
+ message.value.slice(-1)[0].loading = false
}
if (data?.event === 'message_end') {
handler.onData({
@@ -118,6 +134,7 @@ export async function handleSSEStream(response: Response, handler: StreamHandler
object: '',
model: ''
})
+ message.value.slice(-1)[0].loading = false
}
// handler.onData(data)
} catch (error) {
diff --git a/examples/sites/src/views/components-doc/tiny-robot-chat.vue b/examples/sites/src/views/components-doc/tiny-robot-chat.vue
index de07c9e0d9..5d0749003e 100644
--- a/examples/sites/src/views/components-doc/tiny-robot-chat.vue
+++ b/examples/sites/src/views/components-doc/tiny-robot-chat.vue
@@ -1,22 +1,6 @@
-
-
-
-
-
-
-
-
+
@@ -33,8 +17,7 @@
@item-click="handlePromptItemClick"
>
-
-
+
@@ -56,50 +39,37 @@
+