@lobehub/lobehub 2.0.0-next.38 → 2.0.0-next.39

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.
Files changed (103) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/apps/desktop/src/main/modules/networkProxy/__tests__/dispatcher.test.ts +401 -0
  3. package/apps/desktop/src/main/modules/networkProxy/__tests__/tester.test.ts +531 -0
  4. package/apps/desktop/src/main/modules/networkProxy/__tests__/urlBuilder.test.ts +349 -0
  5. package/apps/desktop/src/main/modules/networkProxy/__tests__/validator.test.ts +492 -0
  6. package/changelog/v1.json +5 -0
  7. package/locales/ar/auth.json +45 -1
  8. package/locales/bg-BG/auth.json +45 -1
  9. package/locales/de-DE/auth.json +45 -1
  10. package/locales/en-US/auth.json +45 -1
  11. package/locales/es-ES/auth.json +45 -1
  12. package/locales/fa-IR/auth.json +45 -1
  13. package/locales/fr-FR/auth.json +45 -1
  14. package/locales/it-IT/auth.json +45 -1
  15. package/locales/ja-JP/auth.json +45 -1
  16. package/locales/ko-KR/auth.json +45 -1
  17. package/locales/nl-NL/auth.json +45 -1
  18. package/locales/pl-PL/auth.json +45 -1
  19. package/locales/pt-BR/auth.json +45 -1
  20. package/locales/ru-RU/auth.json +45 -1
  21. package/locales/tr-TR/auth.json +45 -1
  22. package/locales/vi-VN/auth.json +45 -1
  23. package/locales/zh-CN/auth.json +45 -1
  24. package/locales/zh-TW/auth.json +45 -1
  25. package/package.json +1 -1
  26. package/packages/context-engine/src/processors/MessageCleanup.ts +1 -0
  27. package/packages/context-engine/src/processors/__tests__/MessageCleanup.test.ts +28 -0
  28. package/packages/obervability-otel/package.json +3 -1
  29. package/packages/obervability-otel/src/api.ts +2 -0
  30. package/packages/obervability-otel/src/trpc/convention.ts +16 -0
  31. package/packages/obervability-otel/src/trpc/index.test.ts +38 -0
  32. package/packages/obervability-otel/src/trpc/index.ts +62 -0
  33. package/packages/obervability-otel/src/trpc/metrics.ts +31 -0
  34. package/packages/types/src/usage/usageRecord.ts +54 -0
  35. package/src/app/[variants]/(main)/profile/hooks/useCategory.tsx +10 -1
  36. package/src/app/[variants]/(main)/profile/usage/Client.tsx +114 -0
  37. package/src/app/[variants]/(main)/profile/usage/features/UsageCards/ActiveModels/ModelTable.tsx +175 -0
  38. package/src/app/[variants]/(main)/profile/usage/features/UsageCards/ActiveModels/index.tsx +126 -0
  39. package/src/app/[variants]/(main)/profile/usage/features/UsageCards/MonthSpend.tsx +53 -0
  40. package/src/app/[variants]/(main)/profile/usage/features/UsageCards/TodaySpend.tsx +67 -0
  41. package/src/app/[variants]/(main)/profile/usage/features/UsageCards/index.tsx +19 -0
  42. package/src/app/[variants]/(main)/profile/usage/features/UsageTable.tsx +145 -0
  43. package/src/app/[variants]/(main)/profile/usage/features/UsageTrends.tsx +107 -0
  44. package/src/app/[variants]/(main)/profile/usage/features/components/UsageBarChart.tsx +48 -0
  45. package/src/app/[variants]/(main)/profile/usage/page.tsx +23 -0
  46. package/src/features/Conversation/Messages/Assistant/Tool/Render/CustomRender.tsx +3 -3
  47. package/src/features/Conversation/Messages/Group/Actions/WithoutContentId.tsx +37 -14
  48. package/src/features/Conversation/Messages/Group/Error/index.tsx +1 -1
  49. package/src/features/Conversation/Messages/Group/GroupChildren.tsx +13 -35
  50. package/src/features/Conversation/Messages/Group/GroupItem.tsx +43 -0
  51. package/src/features/Conversation/Messages/Group/Tool/Inspector/index.tsx +1 -2
  52. package/src/features/Conversation/Messages/Group/Tool/Render/CustomRender.tsx +1 -1
  53. package/src/features/Conversation/Messages/Group/Tool/index.tsx +0 -2
  54. package/src/features/Conversation/Messages/Group/index.tsx +7 -2
  55. package/src/features/Conversation/hooks/useChatListActionsBar.tsx +21 -7
  56. package/src/features/PluginsUI/Render/BuiltinType/index.tsx +1 -1
  57. package/src/features/PluginsUI/Render/MCPType/index.tsx +52 -0
  58. package/src/features/PluginsUI/Render/StandaloneType/Iframe.tsx +2 -2
  59. package/src/features/PluginsUI/Render/index.tsx +17 -0
  60. package/src/libs/mcp/client.ts +3 -2
  61. package/src/libs/mcp/types.ts +71 -0
  62. package/src/libs/trpc/lambda/index.ts +5 -2
  63. package/src/libs/trpc/middleware/openTelemetry.ts +141 -0
  64. package/src/locales/default/auth.ts +44 -0
  65. package/src/locales/default/chat.ts +1 -0
  66. package/src/server/routers/desktop/mcp.ts +1 -3
  67. package/src/server/routers/lambda/index.ts +2 -0
  68. package/src/server/routers/lambda/usage.ts +36 -0
  69. package/src/server/routers/tools/mcp.ts +1 -3
  70. package/src/server/services/mcp/index.test.ts +28 -15
  71. package/src/server/services/mcp/index.ts +29 -18
  72. package/src/server/services/usage/index.test.ts +310 -0
  73. package/src/server/services/usage/index.ts +164 -0
  74. package/src/services/chat/contextEngineering.test.ts +4 -0
  75. package/src/services/mcp.test.ts +7 -1
  76. package/src/services/mcp.ts +13 -12
  77. package/src/services/usage.ts +13 -0
  78. package/src/store/chat/agents/createAgentExecutors.ts +2 -3
  79. package/src/store/chat/slices/aiChat/actions/conversationLifecycle.ts +40 -1
  80. package/src/store/chat/slices/aiChat/actions/streamingExecutor.ts +13 -5
  81. package/src/store/chat/slices/builtinTool/actions/__tests__/localSystem.test.ts +3 -3
  82. package/src/store/chat/slices/builtinTool/actions/__tests__/search.test.ts +6 -6
  83. package/src/store/chat/slices/builtinTool/actions/interpreter.ts +2 -2
  84. package/src/store/chat/slices/builtinTool/actions/localSystem.ts +2 -2
  85. package/src/store/chat/slices/builtinTool/actions/search.ts +6 -6
  86. package/src/store/chat/slices/message/actions/publicApi.ts +19 -1
  87. package/src/store/chat/slices/message/initialState.ts +5 -0
  88. package/src/store/chat/slices/message/selectors/chat.test.ts +22 -602
  89. package/src/store/chat/slices/message/selectors/chat.ts +0 -2
  90. package/src/store/chat/slices/message/selectors/dbMessage.test.ts +51 -0
  91. package/src/store/chat/slices/message/selectors/displayMessage.test.ts +818 -0
  92. package/src/store/chat/slices/message/selectors/displayMessage.ts +52 -1
  93. package/src/store/chat/slices/message/selectors/messageState.ts +2 -0
  94. package/src/store/chat/slices/plugin/action.test.ts +4 -4
  95. package/src/store/chat/slices/plugin/actions/index.ts +39 -0
  96. package/src/store/chat/slices/plugin/actions/internals.ts +83 -0
  97. package/src/store/chat/slices/plugin/actions/optimisticUpdate.ts +188 -0
  98. package/src/store/chat/slices/plugin/actions/pluginTypes.ts +213 -0
  99. package/src/store/chat/slices/plugin/actions/publicApi.ts +115 -0
  100. package/src/store/chat/slices/plugin/actions/workflow.ts +121 -0
  101. package/src/store/chat/store.ts +1 -1
  102. package/src/store/global/initialState.ts +1 -0
  103. package/src/store/chat/slices/plugin/action.ts +0 -539
@@ -0,0 +1,115 @@
1
+ /* eslint-disable sort-keys-fix/sort-keys-fix, typescript-sort-keys/interface */
2
+ import { ChatToolPayload, UIChatMessage } from '@lobechat/types';
3
+ import { StateCreator } from 'zustand/vanilla';
4
+
5
+ import { ChatStore } from '@/store/chat/store';
6
+
7
+ import { displayMessageSelectors } from '../../message/selectors';
8
+
9
+ /**
10
+ * Public API for plugin operations
11
+ * These methods are called by UI components or other business scenarios
12
+ */
13
+ export interface PluginPublicApiAction {
14
+ /**
15
+ * Fill plugin message content and optionally trigger AI message
16
+ */
17
+ fillPluginMessageContent: (
18
+ id: string,
19
+ content: string,
20
+ triggerAiMessage?: boolean,
21
+ ) => Promise<void>;
22
+
23
+ /**
24
+ * Re-invoke a tool message (retry failed plugin call)
25
+ */
26
+ reInvokeToolMessage: (id: string) => Promise<void>;
27
+
28
+ /**
29
+ * Summary plugin content using AI
30
+ */
31
+ summaryPluginContent: (id: string) => Promise<void>;
32
+
33
+ /**
34
+ * Invoke different type of plugin based on payload type
35
+ * This is the unified entry point for plugin invocation
36
+ */
37
+ internal_invokeDifferentTypePlugin: (id: string, payload: ChatToolPayload) => Promise<any>;
38
+ }
39
+
40
+ export const pluginPublicApi: StateCreator<
41
+ ChatStore,
42
+ [['zustand/devtools', never]],
43
+ [],
44
+ PluginPublicApiAction
45
+ > = (set, get) => ({
46
+ fillPluginMessageContent: async (id, content, triggerAiMessage) => {
47
+ const { triggerAIMessage, optimisticUpdateMessageContent } = get();
48
+
49
+ await optimisticUpdateMessageContent(id, content);
50
+
51
+ if (triggerAiMessage) await triggerAIMessage({ parentId: id });
52
+ },
53
+
54
+ reInvokeToolMessage: async (id) => {
55
+ const message = displayMessageSelectors.getDisplayMessageById(id)(get());
56
+ if (!message || message.role !== 'tool' || !message.plugin) return;
57
+
58
+ // if there is error content, then clear the error
59
+ if (!!message.pluginError) {
60
+ get().optimisticUpdateMessagePluginError(id, null);
61
+ }
62
+
63
+ const payload: ChatToolPayload = { ...message.plugin, id: message.tool_call_id! };
64
+
65
+ await get().internal_invokeDifferentTypePlugin(id, payload);
66
+ },
67
+
68
+ summaryPluginContent: async (id) => {
69
+ const message = displayMessageSelectors.getDisplayMessageById(id)(get());
70
+ if (!message || message.role !== 'tool') return;
71
+
72
+ await get().internal_execAgentRuntime({
73
+ messages: [
74
+ {
75
+ role: 'assistant',
76
+ content: '作为一名总结专家,请结合以上系统提示词,将以下内容进行总结:',
77
+ },
78
+ {
79
+ ...message,
80
+ content: message.content,
81
+ role: 'assistant',
82
+ name: undefined,
83
+ tool_call_id: undefined,
84
+ },
85
+ ] as UIChatMessage[],
86
+ parentMessageId: message.id,
87
+ parentMessageType: 'assistant',
88
+ });
89
+ },
90
+
91
+ internal_invokeDifferentTypePlugin: async (id, payload) => {
92
+ switch (payload.type) {
93
+ case 'standalone': {
94
+ return await get().invokeStandaloneTypePlugin(id, payload);
95
+ }
96
+
97
+ case 'markdown': {
98
+ return await get().invokeMarkdownTypePlugin(id, payload);
99
+ }
100
+
101
+ case 'builtin': {
102
+ return await get().invokeBuiltinTool(id, payload);
103
+ }
104
+
105
+ // @ts-ignore
106
+ case 'mcp': {
107
+ return await get().invokeMCPTypePlugin(id, payload);
108
+ }
109
+
110
+ default: {
111
+ return await get().invokeDefaultTypePlugin(id, payload);
112
+ }
113
+ }
114
+ },
115
+ });
@@ -0,0 +1,121 @@
1
+ /* eslint-disable sort-keys-fix/sort-keys-fix, typescript-sort-keys/interface */
2
+ import { CreateMessageParams } from '@lobechat/types';
3
+ import { StateCreator } from 'zustand/vanilla';
4
+
5
+ import { messageService } from '@/services/message';
6
+ import { ChatStore } from '@/store/chat/store';
7
+
8
+ import { dbMessageSelectors, displayMessageSelectors } from '../../message/selectors';
9
+ import { threadSelectors } from '../../thread/selectors';
10
+
11
+ /**
12
+ * Workflow orchestration actions
13
+ * Handle complex business flows involving multiple steps
14
+ */
15
+ export interface PluginWorkflowAction {
16
+ /**
17
+ * Create an assistant message by plugin result
18
+ */
19
+ createAssistantMessageByPlugin: (content: string, parentId: string) => Promise<void>;
20
+
21
+ /**
22
+ * Trigger AI message after tool calls
23
+ */
24
+ triggerAIMessage: (params: {
25
+ parentId?: string;
26
+ traceId?: string;
27
+ threadId?: string;
28
+ inPortalThread?: boolean;
29
+ inSearchWorkflow?: boolean;
30
+ }) => Promise<void>;
31
+
32
+ /**
33
+ * Trigger tool calls (V1 deprecated method)
34
+ * @deprecated
35
+ */
36
+ triggerToolCalls: (
37
+ id: string,
38
+ params?: { threadId?: string; inPortalThread?: boolean; inSearchWorkflow?: boolean },
39
+ ) => Promise<void>;
40
+ }
41
+
42
+ export const pluginWorkflow: StateCreator<
43
+ ChatStore,
44
+ [['zustand/devtools', never]],
45
+ [],
46
+ PluginWorkflowAction
47
+ > = (set, get) => ({
48
+ createAssistantMessageByPlugin: async (content, parentId) => {
49
+ const newMessage: CreateMessageParams = {
50
+ content,
51
+ parentId,
52
+ role: 'assistant',
53
+ sessionId: get().activeId,
54
+ topicId: get().activeTopicId, // if there is activeTopicId,then add it to topicId
55
+ };
56
+
57
+ const result = await messageService.createMessage(newMessage);
58
+ get().replaceMessages(result.messages);
59
+ },
60
+
61
+ triggerAIMessage: async ({ parentId, traceId, threadId, inPortalThread, inSearchWorkflow }) => {
62
+ const { internal_execAgentRuntime } = get();
63
+
64
+ const chats = inPortalThread
65
+ ? threadSelectors.portalAIChatsWithHistoryConfig(get())
66
+ : displayMessageSelectors.mainAIChatsWithHistoryConfig(get());
67
+
68
+ await internal_execAgentRuntime({
69
+ messages: chats,
70
+ parentMessageId: parentId ?? chats.at(-1)!.id,
71
+ parentMessageType: 'user',
72
+ traceId,
73
+ threadId,
74
+ inPortalThread,
75
+ inSearchWorkflow,
76
+ });
77
+ },
78
+
79
+ triggerToolCalls: async (assistantId, { threadId, inPortalThread, inSearchWorkflow } = {}) => {
80
+ const message = displayMessageSelectors.getDisplayMessageById(assistantId)(get());
81
+ if (!message || !message.tools) return;
82
+
83
+ let shouldCreateMessage = false;
84
+ let latestToolId = '';
85
+ const messagePools = message.tools.map(async (payload) => {
86
+ const toolMessage: CreateMessageParams = {
87
+ content: '',
88
+ parentId: assistantId,
89
+ plugin: payload,
90
+ role: 'tool',
91
+ sessionId: get().activeId,
92
+ tool_call_id: payload.id,
93
+ threadId,
94
+ topicId: get().activeTopicId, // if there is activeTopicId,then add it to topicId
95
+ groupId: message.groupId, // Propagate groupId from parent message for group chat
96
+ };
97
+
98
+ const result = await get().optimisticCreateMessage(toolMessage);
99
+ if (!result) return;
100
+
101
+ // trigger the plugin call
102
+ const data = await get().internal_invokeDifferentTypePlugin(result.id, payload);
103
+
104
+ if (data && !['markdown', 'standalone'].includes(payload.type)) {
105
+ shouldCreateMessage = true;
106
+ latestToolId = result.id;
107
+ }
108
+ });
109
+
110
+ await Promise.all(messagePools);
111
+
112
+ await get().internal_toggleMessageInToolsCalling(false, assistantId);
113
+
114
+ // only default type tool calls should trigger AI message
115
+ if (!shouldCreateMessage) return;
116
+
117
+ const traceId = dbMessageSelectors.getTraceIdByDbMessageId(latestToolId)(get());
118
+
119
+ await get().triggerAIMessage({ traceId, threadId, inPortalThread, inSearchWorkflow });
120
+ },
121
+ });
@@ -10,7 +10,7 @@ import { ChatBuiltinToolAction, chatToolSlice } from './slices/builtinTool/actio
10
10
  import { ChatPortalAction, chatPortalSlice } from './slices/portal/action';
11
11
  import { ChatTranslateAction, chatTranslate } from './slices/translate/action';
12
12
  import { ChatMessageAction, chatMessage } from './slices/message/actions';
13
- import { ChatPluginAction, chatPlugin } from './slices/plugin/action';
13
+ import { ChatPluginAction, chatPlugin } from './slices/plugin/actions';
14
14
  import { ChatTopicAction, chatTopic } from './slices/topic/action';
15
15
  import { ChatAIChatAction, chatAiChat } from './slices/aiChat/actions';
16
16
  import { ChatTTSAction, chatTTS } from './slices/tts/action';
@@ -50,6 +50,7 @@ export enum ProfileTabs {
50
50
  Profile = 'profile',
51
51
  Security = 'security',
52
52
  Stats = 'stats',
53
+ Usage = 'usage',
53
54
  }
54
55
 
55
56
  export interface SystemStatus {