@yushaw/sanqian-chat 0.2.6 → 0.2.9
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/README.md +13 -0
- package/dist/chunk-S6HCEDWX.mjs +86 -0
- package/dist/core/index.d.mts +98 -3
- package/dist/core/index.d.ts +98 -3
- package/dist/core/index.js +6 -2
- package/dist/core/index.mjs +6 -2
- package/dist/main/index.d.mts +105 -3
- package/dist/main/index.d.ts +105 -3
- package/dist/main/index.js +146 -4
- package/dist/main/index.mjs +146 -3
- package/dist/preload/entry.d.mts +2 -0
- package/dist/preload/entry.d.ts +2 -0
- package/dist/preload/entry.js +93 -0
- package/dist/preload/entry.mjs +12 -0
- package/dist/preload/factories.d.mts +261 -0
- package/dist/preload/factories.d.ts +261 -0
- package/dist/preload/factories.js +111 -0
- package/dist/preload/factories.mjs +8 -0
- package/dist/preload/index.d.mts +2 -0
- package/dist/preload/index.d.ts +2 -210
- package/dist/preload/index.js +94 -67
- package/dist/preload/index.mjs +8 -0
- package/dist/renderer/index.d.mts +262 -4
- package/dist/renderer/index.d.ts +262 -4
- package/dist/renderer/index.js +1655 -480
- package/dist/renderer/index.mjs +1615 -446
- package/package.json +3 -2
- package/src/renderer/styles/chat.css +22 -19
- package/src/renderer/styles/coreCss.ts +22 -19
- package/src/renderer/styles/safe.css +22 -19
package/README.md
CHANGED
|
@@ -99,6 +99,19 @@ src/renderer/styles/
|
|
|
99
99
|
|
|
100
100
|
## Changelog
|
|
101
101
|
|
|
102
|
+
### 0.2.7 (2026-01-06)
|
|
103
|
+
- **Added**: External resource reference support
|
|
104
|
+
- `useResourcePicker` hook - manage resource picker state, search, pagination
|
|
105
|
+
- `ResourcePicker` component - two-level picker (providers → resources)
|
|
106
|
+
- `ResourceChip` / `ResourceChipList` - display attached resources
|
|
107
|
+
- `AddResourceButton` - + button with dropdown menu
|
|
108
|
+
- **Added**: `ChatAdapter` extensions: `listResourceProviders`, `getResourceList`, `onLocaleChanged`
|
|
109
|
+
- **Added**: `FloatingWindow.notifyLocaleChanged(locale)` and `ChatPanel.notifyLocaleChanged(locale)` - notify renderer when locale changes
|
|
110
|
+
- **Added**: `sendMessage` now accepts `options.attachedResources`
|
|
111
|
+
- **Added**: Message rendering displays attached resources in user messages
|
|
112
|
+
- **Added**: New types: `AttachedResource`, `ResourcePickerItem`, `ContextProviderInfo`
|
|
113
|
+
- **Changed**: `AppContextProvider.getList` now accepts `options` parameter for search/pagination
|
|
114
|
+
|
|
102
115
|
### 2025-01-03
|
|
103
116
|
- **Added**: Focus persistence - input keeps focus when clicking empty areas (unless selecting text)
|
|
104
117
|
- **Added**: `Cmd+N` (macOS) / `Ctrl+N` (Windows) keyboard shortcut for new chat
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
// src/preload/factories.ts
|
|
2
|
+
import { ipcRenderer } from "electron";
|
|
3
|
+
function createSanqianChatApi() {
|
|
4
|
+
return {
|
|
5
|
+
connect: () => ipcRenderer.invoke("sanqian-chat:connect"),
|
|
6
|
+
isConnected: () => ipcRenderer.invoke("sanqian-chat:isConnected"),
|
|
7
|
+
stream: (params) => ipcRenderer.invoke("sanqian-chat:stream", params),
|
|
8
|
+
cancelStream: (params) => ipcRenderer.invoke("sanqian-chat:cancelStream", params),
|
|
9
|
+
onStreamEvent: (callback) => {
|
|
10
|
+
const handler = (_, data) => {
|
|
11
|
+
callback(data.streamId, data.event);
|
|
12
|
+
};
|
|
13
|
+
ipcRenderer.on("sanqian-chat:streamEvent", handler);
|
|
14
|
+
return () => ipcRenderer.removeListener("sanqian-chat:streamEvent", handler);
|
|
15
|
+
},
|
|
16
|
+
sendHitlResponse: (params) => ipcRenderer.invoke("sanqian-chat:hitlResponse", params),
|
|
17
|
+
listConversations: (params) => ipcRenderer.invoke("sanqian-chat:listConversations", params),
|
|
18
|
+
getConversation: (params) => ipcRenderer.invoke("sanqian-chat:getConversation", params),
|
|
19
|
+
deleteConversation: (params) => ipcRenderer.invoke("sanqian-chat:deleteConversation", params),
|
|
20
|
+
hide: () => ipcRenderer.invoke("sanqian-chat:hide"),
|
|
21
|
+
setAlwaysOnTop: (params) => ipcRenderer.invoke("sanqian-chat:setAlwaysOnTop", params),
|
|
22
|
+
getAlwaysOnTop: () => ipcRenderer.invoke("sanqian-chat:getAlwaysOnTop"),
|
|
23
|
+
getUiConfig: () => ipcRenderer.invoke("sanqian-chat:getUiConfig"),
|
|
24
|
+
setBackgroundColor: (params) => ipcRenderer.invoke("sanqian-chat:setBackgroundColor", params),
|
|
25
|
+
getPlatform: () => process.platform,
|
|
26
|
+
// Resource Picker
|
|
27
|
+
listResourceProviders: () => ipcRenderer.invoke("sanqian-chat:listResourceProviders"),
|
|
28
|
+
getResourceList: (params) => ipcRenderer.invoke("sanqian-chat:getResourceList", params),
|
|
29
|
+
// Locale
|
|
30
|
+
onLocaleChanged: (callback) => {
|
|
31
|
+
const handler = (_, data) => {
|
|
32
|
+
callback(data.locale);
|
|
33
|
+
};
|
|
34
|
+
ipcRenderer.on("sanqian-chat:localeChanged", handler);
|
|
35
|
+
return () => ipcRenderer.removeListener("sanqian-chat:localeChanged", handler);
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
function createChatPanelApi() {
|
|
40
|
+
return {
|
|
41
|
+
// Mode
|
|
42
|
+
getMode: () => ipcRenderer.invoke("chatPanel:getMode"),
|
|
43
|
+
setMode: (mode) => ipcRenderer.invoke("chatPanel:setMode", mode),
|
|
44
|
+
toggleMode: () => ipcRenderer.invoke("chatPanel:toggleMode"),
|
|
45
|
+
onModeChanged: (callback) => {
|
|
46
|
+
const handler = (_, data) => {
|
|
47
|
+
callback(data.mode);
|
|
48
|
+
};
|
|
49
|
+
ipcRenderer.on("chatPanel:modeChanged", handler);
|
|
50
|
+
return () => ipcRenderer.removeListener("chatPanel:modeChanged", handler);
|
|
51
|
+
},
|
|
52
|
+
// Visibility
|
|
53
|
+
isVisible: () => ipcRenderer.invoke("chatPanel:isVisible"),
|
|
54
|
+
show: () => ipcRenderer.invoke("chatPanel:show"),
|
|
55
|
+
hide: () => ipcRenderer.invoke("chatPanel:hide"),
|
|
56
|
+
toggle: () => ipcRenderer.invoke("chatPanel:toggle"),
|
|
57
|
+
onVisibilityChanged: (callback) => {
|
|
58
|
+
const handler = (_, data) => {
|
|
59
|
+
callback(data.visible);
|
|
60
|
+
};
|
|
61
|
+
ipcRenderer.on("chatPanel:visibilityChanged", handler);
|
|
62
|
+
return () => ipcRenderer.removeListener("chatPanel:visibilityChanged", handler);
|
|
63
|
+
},
|
|
64
|
+
// Attach state
|
|
65
|
+
getAttachState: () => ipcRenderer.invoke("chatPanel:getAttachState"),
|
|
66
|
+
toggleAttach: () => ipcRenderer.invoke("chatPanel:toggleAttach"),
|
|
67
|
+
onAttachStateChanged: (callback) => {
|
|
68
|
+
const handler = (_, data) => {
|
|
69
|
+
callback(data.state);
|
|
70
|
+
};
|
|
71
|
+
ipcRenderer.on("chatPanel:attachStateChanged", handler);
|
|
72
|
+
return () => ipcRenderer.removeListener("chatPanel:attachStateChanged", handler);
|
|
73
|
+
},
|
|
74
|
+
// Width
|
|
75
|
+
getWidth: () => ipcRenderer.invoke("chatPanel:getWidth"),
|
|
76
|
+
setWidth: (width, animate) => ipcRenderer.invoke("chatPanel:setWidth", { width, animate }),
|
|
77
|
+
onResizeEnd: () => ipcRenderer.invoke("chatPanel:onResizeEnd"),
|
|
78
|
+
// UI Config
|
|
79
|
+
getUiConfig: () => ipcRenderer.invoke("chatPanel:getUiConfig")
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export {
|
|
84
|
+
createSanqianChatApi,
|
|
85
|
+
createChatPanelApi
|
|
86
|
+
};
|
package/dist/core/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
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';
|
|
1
|
+
import { ResourceType, HitlInterruptPayload, ContextListItem, HitlResponse, ResourceListOptions, SanqianSDK } from '@yushaw/sanqian-sdk';
|
|
2
|
+
export { ChatStreamEvent, ContextListItem, HitlInterruptPayload, HitlInterruptType, HitlResponse, HitlRiskLevel, ResourceListOptions, ResourceListResult, ResourceType, ChatMessage as SdkChatMessage, ConversationDetail as SdkConversationDetail, ConversationInfo as SdkConversationInfo, ToolCall as SdkToolCall } from '@yushaw/sanqian-sdk';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* @yushaw/sanqian-chat Core Types
|
|
@@ -120,6 +120,8 @@ interface ChatMessage {
|
|
|
120
120
|
finalContent?: string;
|
|
121
121
|
isComplete?: boolean;
|
|
122
122
|
filePaths?: string[];
|
|
123
|
+
/** Attached external resources (for user messages) */
|
|
124
|
+
attachedResources?: AttachedResource[];
|
|
123
125
|
}
|
|
124
126
|
/** Conversation info for UI */
|
|
125
127
|
interface ConversationInfo {
|
|
@@ -307,6 +309,86 @@ interface ChatPanelConfig {
|
|
|
307
309
|
*/
|
|
308
310
|
uiConfig?: ChatUiConfigSerializable;
|
|
309
311
|
}
|
|
312
|
+
/**
|
|
313
|
+
* Context provider info for UI display (in + menu)
|
|
314
|
+
*/
|
|
315
|
+
interface ContextProviderInfo {
|
|
316
|
+
/** Full provider ID (format: "appName:providerId") */
|
|
317
|
+
id: string;
|
|
318
|
+
/** Display name */
|
|
319
|
+
name: string;
|
|
320
|
+
/** Description */
|
|
321
|
+
description: string;
|
|
322
|
+
/** App name (extracted from id) */
|
|
323
|
+
appName: string;
|
|
324
|
+
/** Whether app is currently connected */
|
|
325
|
+
isConnected?: boolean;
|
|
326
|
+
/** Whether provider supports getList (resource picker) */
|
|
327
|
+
hasGetList?: boolean;
|
|
328
|
+
/** Whether provider supports getCurrent (auto-inject) */
|
|
329
|
+
hasGetCurrent?: boolean;
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Resource item for picker display (extends ContextListItem with provider info)
|
|
333
|
+
*/
|
|
334
|
+
interface ResourcePickerItem extends ContextListItem {
|
|
335
|
+
/** Full provider ID that owns this resource */
|
|
336
|
+
providerId: string;
|
|
337
|
+
/** Provider display name */
|
|
338
|
+
providerName?: string;
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Attached resource reference (selected by user)
|
|
342
|
+
*/
|
|
343
|
+
interface AttachedResource {
|
|
344
|
+
/** Full provider ID (format: "appName:providerId") */
|
|
345
|
+
providerId: string;
|
|
346
|
+
/** Resource ID (from ContextListItem.id) */
|
|
347
|
+
resourceId: string;
|
|
348
|
+
/** Display title */
|
|
349
|
+
title: string;
|
|
350
|
+
/** Optional summary for tooltip */
|
|
351
|
+
summary?: string;
|
|
352
|
+
/** Resource type for icon/styling */
|
|
353
|
+
type?: ResourceType;
|
|
354
|
+
/** Icon emoji or URL */
|
|
355
|
+
icon?: string;
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Resource picker state
|
|
359
|
+
*/
|
|
360
|
+
interface ResourcePickerState {
|
|
361
|
+
/** Currently loading */
|
|
362
|
+
isLoading: boolean;
|
|
363
|
+
/** Search query */
|
|
364
|
+
query: string;
|
|
365
|
+
/** Available items grouped by provider */
|
|
366
|
+
itemsByProvider: Record<string, ResourcePickerItem[]>;
|
|
367
|
+
/** Whether more items are available (for pagination) */
|
|
368
|
+
hasMoreByProvider: Record<string, boolean>;
|
|
369
|
+
/** Error message if any */
|
|
370
|
+
error?: string;
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* Attachment menu item type
|
|
374
|
+
*/
|
|
375
|
+
type AttachmentMenuItemType = 'upload' | 'provider';
|
|
376
|
+
/**
|
|
377
|
+
* Attachment menu item for + button dropdown
|
|
378
|
+
*/
|
|
379
|
+
interface AttachmentMenuItem {
|
|
380
|
+
type: AttachmentMenuItemType;
|
|
381
|
+
/** For 'upload': 'file' or 'image'. For 'provider': provider ID */
|
|
382
|
+
id: string;
|
|
383
|
+
/** Display label */
|
|
384
|
+
label: string;
|
|
385
|
+
/** Icon emoji or URL */
|
|
386
|
+
icon?: string;
|
|
387
|
+
/** Description or subtitle */
|
|
388
|
+
description?: string;
|
|
389
|
+
/** Whether currently available (e.g., app connected) */
|
|
390
|
+
available?: boolean;
|
|
391
|
+
}
|
|
310
392
|
|
|
311
393
|
/**
|
|
312
394
|
* Chat Adapter Interface
|
|
@@ -390,10 +472,23 @@ interface ChatAdapter {
|
|
|
390
472
|
deleteConversation(id: string): Promise<void>;
|
|
391
473
|
chatStream(messages: SendMessage[], conversationId: string | undefined, onEvent: (event: StreamEvent) => void, options?: {
|
|
392
474
|
agentId?: string | null;
|
|
475
|
+
/** Attached context provider IDs (e.g., ["sanqian-notes:notes"]) - for getCurrent */
|
|
476
|
+
attachedContexts?: string[];
|
|
477
|
+
/** Attached resource references (e.g., ["sanqian-notes:notes:abc123"]) - for getById */
|
|
478
|
+
attachedResources?: string[];
|
|
393
479
|
}): Promise<{
|
|
394
480
|
cancel: () => void;
|
|
395
481
|
}>;
|
|
396
482
|
sendHitlResponse?(response: HitlResponse, runId?: string): void;
|
|
483
|
+
/** List available context providers */
|
|
484
|
+
listResourceProviders?(): Promise<ContextProviderInfo[]>;
|
|
485
|
+
/** Get resource list from a provider with search/pagination */
|
|
486
|
+
getResourceList?(providerId: string, options?: ResourceListOptions): Promise<{
|
|
487
|
+
items: ResourcePickerItem[];
|
|
488
|
+
hasMore?: boolean;
|
|
489
|
+
}>;
|
|
490
|
+
/** Subscribe to locale change events */
|
|
491
|
+
onLocaleChanged?(callback: (locale: string) => void): () => void;
|
|
397
492
|
cleanup?(): void;
|
|
398
493
|
}
|
|
399
494
|
/** SDK adapter config */
|
|
@@ -480,4 +575,4 @@ declare function parseToolCalls(toolCalls: unknown): ToolCall[] | undefined;
|
|
|
480
575
|
*/
|
|
481
576
|
declare function mergeConsecutiveAssistantMessages(rawMessages: ApiMessage[]): ChatMessage[];
|
|
482
577
|
|
|
483
|
-
export { type ApiMessage, type AttachConfig, type AttachPosition, type AttachState, type ChatAdapter, type ChatAdapterConfig, type ChatFontSize, type ChatMessage, type ChatPanelConfig, type ChatPanelMode, type ChatPanelPosition, type ChatThemeMode, type ChatUiConfigSerializable, type ChatUiStrings, type ConnectionErrorCode, type ConnectionStatus, type ConversationDetail, type ConversationInfo, type FloatingWindowConfig, type HitlInterruptData, type Locale, type MessageBlock, type MessageRole, type SdkAdapterConfig, type SendMessage, type StreamEvent, type ToolCall, type ToolCallStatus, type WindowPosition, createChatAdapter, createSdkAdapter, mergeConsecutiveAssistantMessages, parseToolCalls };
|
|
578
|
+
export { type ApiMessage, type AttachConfig, type AttachPosition, type AttachState, type AttachedResource, type AttachmentMenuItem, type AttachmentMenuItemType, type ChatAdapter, type ChatAdapterConfig, type ChatFontSize, type ChatMessage, type ChatPanelConfig, type ChatPanelMode, type ChatPanelPosition, type ChatThemeMode, type ChatUiConfigSerializable, type ChatUiStrings, type ConnectionErrorCode, type ConnectionStatus, type ContextProviderInfo, type ConversationDetail, type ConversationInfo, type FloatingWindowConfig, type HitlInterruptData, type Locale, type MessageBlock, type MessageRole, type ResourcePickerItem, type ResourcePickerState, type SdkAdapterConfig, type SendMessage, type StreamEvent, type ToolCall, type ToolCallStatus, type WindowPosition, createChatAdapter, createSdkAdapter, mergeConsecutiveAssistantMessages, parseToolCalls };
|
package/dist/core/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
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';
|
|
1
|
+
import { ResourceType, HitlInterruptPayload, ContextListItem, HitlResponse, ResourceListOptions, SanqianSDK } from '@yushaw/sanqian-sdk';
|
|
2
|
+
export { ChatStreamEvent, ContextListItem, HitlInterruptPayload, HitlInterruptType, HitlResponse, HitlRiskLevel, ResourceListOptions, ResourceListResult, ResourceType, ChatMessage as SdkChatMessage, ConversationDetail as SdkConversationDetail, ConversationInfo as SdkConversationInfo, ToolCall as SdkToolCall } from '@yushaw/sanqian-sdk';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* @yushaw/sanqian-chat Core Types
|
|
@@ -120,6 +120,8 @@ interface ChatMessage {
|
|
|
120
120
|
finalContent?: string;
|
|
121
121
|
isComplete?: boolean;
|
|
122
122
|
filePaths?: string[];
|
|
123
|
+
/** Attached external resources (for user messages) */
|
|
124
|
+
attachedResources?: AttachedResource[];
|
|
123
125
|
}
|
|
124
126
|
/** Conversation info for UI */
|
|
125
127
|
interface ConversationInfo {
|
|
@@ -307,6 +309,86 @@ interface ChatPanelConfig {
|
|
|
307
309
|
*/
|
|
308
310
|
uiConfig?: ChatUiConfigSerializable;
|
|
309
311
|
}
|
|
312
|
+
/**
|
|
313
|
+
* Context provider info for UI display (in + menu)
|
|
314
|
+
*/
|
|
315
|
+
interface ContextProviderInfo {
|
|
316
|
+
/** Full provider ID (format: "appName:providerId") */
|
|
317
|
+
id: string;
|
|
318
|
+
/** Display name */
|
|
319
|
+
name: string;
|
|
320
|
+
/** Description */
|
|
321
|
+
description: string;
|
|
322
|
+
/** App name (extracted from id) */
|
|
323
|
+
appName: string;
|
|
324
|
+
/** Whether app is currently connected */
|
|
325
|
+
isConnected?: boolean;
|
|
326
|
+
/** Whether provider supports getList (resource picker) */
|
|
327
|
+
hasGetList?: boolean;
|
|
328
|
+
/** Whether provider supports getCurrent (auto-inject) */
|
|
329
|
+
hasGetCurrent?: boolean;
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Resource item for picker display (extends ContextListItem with provider info)
|
|
333
|
+
*/
|
|
334
|
+
interface ResourcePickerItem extends ContextListItem {
|
|
335
|
+
/** Full provider ID that owns this resource */
|
|
336
|
+
providerId: string;
|
|
337
|
+
/** Provider display name */
|
|
338
|
+
providerName?: string;
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Attached resource reference (selected by user)
|
|
342
|
+
*/
|
|
343
|
+
interface AttachedResource {
|
|
344
|
+
/** Full provider ID (format: "appName:providerId") */
|
|
345
|
+
providerId: string;
|
|
346
|
+
/** Resource ID (from ContextListItem.id) */
|
|
347
|
+
resourceId: string;
|
|
348
|
+
/** Display title */
|
|
349
|
+
title: string;
|
|
350
|
+
/** Optional summary for tooltip */
|
|
351
|
+
summary?: string;
|
|
352
|
+
/** Resource type for icon/styling */
|
|
353
|
+
type?: ResourceType;
|
|
354
|
+
/** Icon emoji or URL */
|
|
355
|
+
icon?: string;
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Resource picker state
|
|
359
|
+
*/
|
|
360
|
+
interface ResourcePickerState {
|
|
361
|
+
/** Currently loading */
|
|
362
|
+
isLoading: boolean;
|
|
363
|
+
/** Search query */
|
|
364
|
+
query: string;
|
|
365
|
+
/** Available items grouped by provider */
|
|
366
|
+
itemsByProvider: Record<string, ResourcePickerItem[]>;
|
|
367
|
+
/** Whether more items are available (for pagination) */
|
|
368
|
+
hasMoreByProvider: Record<string, boolean>;
|
|
369
|
+
/** Error message if any */
|
|
370
|
+
error?: string;
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* Attachment menu item type
|
|
374
|
+
*/
|
|
375
|
+
type AttachmentMenuItemType = 'upload' | 'provider';
|
|
376
|
+
/**
|
|
377
|
+
* Attachment menu item for + button dropdown
|
|
378
|
+
*/
|
|
379
|
+
interface AttachmentMenuItem {
|
|
380
|
+
type: AttachmentMenuItemType;
|
|
381
|
+
/** For 'upload': 'file' or 'image'. For 'provider': provider ID */
|
|
382
|
+
id: string;
|
|
383
|
+
/** Display label */
|
|
384
|
+
label: string;
|
|
385
|
+
/** Icon emoji or URL */
|
|
386
|
+
icon?: string;
|
|
387
|
+
/** Description or subtitle */
|
|
388
|
+
description?: string;
|
|
389
|
+
/** Whether currently available (e.g., app connected) */
|
|
390
|
+
available?: boolean;
|
|
391
|
+
}
|
|
310
392
|
|
|
311
393
|
/**
|
|
312
394
|
* Chat Adapter Interface
|
|
@@ -390,10 +472,23 @@ interface ChatAdapter {
|
|
|
390
472
|
deleteConversation(id: string): Promise<void>;
|
|
391
473
|
chatStream(messages: SendMessage[], conversationId: string | undefined, onEvent: (event: StreamEvent) => void, options?: {
|
|
392
474
|
agentId?: string | null;
|
|
475
|
+
/** Attached context provider IDs (e.g., ["sanqian-notes:notes"]) - for getCurrent */
|
|
476
|
+
attachedContexts?: string[];
|
|
477
|
+
/** Attached resource references (e.g., ["sanqian-notes:notes:abc123"]) - for getById */
|
|
478
|
+
attachedResources?: string[];
|
|
393
479
|
}): Promise<{
|
|
394
480
|
cancel: () => void;
|
|
395
481
|
}>;
|
|
396
482
|
sendHitlResponse?(response: HitlResponse, runId?: string): void;
|
|
483
|
+
/** List available context providers */
|
|
484
|
+
listResourceProviders?(): Promise<ContextProviderInfo[]>;
|
|
485
|
+
/** Get resource list from a provider with search/pagination */
|
|
486
|
+
getResourceList?(providerId: string, options?: ResourceListOptions): Promise<{
|
|
487
|
+
items: ResourcePickerItem[];
|
|
488
|
+
hasMore?: boolean;
|
|
489
|
+
}>;
|
|
490
|
+
/** Subscribe to locale change events */
|
|
491
|
+
onLocaleChanged?(callback: (locale: string) => void): () => void;
|
|
397
492
|
cleanup?(): void;
|
|
398
493
|
}
|
|
399
494
|
/** SDK adapter config */
|
|
@@ -480,4 +575,4 @@ declare function parseToolCalls(toolCalls: unknown): ToolCall[] | undefined;
|
|
|
480
575
|
*/
|
|
481
576
|
declare function mergeConsecutiveAssistantMessages(rawMessages: ApiMessage[]): ChatMessage[];
|
|
482
577
|
|
|
483
|
-
export { type ApiMessage, type AttachConfig, type AttachPosition, type AttachState, type ChatAdapter, type ChatAdapterConfig, type ChatFontSize, type ChatMessage, type ChatPanelConfig, type ChatPanelMode, type ChatPanelPosition, type ChatThemeMode, type ChatUiConfigSerializable, type ChatUiStrings, type ConnectionErrorCode, type ConnectionStatus, type ConversationDetail, type ConversationInfo, type FloatingWindowConfig, type HitlInterruptData, type Locale, type MessageBlock, type MessageRole, type SdkAdapterConfig, type SendMessage, type StreamEvent, type ToolCall, type ToolCallStatus, type WindowPosition, createChatAdapter, createSdkAdapter, mergeConsecutiveAssistantMessages, parseToolCalls };
|
|
578
|
+
export { type ApiMessage, type AttachConfig, type AttachPosition, type AttachState, type AttachedResource, type AttachmentMenuItem, type AttachmentMenuItemType, type ChatAdapter, type ChatAdapterConfig, type ChatFontSize, type ChatMessage, type ChatPanelConfig, type ChatPanelMode, type ChatPanelPosition, type ChatThemeMode, type ChatUiConfigSerializable, type ChatUiStrings, type ConnectionErrorCode, type ConnectionStatus, type ContextProviderInfo, type ConversationDetail, type ConversationInfo, type FloatingWindowConfig, type HitlInterruptData, type Locale, type MessageBlock, type MessageRole, type ResourcePickerItem, type ResourcePickerState, type SdkAdapterConfig, type SendMessage, type StreamEvent, type ToolCall, type ToolCallStatus, type WindowPosition, createChatAdapter, createSdkAdapter, mergeConsecutiveAssistantMessages, parseToolCalls };
|
package/dist/core/index.js
CHANGED
|
@@ -412,7 +412,8 @@ function createChatAdapter(config) {
|
|
|
412
412
|
sdkMessages,
|
|
413
413
|
{
|
|
414
414
|
conversationId,
|
|
415
|
-
persistHistory: config.persistHistory ?? false
|
|
415
|
+
persistHistory: config.persistHistory ?? false,
|
|
416
|
+
attachedResources: options?.attachedResources
|
|
416
417
|
}
|
|
417
418
|
);
|
|
418
419
|
return processStreamEvents(stream, onEvent, sdk, (id) => {
|
|
@@ -635,7 +636,10 @@ function createSdkAdapter(config) {
|
|
|
635
636
|
const stream = sdk.chatStream(
|
|
636
637
|
agentId,
|
|
637
638
|
sdkMessages,
|
|
638
|
-
{
|
|
639
|
+
{
|
|
640
|
+
conversationId,
|
|
641
|
+
attachedResources: options?.attachedResources
|
|
642
|
+
}
|
|
639
643
|
);
|
|
640
644
|
return processStreamEvents(stream, onEvent, sdk, (id) => {
|
|
641
645
|
currentRunId = id;
|
package/dist/core/index.mjs
CHANGED
|
@@ -373,7 +373,8 @@ function createChatAdapter(config) {
|
|
|
373
373
|
sdkMessages,
|
|
374
374
|
{
|
|
375
375
|
conversationId,
|
|
376
|
-
persistHistory: config.persistHistory ?? false
|
|
376
|
+
persistHistory: config.persistHistory ?? false,
|
|
377
|
+
attachedResources: options?.attachedResources
|
|
377
378
|
}
|
|
378
379
|
);
|
|
379
380
|
return processStreamEvents(stream, onEvent, sdk, (id) => {
|
|
@@ -596,7 +597,10 @@ function createSdkAdapter(config) {
|
|
|
596
597
|
const stream = sdk.chatStream(
|
|
597
598
|
agentId,
|
|
598
599
|
sdkMessages,
|
|
599
|
-
{
|
|
600
|
+
{
|
|
601
|
+
conversationId,
|
|
602
|
+
attachedResources: options?.attachedResources
|
|
603
|
+
}
|
|
600
604
|
);
|
|
601
605
|
return processStreamEvents(stream, onEvent, sdk, (id) => {
|
|
602
606
|
currentRunId = id;
|
package/dist/main/index.d.mts
CHANGED
|
@@ -8,6 +8,8 @@ import { BrowserWindow, WebContents } from 'electron';
|
|
|
8
8
|
* Application-facing types that hide SDK implementation details.
|
|
9
9
|
* These provide a stable API even as the underlying SDK evolves.
|
|
10
10
|
*/
|
|
11
|
+
/** Resource type for display styling (can be any string for custom types) */
|
|
12
|
+
type AppResourceType = string;
|
|
11
13
|
/**
|
|
12
14
|
* Context data returned by a provider
|
|
13
15
|
*/
|
|
@@ -22,6 +24,16 @@ interface AppContextData {
|
|
|
22
24
|
summary?: string;
|
|
23
25
|
/** Version for change detection (optional, Sanqian uses content hash if not provided) */
|
|
24
26
|
version?: string;
|
|
27
|
+
/** Resource type for display styling */
|
|
28
|
+
type?: AppResourceType;
|
|
29
|
+
/** Additional metadata (accessible in templates via {{metadata.xxx}}) */
|
|
30
|
+
metadata?: Record<string, unknown>;
|
|
31
|
+
/**
|
|
32
|
+
* Custom injection template using Mustache-style variables.
|
|
33
|
+
* Available variables: {{title}}, {{content}}, {{summary}}, {{type}}, {{metadata.xxx}}
|
|
34
|
+
* @example "# {{title}}\n\n{{content}}"
|
|
35
|
+
*/
|
|
36
|
+
template?: string;
|
|
25
37
|
}
|
|
26
38
|
/**
|
|
27
39
|
* List item for context provider's getList method
|
|
@@ -35,6 +47,34 @@ interface AppContextListItem {
|
|
|
35
47
|
summary?: string;
|
|
36
48
|
/** Optional icon */
|
|
37
49
|
icon?: string;
|
|
50
|
+
/** Resource type for display styling */
|
|
51
|
+
type?: AppResourceType;
|
|
52
|
+
/** Last updated timestamp (ISO 8601) */
|
|
53
|
+
updatedAt?: string;
|
|
54
|
+
/** Group name for categorization in picker UI */
|
|
55
|
+
group?: string;
|
|
56
|
+
/** Tags for filtering */
|
|
57
|
+
tags?: string[];
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Options for getList() pagination and search
|
|
61
|
+
*/
|
|
62
|
+
interface AppResourceListOptions {
|
|
63
|
+
/** Search query string */
|
|
64
|
+
query?: string;
|
|
65
|
+
/** Pagination offset (default: 0) */
|
|
66
|
+
offset?: number;
|
|
67
|
+
/** Max items to return (default: 20) */
|
|
68
|
+
limit?: number;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Result from getList() with pagination info
|
|
72
|
+
*/
|
|
73
|
+
interface AppResourceListResult {
|
|
74
|
+
/** List items */
|
|
75
|
+
items: AppContextListItem[];
|
|
76
|
+
/** Whether more items are available */
|
|
77
|
+
hasMore?: boolean;
|
|
38
78
|
}
|
|
39
79
|
/**
|
|
40
80
|
* Context provider definition
|
|
@@ -48,8 +88,8 @@ interface AppContextProvider {
|
|
|
48
88
|
description: string;
|
|
49
89
|
/** Get current state (for dynamic context) */
|
|
50
90
|
getCurrent?: () => Promise<AppContextData | null>;
|
|
51
|
-
/** Get list of available
|
|
52
|
-
getList?: () => Promise<
|
|
91
|
+
/** Get list of available resources with pagination and search */
|
|
92
|
+
getList?: (options?: AppResourceListOptions) => Promise<AppResourceListResult>;
|
|
53
93
|
/** Get full content by ID */
|
|
54
94
|
getById?: (id: string) => Promise<AppContextData | null>;
|
|
55
95
|
}
|
|
@@ -207,6 +247,11 @@ declare class SanqianAppClient {
|
|
|
207
247
|
* Ensure SDK is ready (connects if needed, waits for registration)
|
|
208
248
|
*/
|
|
209
249
|
ensureReady(): Promise<void>;
|
|
250
|
+
/**
|
|
251
|
+
* Get the port number for the Sanqian backend
|
|
252
|
+
* @throws Error if not connected
|
|
253
|
+
*/
|
|
254
|
+
getPort(): number;
|
|
210
255
|
/**
|
|
211
256
|
* Request persistent connection (enables auto-reconnect)
|
|
212
257
|
* Call when a component needs the connection to stay alive
|
|
@@ -224,6 +269,11 @@ declare class SanqianAppClient {
|
|
|
224
269
|
createAgent(config: AppAgentConfig): Promise<{
|
|
225
270
|
agentId: string;
|
|
226
271
|
}>;
|
|
272
|
+
/**
|
|
273
|
+
* Update context providers dynamically
|
|
274
|
+
* Use this to update provider names/descriptions when locale changes
|
|
275
|
+
*/
|
|
276
|
+
updateContexts(contexts: AppContextProvider[]): Promise<void>;
|
|
227
277
|
/**
|
|
228
278
|
* Get embedding configuration from Sanqian
|
|
229
279
|
* @returns Embedding config or null if not available
|
|
@@ -619,6 +669,18 @@ declare class FloatingWindow {
|
|
|
619
669
|
isVisible(): boolean;
|
|
620
670
|
destroy(): void;
|
|
621
671
|
getWindow(): BrowserWindow | null;
|
|
672
|
+
/**
|
|
673
|
+
* Notify renderer that locale has changed.
|
|
674
|
+
* Call this after updating contexts with new locale via client.updateContexts().
|
|
675
|
+
*
|
|
676
|
+
* @example
|
|
677
|
+
* ```typescript
|
|
678
|
+
* // When locale changes
|
|
679
|
+
* await client.updateContexts(getLocalizedContexts(newLocale));
|
|
680
|
+
* floatingWindow.notifyLocaleChanged(newLocale);
|
|
681
|
+
* ```
|
|
682
|
+
*/
|
|
683
|
+
notifyLocaleChanged(locale: string): void;
|
|
622
684
|
}
|
|
623
685
|
|
|
624
686
|
/**
|
|
@@ -718,6 +780,18 @@ declare class ChatPanel {
|
|
|
718
780
|
* Get webContents (for IPC)
|
|
719
781
|
*/
|
|
720
782
|
getWebContents(): WebContents;
|
|
783
|
+
/**
|
|
784
|
+
* Notify renderer that locale has changed.
|
|
785
|
+
* Call this after updating contexts with new locale via client.updateContexts().
|
|
786
|
+
*
|
|
787
|
+
* @example
|
|
788
|
+
* ```typescript
|
|
789
|
+
* // When locale changes
|
|
790
|
+
* await client.updateContexts(getLocalizedContexts(newLocale));
|
|
791
|
+
* chatPanel.notifyLocaleChanged(newLocale);
|
|
792
|
+
* ```
|
|
793
|
+
*/
|
|
794
|
+
notifyLocaleChanged(locale: string): void;
|
|
721
795
|
/**
|
|
722
796
|
* Destroy panel
|
|
723
797
|
*/
|
|
@@ -839,4 +913,32 @@ declare class WindowAttachment {
|
|
|
839
913
|
private stopPolling;
|
|
840
914
|
}
|
|
841
915
|
|
|
842
|
-
|
|
916
|
+
/**
|
|
917
|
+
* @yushaw/sanqian-chat Main
|
|
918
|
+
*
|
|
919
|
+
* Electron main process module
|
|
920
|
+
*
|
|
921
|
+
* Provides:
|
|
922
|
+
* - SanqianAppClient: Facade for SDK, stable application-facing API
|
|
923
|
+
* - FloatingWindow: Floating chat window manager
|
|
924
|
+
* - ChatPanel: Embedded + Floating chat panel (new)
|
|
925
|
+
* - WindowAttachment: Floating window attachment (new)
|
|
926
|
+
* - getPreloadPath: Get the path to the built preload script
|
|
927
|
+
*/
|
|
928
|
+
/**
|
|
929
|
+
* Get the path to the chat SDK's built preload script.
|
|
930
|
+
* Use this when creating ChatPanel or FloatingWindow.
|
|
931
|
+
*
|
|
932
|
+
* @example
|
|
933
|
+
* ```typescript
|
|
934
|
+
* import { ChatPanel, getPreloadPath } from '@yushaw/sanqian-chat/main'
|
|
935
|
+
*
|
|
936
|
+
* const chatPanel = new ChatPanel({
|
|
937
|
+
* preloadPath: getPreloadPath(),
|
|
938
|
+
* // ...
|
|
939
|
+
* })
|
|
940
|
+
* ```
|
|
941
|
+
*/
|
|
942
|
+
declare function getPreloadPath(): string;
|
|
943
|
+
|
|
944
|
+
export { type AppAgentConfig, type AppClientEvent, type AppClientEventHandlers, type AppConfig, type AppContextData, type AppContextListItem, type AppContextProvider, type AppEmbeddingConfig, type AppJsonSchemaProperty, type AppResourceListOptions, type AppResourceListResult, type AppResourceType, type AppToolDefinition, type AttachConfig, type AttachPosition, type AttachState, ChatPanel, type ChatPanelConfig, type ChatPanelMode, type ChatPanelPosition, type ChatUiConfigSerializable, FloatingWindow, type FloatingWindowConfig, type FloatingWindowOptions, SanqianAppClient, WindowAttachment, type WindowPosition, getPreloadPath };
|