@yushaw/sanqian-chat 0.1.1

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.
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __copyProps = (to, from, except, desc) => {
7
+ if (from && typeof from === "object" || typeof from === "function") {
8
+ for (let key of __getOwnPropNames(from))
9
+ if (!__hasOwnProp.call(to, key) && key !== except)
10
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
11
+ }
12
+ return to;
13
+ };
14
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
15
+
16
+ // src/preload/index.ts
17
+ var preload_exports = {};
18
+ module.exports = __toCommonJS(preload_exports);
19
+ var import_electron = require("electron");
20
+ var api = {
21
+ connect: () => import_electron.ipcRenderer.invoke("sanqian-chat:connect"),
22
+ isConnected: () => import_electron.ipcRenderer.invoke("sanqian-chat:isConnected"),
23
+ stream: (params) => import_electron.ipcRenderer.invoke("sanqian-chat:stream", params),
24
+ cancelStream: (params) => import_electron.ipcRenderer.invoke("sanqian-chat:cancelStream", params),
25
+ onStreamEvent: (callback) => {
26
+ const handler = (_, data) => {
27
+ callback(data.streamId, data.event);
28
+ };
29
+ import_electron.ipcRenderer.on("sanqian-chat:streamEvent", handler);
30
+ return () => import_electron.ipcRenderer.removeListener("sanqian-chat:streamEvent", handler);
31
+ },
32
+ sendHitlResponse: (params) => import_electron.ipcRenderer.invoke("sanqian-chat:hitlResponse", params),
33
+ listConversations: (params) => import_electron.ipcRenderer.invoke("sanqian-chat:listConversations", params),
34
+ getConversation: (params) => import_electron.ipcRenderer.invoke("sanqian-chat:getConversation", params),
35
+ deleteConversation: (params) => import_electron.ipcRenderer.invoke("sanqian-chat:deleteConversation", params),
36
+ hide: () => import_electron.ipcRenderer.invoke("sanqian-chat:hide")
37
+ };
38
+ import_electron.contextBridge.exposeInMainWorld("sanqianChat", api);
@@ -0,0 +1,340 @@
1
+ import { HitlInterruptPayload, HitlResponse, SanqianSDK } from '@yushaw/sanqian-sdk';
2
+ export { ChatStreamEvent, HitlInterruptPayload, HitlInterruptType, HitlResponse, HitlRiskLevel, ChatMessage as SdkChatMessage, ConversationDetail as SdkConversationDetail, ConversationInfo as SdkConversationInfo, ToolCall as SdkToolCall } from '@yushaw/sanqian-sdk';
3
+ import * as react_jsx_runtime from 'react/jsx-runtime';
4
+ import * as react from 'react';
5
+ import { ReactNode } from 'react';
6
+
7
+ /**
8
+ * @yushaw/sanqian-chat Core Types
9
+ *
10
+ * Re-exports SDK types + chat-specific types
11
+ */
12
+
13
+ type MessageRole = 'user' | 'assistant' | 'system';
14
+ type ToolCallStatus = 'pending' | 'running' | 'completed' | 'error' | 'cancelled';
15
+ type ConnectionStatus = 'disconnected' | 'connecting' | 'connected' | 'reconnecting' | 'error';
16
+ type ConnectionErrorCode = 'NOT_FOUND' | 'CONNECTION_FAILED' | 'WEBSOCKET_ERROR' | 'AUTH_ERROR' | 'TIMEOUT' | 'UNKNOWN';
17
+ /** Tool call for UI rendering (extended from SDK) */
18
+ interface ToolCall {
19
+ id: string;
20
+ name: string;
21
+ arguments: Record<string, unknown>;
22
+ status: ToolCallStatus;
23
+ result?: unknown;
24
+ error?: string;
25
+ }
26
+ /** Message block for structured rendering */
27
+ interface MessageBlock {
28
+ type: 'thinking' | 'text' | 'tool_call' | 'tool_result';
29
+ content: string;
30
+ timestamp: number;
31
+ toolName?: string;
32
+ toolArgs?: Record<string, unknown>;
33
+ toolCallId?: string;
34
+ toolStatus?: ToolCallStatus;
35
+ isIntermediate?: boolean;
36
+ }
37
+ /** Chat message for UI rendering */
38
+ interface ChatMessage {
39
+ id: string;
40
+ role: MessageRole;
41
+ content: string;
42
+ timestamp: string;
43
+ isStreaming?: boolean;
44
+ toolCalls?: ToolCall[];
45
+ thinking?: string;
46
+ currentThinking?: string;
47
+ isThinkingStreaming?: boolean;
48
+ blocks?: MessageBlock[];
49
+ isComplete?: boolean;
50
+ }
51
+ /** Conversation info for UI */
52
+ interface ConversationInfo {
53
+ id: string;
54
+ title: string;
55
+ createdAt: string;
56
+ updatedAt: string;
57
+ messageCount: number;
58
+ }
59
+ interface ConversationDetail extends ConversationInfo {
60
+ messages: ChatMessage[];
61
+ }
62
+ /** HITL interrupt data for UI (alias for HitlInterruptPayload) */
63
+ type HitlInterruptData = HitlInterruptPayload;
64
+ type WindowPosition = 'center' | 'cursor' | 'remember' | {
65
+ x: number;
66
+ y: number;
67
+ };
68
+ interface FloatingWindowConfig {
69
+ shortcut?: string;
70
+ position?: WindowPosition;
71
+ width?: number;
72
+ height?: number;
73
+ alwaysOnTop?: boolean;
74
+ showInTaskbar?: boolean;
75
+ theme?: 'light' | 'dark' | 'system';
76
+ }
77
+
78
+ /**
79
+ * Chat Adapter Interface
80
+ *
81
+ * Abstracts the connection to Sanqian backend.
82
+ * Default implementation uses @yushaw/sanqian-sdk directly.
83
+ */
84
+
85
+ /** Stream event callback */
86
+ type StreamEvent = {
87
+ type: 'text';
88
+ content: string;
89
+ } | {
90
+ type: 'thinking';
91
+ content: string;
92
+ } | {
93
+ type: 'tool_call';
94
+ tool_call: {
95
+ id: string;
96
+ function: {
97
+ name: string;
98
+ arguments: string;
99
+ };
100
+ };
101
+ } | {
102
+ type: 'tool_result';
103
+ tool_call_id: string;
104
+ result: unknown;
105
+ } | {
106
+ type: 'done';
107
+ conversationId: string;
108
+ title?: string;
109
+ } | {
110
+ type: 'error';
111
+ error: string;
112
+ } | {
113
+ type: 'interrupt';
114
+ interrupt_type: string;
115
+ interrupt_payload: HitlInterruptData;
116
+ run_id?: string;
117
+ };
118
+ /** Message to send */
119
+ interface SendMessage {
120
+ role: 'user' | 'assistant';
121
+ content: string;
122
+ }
123
+ /** Chat adapter interface */
124
+ interface ChatAdapter {
125
+ connect(): Promise<void>;
126
+ disconnect(): Promise<void>;
127
+ isConnected(): boolean;
128
+ getConnectionStatus(): ConnectionStatus;
129
+ onConnectionChange(callback: (status: ConnectionStatus, error?: string, errorCode?: ConnectionErrorCode) => void): () => void;
130
+ listConversations(options?: {
131
+ limit?: number;
132
+ offset?: number;
133
+ }): Promise<{
134
+ conversations: ConversationInfo[];
135
+ total: number;
136
+ }>;
137
+ getConversation(id: string, options?: {
138
+ messageLimit?: number;
139
+ }): Promise<ConversationDetail>;
140
+ deleteConversation(id: string): Promise<void>;
141
+ chatStream(messages: SendMessage[], conversationId: string | undefined, onEvent: (event: StreamEvent) => void): Promise<{
142
+ cancel: () => void;
143
+ }>;
144
+ sendHitlResponse?(response: HitlResponse, runId?: string): void;
145
+ cleanup?(): void;
146
+ }
147
+ /** SDK adapter config */
148
+ interface SdkAdapterConfig {
149
+ /** SDK instance getter */
150
+ getSdk: () => SanqianSDK | null;
151
+ /** Agent ID getter */
152
+ getAgentId: () => string | null;
153
+ }
154
+ /**
155
+ * Create adapter that wraps @yushaw/sanqian-sdk
156
+ */
157
+ declare function createSdkAdapter(config: SdkAdapterConfig): ChatAdapter;
158
+
159
+ /**
160
+ * useChat Hook
161
+ *
162
+ * Core hook for managing chat state and interactions.
163
+ * Simplified from sanqian-notes chat-ui.
164
+ */
165
+
166
+ interface UseChatOptions {
167
+ adapter: ChatAdapter;
168
+ conversationId?: string;
169
+ onError?: (error: Error) => void;
170
+ onConversationChange?: (conversationId: string, title?: string) => void;
171
+ }
172
+ interface UseChatReturn {
173
+ messages: ChatMessage[];
174
+ isLoading: boolean;
175
+ isStreaming: boolean;
176
+ error: string | null;
177
+ conversationId: string | null;
178
+ conversationTitle: string | null;
179
+ pendingInterrupt: HitlInterruptData | null;
180
+ sendMessage: (content: string) => Promise<void>;
181
+ stopStreaming: () => void;
182
+ clearMessages: () => void;
183
+ setError: (error: string | null) => void;
184
+ approveHitl: (remember?: boolean) => void;
185
+ rejectHitl: (remember?: boolean) => void;
186
+ submitHitlInput: (response: HitlResponse) => void;
187
+ loadConversation: (id: string) => Promise<void>;
188
+ newConversation: () => void;
189
+ }
190
+ declare function useChat(options: UseChatOptions): UseChatReturn;
191
+
192
+ type ThemeMode = 'light' | 'dark' | 'system';
193
+ type ResolvedTheme = 'light' | 'dark';
194
+ interface ThemeContextValue {
195
+ theme: ThemeMode;
196
+ resolvedTheme: ResolvedTheme;
197
+ setTheme: (theme: ThemeMode) => void;
198
+ }
199
+ interface ThemeProviderProps {
200
+ children: ReactNode;
201
+ defaultTheme?: ThemeMode;
202
+ storageKey?: string;
203
+ }
204
+ declare function ThemeProvider({ children, defaultTheme, storageKey, }: ThemeProviderProps): react_jsx_runtime.JSX.Element;
205
+ declare function useTheme(): ThemeContextValue;
206
+ /**
207
+ * Hook for theme without provider (standalone usage)
208
+ * Useful when you can't wrap with ThemeProvider
209
+ */
210
+ declare function useStandaloneTheme(defaultTheme?: ThemeMode): ThemeContextValue;
211
+
212
+ type Locale = 'en' | 'zh';
213
+ interface Translations {
214
+ hitl: {
215
+ approvalRequired: string;
216
+ inputRequired: string;
217
+ tool: string;
218
+ approve: string;
219
+ reject: string;
220
+ submit: string;
221
+ cancel: string;
222
+ };
223
+ input: {
224
+ placeholder: string;
225
+ send: string;
226
+ stop: string;
227
+ };
228
+ message: {
229
+ thinking: string;
230
+ error: string;
231
+ loading: string;
232
+ };
233
+ connection: {
234
+ connecting: string;
235
+ connected: string;
236
+ disconnected: string;
237
+ reconnecting: string;
238
+ error: string;
239
+ };
240
+ conversation: {
241
+ new: string;
242
+ untitled: string;
243
+ delete: string;
244
+ deleteConfirm: string;
245
+ };
246
+ }
247
+ interface I18nContextValue {
248
+ locale: Locale;
249
+ setLocale: (locale: Locale) => void;
250
+ t: Translations;
251
+ }
252
+ interface I18nProviderProps {
253
+ children: ReactNode;
254
+ defaultLocale?: Locale;
255
+ storageKey?: string;
256
+ /** Custom translations to merge with built-in ones */
257
+ customTranslations?: Partial<Record<Locale, Partial<Translations>>>;
258
+ }
259
+ declare function I18nProvider({ children, defaultLocale, storageKey, customTranslations, }: I18nProviderProps): react_jsx_runtime.JSX.Element;
260
+ declare function useI18n(): I18nContextValue;
261
+ /**
262
+ * Hook for i18n without provider (standalone usage)
263
+ * Returns default English translations if no provider
264
+ */
265
+ declare function useStandaloneI18n(defaultLocale?: Locale): I18nContextValue;
266
+ /**
267
+ * Get translations for a specific locale (utility function)
268
+ */
269
+ declare function getTranslations(locale: Locale): Translations;
270
+
271
+ /**
272
+ * IPC Adapter
273
+ *
274
+ * Connects to main process via preload API (window.sanqianChat)
275
+ */
276
+
277
+ /**
278
+ * Create IPC adapter that communicates via window.sanqianChat (preload)
279
+ */
280
+ declare function createIpcAdapter(): ChatAdapter;
281
+
282
+ interface MessageListProps {
283
+ messages: ChatMessage[];
284
+ className?: string;
285
+ renderMessage: (message: ChatMessage, index: number) => ReactNode;
286
+ autoScroll?: boolean;
287
+ scrollBehavior?: ScrollBehavior;
288
+ }
289
+ declare const MessageList: react.NamedExoticComponent<MessageListProps>;
290
+
291
+ interface MessageBubbleProps {
292
+ message: ChatMessage;
293
+ className?: string;
294
+ children?: ReactNode;
295
+ renderContent?: (content: string, isStreaming: boolean) => ReactNode;
296
+ }
297
+ declare const MessageBubble: react.NamedExoticComponent<MessageBubbleProps>;
298
+
299
+ interface ChatInputProps {
300
+ onSend: (content: string) => void;
301
+ onStop?: () => void;
302
+ placeholder?: string;
303
+ disabled?: boolean;
304
+ isStreaming?: boolean;
305
+ isLoading?: boolean;
306
+ className?: string;
307
+ textareaClassName?: string;
308
+ sendButtonClassName?: string;
309
+ stopButtonClassName?: string;
310
+ sendButtonContent?: ReactNode;
311
+ stopButtonContent?: ReactNode;
312
+ maxRows?: number;
313
+ autoFocus?: boolean;
314
+ focusRef?: React.MutableRefObject<(() => void) | null>;
315
+ }
316
+ declare const ChatInput: react.NamedExoticComponent<ChatInputProps>;
317
+
318
+ interface FloatingChatProps {
319
+ messages: ChatMessage[];
320
+ isLoading: boolean;
321
+ isStreaming: boolean;
322
+ error: string | null;
323
+ pendingInterrupt: HitlInterruptData | null;
324
+ onSendMessage: (content: string) => void;
325
+ onStopStreaming: () => void;
326
+ onApproveHitl?: (remember?: boolean) => void;
327
+ onRejectHitl?: (remember?: boolean) => void;
328
+ onHide?: () => void;
329
+ className?: string;
330
+ placeholder?: string;
331
+ locale?: Locale;
332
+ renderMessage?: (message: ChatMessage, index: number) => ReactNode;
333
+ renderContent?: (content: string, isStreaming: boolean) => ReactNode;
334
+ renderHitl?: (interrupt: HitlInterruptData, onApprove: () => void, onReject: () => void) => ReactNode;
335
+ header?: ReactNode;
336
+ footer?: ReactNode;
337
+ }
338
+ declare const FloatingChat: react.NamedExoticComponent<FloatingChatProps>;
339
+
340
+ export { type ChatAdapter, ChatInput, type ChatInputProps, type ChatMessage, type ConnectionErrorCode, type ConnectionStatus, type ConversationDetail, type ConversationInfo, FloatingChat, type FloatingChatProps, type FloatingWindowConfig, type HitlInterruptData, I18nProvider, type I18nProviderProps, type Locale, type MessageBlock, MessageBubble, type MessageBubbleProps, MessageList, type MessageListProps, type MessageRole, type ResolvedTheme, type SdkAdapterConfig, type SendMessage, type StreamEvent, type ThemeMode, ThemeProvider, type ThemeProviderProps, type ToolCall, type ToolCallStatus, type Translations, type UseChatOptions, type UseChatReturn, type WindowPosition, createIpcAdapter, createSdkAdapter, getTranslations, useChat, useI18n, useStandaloneI18n, useStandaloneTheme, useTheme };