@liujitcn/kratos-taro-app-system 0.0.17 → 0.0.19
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/package.json +5 -3
- package/src/rpc/base/v1/ai_message.ts +1 -1
- package/src/rpc/base/v1/ai_session.ts +2 -2
- package/src/rpc/base/v1/ai_tool.ts +2 -2
- package/src/rpc/{common → base}/v1/enum.ts +22 -39
- package/src/rpc/google/protobuf/timestamp.ts +1 -1
- package/src/views/pagesMember/ai/components/Composer.tsx +4 -4
- package/src/views/pagesMember/ai/index.scss +19 -0
- package/src/views/pagesMember/ai/index.tsx +20 -14
package/package.json
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"type": "git",
|
|
8
8
|
"url": "git@github.com:liujitcn/kratos-admin.git"
|
|
9
9
|
},
|
|
10
|
-
"version": "0.0.
|
|
10
|
+
"version": "0.0.19",
|
|
11
11
|
"type": "module",
|
|
12
12
|
"files": [
|
|
13
13
|
"dist",
|
|
@@ -21,6 +21,8 @@
|
|
|
21
21
|
"import": "./dist/build.mjs",
|
|
22
22
|
"default": "./dist/build.mjs"
|
|
23
23
|
},
|
|
24
|
+
"./api/*": "./src/api/*",
|
|
25
|
+
"./rpc/*": "./src/rpc/*",
|
|
24
26
|
"./views/*": "./src/views/*",
|
|
25
27
|
"./package.json": "./package.json"
|
|
26
28
|
},
|
|
@@ -31,8 +33,8 @@
|
|
|
31
33
|
"@tarojs/components": "4.2.1",
|
|
32
34
|
"@tarojs/taro": "4.2.1",
|
|
33
35
|
"react": "18.3.1",
|
|
34
|
-
"@liujitcn/kratos-taro-app-
|
|
35
|
-
"@liujitcn/kratos-taro-app-
|
|
36
|
+
"@liujitcn/kratos-taro-app-core": "^0.0.19",
|
|
37
|
+
"@liujitcn/kratos-taro-app-ui": "^0.0.19"
|
|
36
38
|
},
|
|
37
39
|
"scripts": {
|
|
38
40
|
"build": "pnpm run build:entries && pnpm pack --pack-destination ../../../dist/npm",
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
|
2
2
|
// versions:
|
|
3
|
-
// protoc-gen-ts_proto v2.
|
|
3
|
+
// protoc-gen-ts_proto v2.11.8
|
|
4
4
|
// protoc unknown
|
|
5
5
|
// source: base/v1/ai_session.proto
|
|
6
6
|
|
|
7
7
|
/* eslint-disable */
|
|
8
|
-
import type { AiMessageStatus, Terminal } from "../../common/v1/enum";
|
|
9
8
|
import type { Timestamp } from "../../google/protobuf/timestamp";
|
|
10
9
|
import type { AiToolCall } from "./ai_tool";
|
|
10
|
+
import type { AiMessageStatus, Terminal } from "./enum";
|
|
11
11
|
|
|
12
12
|
/** AI 助手消息列表查询条件 */
|
|
13
13
|
export interface ListAiMessageRequest {
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
|
2
2
|
// versions:
|
|
3
|
-
// protoc-gen-ts_proto v2.
|
|
3
|
+
// protoc-gen-ts_proto v2.11.8
|
|
4
4
|
// protoc unknown
|
|
5
5
|
// source: base/v1/ai_tool.proto
|
|
6
6
|
|
|
7
7
|
/* eslint-disable */
|
|
8
|
-
import type { Terminal } from "
|
|
8
|
+
import type { Terminal } from "./enum";
|
|
9
9
|
|
|
10
10
|
/** AI 助手快捷入口列表查询条件 */
|
|
11
11
|
export interface ListAiShortcutRequest {
|
|
@@ -1,18 +1,31 @@
|
|
|
1
1
|
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
|
2
2
|
// versions:
|
|
3
|
-
// protoc-gen-ts_proto v2.
|
|
3
|
+
// protoc-gen-ts_proto v2.11.8
|
|
4
4
|
// protoc unknown
|
|
5
|
-
// source:
|
|
5
|
+
// source: base/v1/enum.proto
|
|
6
6
|
|
|
7
7
|
/* eslint-disable */
|
|
8
8
|
|
|
9
|
-
/**
|
|
10
|
-
export enum
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
9
|
+
/** AI 助手消息状态 */
|
|
10
|
+
export enum AiMessageStatus {
|
|
11
|
+
/** UNKNOWN_AMS - 未知AI助手消息状态 */
|
|
12
|
+
UNKNOWN_AMS = 0,
|
|
13
|
+
/** GENERATING_AMS - 生成中 */
|
|
14
|
+
GENERATING_AMS = 1,
|
|
15
|
+
/** SUCCESS_AMS - 成功 */
|
|
16
|
+
SUCCESS_AMS = 2,
|
|
17
|
+
/** FAILED_AMS - 失败 */
|
|
18
|
+
FAILED_AMS = 3,
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/** 终端类型 */
|
|
22
|
+
export enum Terminal {
|
|
23
|
+
/** UNKNOWN_TERMINAL - 未知终端 */
|
|
24
|
+
UNKNOWN_TERMINAL = 0,
|
|
25
|
+
/** TERMINAL_APP - 移动端 */
|
|
26
|
+
TERMINAL_APP = 1,
|
|
27
|
+
/** TERMINAL_ADMIN - 管理端 */
|
|
28
|
+
TERMINAL_ADMIN = 2,
|
|
16
29
|
}
|
|
17
30
|
|
|
18
31
|
/** 系统配置位置 */
|
|
@@ -39,33 +52,3 @@ export enum PasswordCryptoScene {
|
|
|
39
52
|
/** UPDATE_USER_PASSWORD - 个人修改密码加密场景 */
|
|
40
53
|
UPDATE_USER_PASSWORD = 4,
|
|
41
54
|
}
|
|
42
|
-
|
|
43
|
-
/** AI 助手消息状态 */
|
|
44
|
-
export enum AiMessageStatus {
|
|
45
|
-
/** UNKNOWN_AAMS - 未知AI助手消息状态 */
|
|
46
|
-
UNKNOWN_AAMS = 0,
|
|
47
|
-
/** GENERATING_AAMS - 生成中 */
|
|
48
|
-
GENERATING_AAMS = 1,
|
|
49
|
-
/** SUCCESS_AAMS - 成功 */
|
|
50
|
-
SUCCESS_AAMS = 2,
|
|
51
|
-
/** FAILED_AAMS - 失败 */
|
|
52
|
-
FAILED_AAMS = 3,
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/** 支付通知资源类型 */
|
|
56
|
-
export enum ResourceType {
|
|
57
|
-
/** TRANSACTION - 支付 */
|
|
58
|
-
TRANSACTION = 0,
|
|
59
|
-
/** REFUND - 退款 */
|
|
60
|
-
REFUND = 1,
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/** 终端类型 */
|
|
64
|
-
export enum Terminal {
|
|
65
|
-
/** TERMINAL_UNSPECIFIED - 未知终端 */
|
|
66
|
-
TERMINAL_UNSPECIFIED = 0,
|
|
67
|
-
/** TERMINAL_APP - 移动端 */
|
|
68
|
-
TERMINAL_APP = 1,
|
|
69
|
-
/** TERMINAL_ADMIN - 管理端 */
|
|
70
|
-
TERMINAL_ADMIN = 2,
|
|
71
|
-
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Button, Text, Textarea, View } from '@tarojs/components'
|
|
2
|
-
import {
|
|
2
|
+
import { UniIcon } from '@liujitcn/kratos-taro-app-ui'
|
|
3
3
|
import type { AiAttachment } from '../../../../rpc/base/v1/ai_session'
|
|
4
4
|
import './composer.scss'
|
|
5
5
|
|
|
@@ -24,7 +24,7 @@ export default function Composer(props: ComposerProps) {
|
|
|
24
24
|
<View className='composer' style={{ paddingBottom: props.bottom }}>
|
|
25
25
|
<View className='composer-main'>
|
|
26
26
|
<Button className='attach-button' hoverClass='none' onClick={props.onAttach}>
|
|
27
|
-
<
|
|
27
|
+
<UniIcon type='plusempty' size={30} color='#111' />
|
|
28
28
|
</Button>
|
|
29
29
|
<View className='composer-card'>
|
|
30
30
|
{props.attachments.length ? (
|
|
@@ -54,7 +54,7 @@ export default function Composer(props: ComposerProps) {
|
|
|
54
54
|
hoverClass='none'
|
|
55
55
|
onClick={props.onRecord}
|
|
56
56
|
>
|
|
57
|
-
<
|
|
57
|
+
<UniIcon type='mic' size={28} color={props.recording ? '#00a96b' : '#111'} />
|
|
58
58
|
</Button>
|
|
59
59
|
</View>
|
|
60
60
|
<Button
|
|
@@ -63,7 +63,7 @@ export default function Composer(props: ComposerProps) {
|
|
|
63
63
|
hoverClass='none'
|
|
64
64
|
onClick={props.onSend}
|
|
65
65
|
>
|
|
66
|
-
<
|
|
66
|
+
<UniIcon type='paperplane' size={28} color={props.disabled ? '#111' : '#00a96b'} />
|
|
67
67
|
</Button>
|
|
68
68
|
</View>
|
|
69
69
|
</View>
|
|
@@ -28,10 +28,29 @@ page {
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
.ai-navbar.is-weapp {
|
|
31
|
+
position: relative;
|
|
31
32
|
height: 88PX;
|
|
32
33
|
padding-top: 44PX;
|
|
33
34
|
}
|
|
34
35
|
|
|
36
|
+
.ai-navbar.is-weapp .nav-back-button,
|
|
37
|
+
.ai-navbar.is-weapp .nav-menu-button {
|
|
38
|
+
position: absolute;
|
|
39
|
+
bottom: 0;
|
|
40
|
+
height: 44PX;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.ai-navbar.is-weapp .nav-back-button { left: 0; }
|
|
44
|
+
.ai-navbar.is-weapp .nav-menu-button {
|
|
45
|
+
left: 56px;
|
|
46
|
+
right: auto;
|
|
47
|
+
}
|
|
48
|
+
.ai-navbar.is-weapp .ai-navbar__title {
|
|
49
|
+
width: 100%;
|
|
50
|
+
height: 44PX;
|
|
51
|
+
line-height: 44PX;
|
|
52
|
+
}
|
|
53
|
+
|
|
35
54
|
.nav-back-button,
|
|
36
55
|
.nav-menu-button {
|
|
37
56
|
display: flex;
|
|
@@ -6,13 +6,13 @@ import {
|
|
|
6
6
|
navigateAppRoute,
|
|
7
7
|
uploadFile,
|
|
8
8
|
} from '@liujitcn/kratos-taro-app-core'
|
|
9
|
-
import {
|
|
9
|
+
import { UniIcon } from '@liujitcn/kratos-taro-app-ui'
|
|
10
10
|
import { defAiMessageService, StreamAiMessageByChunkedRequest } from '../../../api/base/ai_message'
|
|
11
11
|
import { defAiSessionService } from '../../../api/base/ai_session'
|
|
12
12
|
import { defAiToolService } from '../../../api/base/ai_tool'
|
|
13
13
|
import type { AiAttachment, AiMessage, AiSession } from '../../../rpc/base/v1/ai_session'
|
|
14
14
|
import type { AiShortcut, AiToolCall } from '../../../rpc/base/v1/ai_tool'
|
|
15
|
-
import { AiMessageStatus, Terminal } from '../../../rpc/
|
|
15
|
+
import { AiMessageStatus, Terminal } from '../../../rpc/base/v1/enum'
|
|
16
16
|
import Composer from './components/Composer'
|
|
17
17
|
import SessionDrawer from './components/SessionDrawer'
|
|
18
18
|
import WelcomePanel from './components/WelcomePanel'
|
|
@@ -70,7 +70,13 @@ export default function AiPage() {
|
|
|
70
70
|
}
|
|
71
71
|
let safeAreaTop = windowInfo.safeArea?.top || windowInfo.statusBarHeight || windowInfo.safeAreaInsets?.top || 0
|
|
72
72
|
if (process.env.TARO_ENV === 'weapp') safeAreaTop ||= 44
|
|
73
|
-
|
|
73
|
+
// 部分微信基础库只返回 safeArea 坐标,需要用屏幕高度反推底部安全区。
|
|
74
|
+
const measuredSafeAreaBottom =
|
|
75
|
+
windowInfo.safeAreaInsets?.bottom ??
|
|
76
|
+
(windowInfo.screenHeight && windowInfo.safeArea?.bottom
|
|
77
|
+
? Math.max(windowInfo.screenHeight - windowInfo.safeArea.bottom, 0)
|
|
78
|
+
: 0)
|
|
79
|
+
const safeAreaBottom = Math.max(measuredSafeAreaBottom, 9)
|
|
74
80
|
const composerBottom = `${safeAreaBottom + 48}px`
|
|
75
81
|
const drawerTopPadding = `${safeAreaTop + 12}px`
|
|
76
82
|
|
|
@@ -605,11 +611,11 @@ export default function AiPage() {
|
|
|
605
611
|
<View className='ai-page'>
|
|
606
612
|
<View className={`ai-navbar${process.env.TARO_ENV === 'weapp' ? ' is-weapp' : ''}`}>
|
|
607
613
|
<Button className='nav-back-button' hoverClass='none' onClick={navigateBack}>
|
|
608
|
-
<
|
|
614
|
+
<UniIcon type='left' size={24} color='#111' />
|
|
609
615
|
</Button>
|
|
610
616
|
<View className='ai-navbar__title'>AI 助手</View>
|
|
611
617
|
<Button className='nav-menu-button' hoverClass='none' onClick={() => setShowSessionDrawer((open) => !open)}>
|
|
612
|
-
<
|
|
618
|
+
<UniIcon type='bars' size={24} color='#111' />
|
|
613
619
|
</Button>
|
|
614
620
|
</View>
|
|
615
621
|
<ScrollView
|
|
@@ -641,7 +647,7 @@ export default function AiPage() {
|
|
|
641
647
|
className={`message-row ${item.role === 'user' ? 'is-user' : 'is-ai'}`}
|
|
642
648
|
>
|
|
643
649
|
<View
|
|
644
|
-
className={`bubble ${item.role === 'ai' ? 'ai-bubble' : 'user-bubble'}${item.status === AiMessageStatus.
|
|
650
|
+
className={`bubble ${item.role === 'ai' ? 'ai-bubble' : 'user-bubble'}${item.status === AiMessageStatus.GENERATING_AMS ? ' is-streaming' : ''}`}
|
|
645
651
|
onLongPress={() => void handleMessageAction(item)}
|
|
646
652
|
>
|
|
647
653
|
{item.role === 'ai' && item.model ? (
|
|
@@ -743,7 +749,7 @@ function normalizeMessageList(list?: AiMessage[] | null) {
|
|
|
743
749
|
}
|
|
744
750
|
|
|
745
751
|
function hasSuccessfulAiMessages(list: ChatMessageItem[]) {
|
|
746
|
-
return list.some((item) => item.status === AiMessageStatus.
|
|
752
|
+
return list.some((item) => item.status === AiMessageStatus.SUCCESS_AMS)
|
|
747
753
|
}
|
|
748
754
|
|
|
749
755
|
function mapMessageItem(message: AiMessage, role: ChatRole): ChatMessageItem {
|
|
@@ -759,7 +765,7 @@ function mapMessageItem(message: AiMessage, role: ChatRole): ChatMessageItem {
|
|
|
759
765
|
step: message.output_content?.step ?? '',
|
|
760
766
|
blocks_json: message.output_content?.blocks_json ?? '',
|
|
761
767
|
}
|
|
762
|
-
const status = Number(message.status ?? AiMessageStatus.
|
|
768
|
+
const status = Number(message.status ?? AiMessageStatus.SUCCESS_AMS)
|
|
763
769
|
return {
|
|
764
770
|
...message,
|
|
765
771
|
key: `${message.id}:${role}`,
|
|
@@ -795,14 +801,14 @@ function createLocalUserMessage(payload: { text: string; attachments: AiAttachme
|
|
|
795
801
|
output_content: undefined,
|
|
796
802
|
attachments: payload.attachments,
|
|
797
803
|
created_at: { seconds: Math.floor(now / 1000), nanos: (now % 1000) * 1_000_000 },
|
|
798
|
-
status: AiMessageStatus.
|
|
804
|
+
status: AiMessageStatus.GENERATING_AMS,
|
|
799
805
|
token: { input: 0, output: 0, cache: 0, total: 0 },
|
|
800
806
|
tools: [],
|
|
801
807
|
first_token_ms: 0,
|
|
802
808
|
duration_ms: 0,
|
|
803
809
|
}, 'user')
|
|
804
810
|
message.localOnly = true
|
|
805
|
-
message.status = AiMessageStatus.
|
|
811
|
+
message.status = AiMessageStatus.GENERATING_AMS
|
|
806
812
|
return message
|
|
807
813
|
}
|
|
808
814
|
|
|
@@ -820,7 +826,7 @@ function createThinkingMessage(options?: { sessionID?: string; messageID?: strin
|
|
|
820
826
|
},
|
|
821
827
|
attachments: [],
|
|
822
828
|
created_at: { seconds: Math.floor(now / 1000), nanos: (now % 1000) * 1_000_000 },
|
|
823
|
-
status: AiMessageStatus.
|
|
829
|
+
status: AiMessageStatus.GENERATING_AMS,
|
|
824
830
|
token: { input: 0, output: 0, cache: 0, total: 0 },
|
|
825
831
|
tools: [],
|
|
826
832
|
first_token_ms: 0,
|
|
@@ -854,7 +860,7 @@ function appendStreamingDelta(current: ChatMessageItem[], payload: AiStreamPaylo
|
|
|
854
860
|
return current.map((item) => {
|
|
855
861
|
if (item.streamKey !== streamKey || item.role === 'user') return item
|
|
856
862
|
const baseContent = item.content === THINKING_MESSAGE_CONTENT ? '' : item.content
|
|
857
|
-
return { ...item, content: `${baseContent}${payload.delta}`, status: AiMessageStatus.
|
|
863
|
+
return { ...item, content: `${baseContent}${payload.delta}`, status: AiMessageStatus.GENERATING_AMS }
|
|
858
864
|
})
|
|
859
865
|
}
|
|
860
866
|
|
|
@@ -863,7 +869,7 @@ function markThinkingMessageFailed(current: ChatMessageItem[]) {
|
|
|
863
869
|
item.localOnly
|
|
864
870
|
? {
|
|
865
871
|
...item,
|
|
866
|
-
status: AiMessageStatus.
|
|
872
|
+
status: AiMessageStatus.FAILED_AMS,
|
|
867
873
|
content: item.role === 'ai' ? '这次回复没有成功返回,你可以直接重试刚才的问题。' : item.content,
|
|
868
874
|
}
|
|
869
875
|
: item,
|
|
@@ -874,7 +880,7 @@ function markStreamingError(current: ChatMessageItem[], payload: AiStreamPayload
|
|
|
874
880
|
const streamKey = buildStreamMessageKey(payload.session_id, payload.message_id)
|
|
875
881
|
return current.map((item) =>
|
|
876
882
|
item.localOnly && item.streamKey === streamKey
|
|
877
|
-
? { ...item, status: AiMessageStatus.
|
|
883
|
+
? { ...item, status: AiMessageStatus.FAILED_AMS, content: '这次回复没有成功返回,你可以直接重试刚才的问题。' }
|
|
878
884
|
: item,
|
|
879
885
|
)
|
|
880
886
|
}
|