@nextclaw/ui 0.15.24 → 0.15.25
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/CHANGELOG.md +21 -0
- package/dist/assets/{api-BxPNDp30.js → api-FK7tikI1.js} +3 -3
- package/dist/assets/appearance-settings-page-BYbvl2wj.js +1 -0
- package/dist/assets/{channels-list-page-DRaNWAxC.js → channels-list-page-CocdcIko.js} +2 -2
- package/dist/assets/chat-page-C5E-LLVd.js +1 -0
- package/dist/assets/{config-split-page-BVWVDbvG.js → config-split-page-CA_a0AJ5.js} +1 -1
- package/dist/assets/{confirm-dialog-mA2iVzxh.js → confirm-dialog-CxZfenjK.js} +1 -1
- package/dist/assets/{desktop-update-config-DyQb1LXr.js → desktop-update-config-BEKC8Ly9.js} +1 -1
- package/dist/assets/{dist-B4Pf5X3Q.js → dist-BH7W5yCi.js} +1 -1
- package/dist/assets/{dist-DHEWkGWX.js → dist-CaYdVVeO.js} +1 -1
- package/dist/assets/doc-browser-Cl2ldE3f.js +1 -0
- package/dist/assets/doc-browser-DXCSd63E.js +1 -0
- package/dist/assets/{doc-browser-context-CuGI6PQc.js → doc-browser-context-FDPs3gJf.js} +1 -1
- package/dist/assets/{form-actions-BOfIyG3O.js → form-actions-0c0aw_bl.js} +1 -1
- package/dist/assets/i18n-provider-DkITJNz8.js +1 -0
- package/dist/assets/index-CQ2LcI2p.css +1 -0
- package/dist/assets/index-CrdfvBVg.js +107 -0
- package/dist/assets/loader-circle-DHtUxCIA.js +1 -0
- package/dist/assets/{mcp-marketplace-page-ofDqbOIF.js → mcp-marketplace-page-Bc_jI5iH.js} +2 -2
- package/dist/assets/mcp-marketplace-page-CzCieD9r.js +1 -0
- package/dist/assets/{model-config-page-D73Tu3jW.js → model-config-page-C4jw-pcj.js} +1 -1
- package/dist/assets/{navigation-link-CAFOcXNg.js → navigation-link-CVy0_kVl.js} +1 -1
- package/dist/assets/plus-CG1RwZQq.js +1 -0
- package/dist/assets/{provider-scoped-model-input-BaJJJYMX.js → provider-scoped-model-input-CmH4BFvc.js} +1 -1
- package/dist/assets/{providers-config-page-BL6IRVBm.js → providers-config-page-CJQjwzaw.js} +1 -1
- package/dist/assets/{react-BC_orpAj.js → react-DjFBVA0n.js} +1 -1
- package/dist/assets/{refresh-cw-CWDp_JnN.js → refresh-cw-j2bl79Ea.js} +1 -1
- package/dist/assets/remote-BIlpD3yL.js +1 -0
- package/dist/assets/rotate-cw-bKG8zH8M.js +1 -0
- package/dist/assets/runtime-config-page-B_x2Glz5.js +1 -0
- package/dist/assets/{save-Cnr71JON.js → save-BKNrtK81.js} +1 -1
- package/dist/assets/{search-CCX11X2m.js → search-CkOm65W_.js} +1 -1
- package/dist/assets/{search-config-page-BB6d5gT7.js → search-config-page-BaIijtmO.js} +1 -1
- package/dist/assets/{secrets-config-page-DYsDeT9K.js → secrets-config-page-CJjtdFAl.js} +2 -2
- package/dist/assets/security-config-DB8apj09.js +1 -0
- package/dist/assets/{select-DvwBu99K.js → select-Ea7ffKCE.js} +1 -1
- package/dist/assets/{settings-2-Dmv6zMne.js → settings-2-CtyN3m_V.js} +1 -1
- package/dist/assets/skeleton-Bt6zxcAB.js +1 -0
- package/dist/assets/{tag-chip-gMPvx7n_.js → tag-chip-C9l4xsKp.js} +1 -1
- package/dist/assets/x-CowtCu9Z.js +1 -0
- package/dist/index.html +20 -20
- package/package.json +8 -8
- package/src/features/chat/features/conversation/components/__tests__/session-conversation-area.test.tsx +30 -1
- package/src/features/chat/features/conversation/components/session-conversation-area.tsx +1 -1
- package/src/features/chat/features/ncp/hooks/__tests__/use-hydrated-ncp-agent.test.tsx +40 -3
- package/src/features/chat/features/workspace/components/__tests__/chat-session-workspace-file-preview.selection.test.tsx +66 -0
- package/src/features/chat/features/workspace/components/__tests__/chat-session-workspace-file-preview.test.tsx +13 -1
- package/src/features/chat/features/workspace/components/__tests__/chat-session-workspace-panel-content.test.tsx +573 -90
- package/src/features/chat/features/workspace/components/chat-session-workspace-directory-browser.tsx +389 -288
- package/src/features/chat/features/workspace/components/chat-session-workspace-file-breadcrumbs.tsx +54 -35
- package/src/features/chat/features/workspace/components/chat-session-workspace-file-preview.tsx +79 -148
- package/src/features/chat/features/workspace/components/chat-session-workspace-panel-content.tsx +149 -94
- package/src/features/chat/features/workspace/components/project-files/__tests__/workspace-directory-entry-menu.test.tsx +50 -0
- package/src/features/chat/features/workspace/components/project-files/workspace-directory-entry-menu.tsx +209 -0
- package/src/features/chat/features/workspace/components/project-files/workspace-directory-tree.tsx +411 -0
- package/src/features/chat/features/workspace/components/project-files/workspace-new-folder-tree-item.tsx +112 -0
- package/src/features/chat/features/workspace/components/project-files/workspace-project-files-toolbar.tsx +64 -0
- package/src/features/chat/features/workspace/hooks/use-workspace-explorer-layout.ts +88 -0
- package/src/features/chat/features/workspace/hooks/use-workspace-file-actions.ts +335 -0
- package/src/features/chat/features/workspace/utils/chat-workspace-file-path-mutation.utils.ts +58 -0
- package/src/features/chat/features/workspace/utils/chat-workspace-file-tab.utils.ts +23 -22
- package/src/features/chat/features/workspace/utils/chat-workspace-panel-layout.utils.ts +13 -4
- package/src/features/chat/managers/__tests__/chat-composer-intent.manager.test.ts +86 -60
- package/src/features/chat/managers/__tests__/chat-thread.manager.test.ts +103 -99
- package/src/features/chat/managers/chat-composer-intent.manager.ts +37 -33
- package/src/features/chat/managers/chat-thread.manager.ts +132 -128
- package/src/features/chat/stores/__tests__/chat-thread.store.test.ts +20 -40
- package/src/features/chat/stores/chat-thread.store.ts +47 -74
- package/src/shared/components/resizable-right-panel/__tests__/resizable-right-panel.test.tsx +35 -38
- package/src/shared/components/resizable-right-panel/resizable-right-panel.tsx +25 -19
- package/src/shared/components/ui/context-menu/__tests__/context-menu.test.tsx +60 -34
- package/src/shared/components/ui/context-menu/context-menu.tsx +95 -68
- package/src/shared/lib/api/managers/client.manager.ts +31 -17
- package/src/shared/lib/api/server-path/server-path.types.ts +66 -0
- package/src/shared/lib/api/types.ts +145 -116
- package/src/shared/lib/api/utils/server-path.utils.ts +35 -11
- package/src/shared/lib/i18n/locales/en-US/chat.json +42 -0
- package/src/shared/lib/i18n/locales/zh-CN/chat.json +42 -0
- package/dist/assets/appearance-settings-page-DpVJjvkB.js +0 -1
- package/dist/assets/chat-page-BuFDmG5_.js +0 -1
- package/dist/assets/doc-browser-CtO_HtRy.js +0 -1
- package/dist/assets/doc-browser-eMUagyBV.js +0 -1
- package/dist/assets/index-BjBdWHV1.js +0 -107
- package/dist/assets/index-DmpmjAGQ.css +0 -1
- package/dist/assets/loader-circle-Df8wF2Pr.js +0 -1
- package/dist/assets/mcp-marketplace-page-DI49IKxp.js +0 -1
- package/dist/assets/plus-DVU5RLCS.js +0 -1
- package/dist/assets/remote-T24O58lH.js +0 -1
- package/dist/assets/rotate-cw-BqhwSV5p.js +0 -1
- package/dist/assets/runtime-config-page-CXUx017t.js +0 -1
- package/dist/assets/security-config-CVPgqL7G.js +0 -1
- package/dist/assets/skeleton-C5tWata3.js +0 -1
- package/dist/assets/use-confirm-dialog-D_3-QpZU.js +0 -1
- package/dist/assets/x-BEWSqeux.js +0 -1
|
@@ -11,15 +11,12 @@ export function createWorkspaceFileTab(
|
|
|
11
11
|
return null;
|
|
12
12
|
}
|
|
13
13
|
const normalizedParentSessionKey = parentSessionKey?.trim() || null;
|
|
14
|
-
const previewViewer =
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
const viewIdentity = action.viewMode === 'preview' && previewViewer === 'rendered'
|
|
21
|
-
? 'preview:rendered'
|
|
22
|
-
: action.viewMode;
|
|
14
|
+
const previewViewer =
|
|
15
|
+
action.viewMode === 'preview'
|
|
16
|
+
? normalizeWorkspaceFilePreviewViewer(path, action.previewViewer ?? (action.line ? 'source' : undefined))
|
|
17
|
+
: (action.previewViewer ?? null);
|
|
18
|
+
const viewIdentity =
|
|
19
|
+
action.viewMode === 'preview' && previewViewer === 'rendered' ? 'preview:rendered' : action.viewMode;
|
|
23
20
|
return {
|
|
24
21
|
key: `${normalizedParentSessionKey ?? 'draft'}::${viewIdentity}::${path}`,
|
|
25
22
|
parentSessionKey: normalizedParentSessionKey,
|
|
@@ -53,28 +50,32 @@ export function upsertWorkspaceFileTab(
|
|
|
53
50
|
nextTabs[existingIndex] = { ...tabs[existingIndex], ...nextTab };
|
|
54
51
|
return nextTabs;
|
|
55
52
|
}
|
|
56
|
-
const adjacentIndex = adjacentToKey
|
|
57
|
-
? tabs.findIndex((tab) => tab.key === adjacentToKey)
|
|
58
|
-
: -1;
|
|
53
|
+
const adjacentIndex = adjacentToKey ? tabs.findIndex((tab) => tab.key === adjacentToKey) : -1;
|
|
59
54
|
if (adjacentIndex === -1) {
|
|
60
55
|
return [nextTab, ...tabs];
|
|
61
56
|
}
|
|
62
|
-
return [
|
|
63
|
-
...tabs.slice(0, adjacentIndex + 1),
|
|
64
|
-
nextTab,
|
|
65
|
-
...tabs.slice(adjacentIndex + 1),
|
|
66
|
-
];
|
|
57
|
+
return [...tabs.slice(0, adjacentIndex + 1), nextTab, ...tabs.slice(adjacentIndex + 1)];
|
|
67
58
|
}
|
|
68
59
|
|
|
69
|
-
export function
|
|
60
|
+
export function replaceWorkspaceFileTabPath(
|
|
70
61
|
tab: ChatWorkspaceFileTab,
|
|
71
|
-
|
|
62
|
+
path: string,
|
|
63
|
+
label?: string | null,
|
|
72
64
|
): ChatWorkspaceFileTab {
|
|
65
|
+
const viewIdentity =
|
|
66
|
+
tab.viewMode === 'preview' && tab.previewViewer === 'rendered' ? 'preview:rendered' : tab.viewMode;
|
|
67
|
+
return {
|
|
68
|
+
...tab,
|
|
69
|
+
key: `${tab.parentSessionKey ?? 'draft'}::${viewIdentity}::${path}`,
|
|
70
|
+
path,
|
|
71
|
+
label: label?.trim() || tab.label,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export function reparentWorkspaceFileTab(tab: ChatWorkspaceFileTab, parentSessionKey: string): ChatWorkspaceFileTab {
|
|
73
76
|
const normalizedParentSessionKey = parentSessionKey.trim();
|
|
74
77
|
const identitySeparatorIndex = tab.key.indexOf('::');
|
|
75
|
-
const tabIdentity = identitySeparatorIndex >= 0
|
|
76
|
-
? tab.key.slice(identitySeparatorIndex)
|
|
77
|
-
: `::${tab.key}`;
|
|
78
|
+
const tabIdentity = identitySeparatorIndex >= 0 ? tab.key.slice(identitySeparatorIndex) : `::${tab.key}`;
|
|
78
79
|
return {
|
|
79
80
|
...tab,
|
|
80
81
|
key: `${normalizedParentSessionKey}${tabIdentity}`,
|
|
@@ -2,12 +2,21 @@ export const CHAT_WORKSPACE_PANEL_DEFAULT_WIDTH = 480;
|
|
|
2
2
|
export const CHAT_WORKSPACE_PANEL_MIN_WIDTH = 360;
|
|
3
3
|
export const CHAT_WORKSPACE_PANEL_MAX_WIDTH = 860;
|
|
4
4
|
|
|
5
|
+
export const CHAT_WORKSPACE_EXPLORER_DEFAULT_WIDTH = 224;
|
|
6
|
+
export const CHAT_WORKSPACE_EXPLORER_MIN_WIDTH = 192;
|
|
7
|
+
export const CHAT_WORKSPACE_EXPLORER_MAX_WIDTH = 400;
|
|
8
|
+
export const CHAT_WORKSPACE_EXPLORER_COMPACT_THRESHOLD = 560;
|
|
9
|
+
|
|
5
10
|
export function normalizeChatWorkspacePanelWidth(value: unknown): number {
|
|
6
11
|
if (typeof value !== 'number' || !Number.isFinite(value)) {
|
|
7
12
|
return CHAT_WORKSPACE_PANEL_DEFAULT_WIDTH;
|
|
8
13
|
}
|
|
9
|
-
return Math.max(
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
14
|
+
return Math.max(CHAT_WORKSPACE_PANEL_MIN_WIDTH, Math.min(CHAT_WORKSPACE_PANEL_MAX_WIDTH, value));
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function normalizeChatWorkspaceExplorerWidth(value: unknown): number {
|
|
18
|
+
if (typeof value !== 'number' || !Number.isFinite(value)) {
|
|
19
|
+
return CHAT_WORKSPACE_EXPLORER_DEFAULT_WIDTH;
|
|
20
|
+
}
|
|
21
|
+
return Math.max(CHAT_WORKSPACE_EXPLORER_MIN_WIDTH, Math.min(CHAT_WORKSPACE_EXPLORER_MAX_WIDTH, value));
|
|
13
22
|
}
|
|
@@ -1,129 +1,155 @@
|
|
|
1
|
-
import { describe, expect, it, vi } from
|
|
2
|
-
import { ChatComposerIntentManager } from
|
|
1
|
+
import { describe, expect, it, vi } from 'vitest';
|
|
2
|
+
import { ChatComposerIntentManager } from '@/features/chat/managers/chat-composer-intent.manager';
|
|
3
3
|
|
|
4
|
-
describe(
|
|
5
|
-
it(
|
|
4
|
+
describe('ChatComposerIntentManager', () => {
|
|
5
|
+
it('delivers a file reference only to the targeted composer', () => {
|
|
6
6
|
const manager = new ChatComposerIntentManager();
|
|
7
7
|
const draftListener = vi.fn();
|
|
8
8
|
const sessionListener = vi.fn();
|
|
9
9
|
manager.subscribe(null, draftListener);
|
|
10
|
-
manager.subscribe(
|
|
10
|
+
manager.subscribe('session-1', sessionListener);
|
|
11
11
|
|
|
12
12
|
manager.requestFileReference({
|
|
13
13
|
targetSessionKey: null,
|
|
14
|
-
tokenKey:
|
|
15
|
-
label:
|
|
14
|
+
tokenKey: 'docs/guide.md',
|
|
15
|
+
label: 'guide.md',
|
|
16
16
|
});
|
|
17
17
|
|
|
18
18
|
expect(draftListener).toHaveBeenCalledWith(
|
|
19
19
|
expect.objectContaining({
|
|
20
20
|
targetSessionKey: null,
|
|
21
|
-
tokenKey:
|
|
22
|
-
label:
|
|
21
|
+
tokenKey: 'docs/guide.md',
|
|
22
|
+
label: 'guide.md',
|
|
23
23
|
}),
|
|
24
24
|
);
|
|
25
25
|
expect(sessionListener).not.toHaveBeenCalled();
|
|
26
26
|
});
|
|
27
27
|
|
|
28
|
-
it(
|
|
28
|
+
it('keeps an intent pending until its matching composer mounts', () => {
|
|
29
29
|
const manager = new ChatComposerIntentManager();
|
|
30
30
|
manager.requestFileReference({
|
|
31
|
-
targetSessionKey:
|
|
32
|
-
tokenKey:
|
|
33
|
-
label:
|
|
31
|
+
targetSessionKey: ' session-1 ',
|
|
32
|
+
tokenKey: ' src/index.ts ',
|
|
33
|
+
label: ' index.ts ',
|
|
34
34
|
});
|
|
35
35
|
|
|
36
36
|
expect(manager.consumePending(null)).toBeNull();
|
|
37
|
-
expect(manager.consumePending(
|
|
38
|
-
targetSessionKey:
|
|
39
|
-
tokenKey:
|
|
40
|
-
label:
|
|
37
|
+
expect(manager.consumePending('session-1')).toMatchObject({
|
|
38
|
+
targetSessionKey: 'session-1',
|
|
39
|
+
tokenKey: 'src/index.ts',
|
|
40
|
+
label: 'index.ts',
|
|
41
41
|
});
|
|
42
|
-
expect(manager.consumePending(
|
|
42
|
+
expect(manager.consumePending('session-1')).toBeNull();
|
|
43
43
|
});
|
|
44
44
|
|
|
45
|
-
it(
|
|
45
|
+
it('publishes a directory reference with the workspace directory kind', () => {
|
|
46
|
+
const manager = new ChatComposerIntentManager();
|
|
47
|
+
const listener = vi.fn();
|
|
48
|
+
manager.subscribe('session-1', listener);
|
|
49
|
+
|
|
50
|
+
manager.requestDirectoryReference({
|
|
51
|
+
targetSessionKey: 'session-1',
|
|
52
|
+
tokenKey: 'docs/designs',
|
|
53
|
+
label: 'designs',
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
expect(listener).toHaveBeenCalledWith(
|
|
57
|
+
expect.objectContaining({
|
|
58
|
+
kind: 'workspace_directory',
|
|
59
|
+
tokenKey: 'docs/designs',
|
|
60
|
+
label: 'designs',
|
|
61
|
+
}),
|
|
62
|
+
);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it('ignores incomplete file references', () => {
|
|
46
66
|
const manager = new ChatComposerIntentManager();
|
|
47
67
|
const listener = vi.fn();
|
|
48
68
|
manager.subscribe(null, listener);
|
|
49
69
|
|
|
50
70
|
manager.requestFileReference({
|
|
51
71
|
targetSessionKey: null,
|
|
52
|
-
tokenKey:
|
|
53
|
-
label:
|
|
72
|
+
tokenKey: ' ',
|
|
73
|
+
label: 'README.md',
|
|
54
74
|
});
|
|
55
75
|
|
|
56
76
|
expect(listener).not.toHaveBeenCalled();
|
|
57
77
|
expect(manager.consumePending(null)).toBeNull();
|
|
58
78
|
});
|
|
59
79
|
|
|
60
|
-
it(
|
|
80
|
+
it('publishes a source-aware excerpt with a stable content identity', () => {
|
|
61
81
|
const manager = new ChatComposerIntentManager();
|
|
62
82
|
const listener = vi.fn();
|
|
63
|
-
manager.subscribe(
|
|
83
|
+
manager.subscribe('session-1', listener);
|
|
64
84
|
|
|
65
85
|
manager.requestExcerptReference({
|
|
66
|
-
targetSessionKey:
|
|
67
|
-
path:
|
|
68
|
-
label:
|
|
69
|
-
excerpt:
|
|
86
|
+
targetSessionKey: 'session-1',
|
|
87
|
+
path: 'docs/guide.md',
|
|
88
|
+
label: 'guide.md',
|
|
89
|
+
excerpt: 'selected text',
|
|
70
90
|
startLine: 12,
|
|
71
91
|
endLine: 13,
|
|
72
92
|
});
|
|
73
93
|
|
|
74
|
-
expect(listener).toHaveBeenCalledWith(
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
94
|
+
expect(listener).toHaveBeenCalledWith(
|
|
95
|
+
expect.objectContaining({
|
|
96
|
+
kind: 'workspace_excerpt',
|
|
97
|
+
path: 'docs/guide.md',
|
|
98
|
+
label: 'guide.md',
|
|
99
|
+
excerpt: 'selected text',
|
|
100
|
+
startLine: 12,
|
|
101
|
+
endLine: 13,
|
|
102
|
+
tokenKey: expect.stringMatching(/^docs\/guide\.md#excerpt-/),
|
|
103
|
+
}),
|
|
104
|
+
);
|
|
83
105
|
});
|
|
84
106
|
|
|
85
|
-
it(
|
|
107
|
+
it('delivers an excerpt to the unmaterialized new-chat composer', () => {
|
|
86
108
|
const manager = new ChatComposerIntentManager();
|
|
87
109
|
const draftListener = vi.fn();
|
|
88
110
|
manager.subscribe(null, draftListener);
|
|
89
111
|
|
|
90
112
|
manager.requestExcerptReference({
|
|
91
113
|
targetSessionKey: null,
|
|
92
|
-
path:
|
|
93
|
-
label:
|
|
114
|
+
path: 'package.json',
|
|
115
|
+
label: 'package.json',
|
|
94
116
|
excerpt: '"name": "nextclaw"',
|
|
95
117
|
startLine: 2,
|
|
96
118
|
endLine: 2,
|
|
97
119
|
});
|
|
98
120
|
|
|
99
|
-
expect(draftListener).toHaveBeenCalledWith(
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
121
|
+
expect(draftListener).toHaveBeenCalledWith(
|
|
122
|
+
expect.objectContaining({
|
|
123
|
+
targetSessionKey: null,
|
|
124
|
+
kind: 'workspace_excerpt',
|
|
125
|
+
path: 'package.json',
|
|
126
|
+
excerpt: '"name": "nextclaw"',
|
|
127
|
+
}),
|
|
128
|
+
);
|
|
105
129
|
});
|
|
106
130
|
|
|
107
|
-
it(
|
|
131
|
+
it('publishes a conversation excerpt with its source message identity', () => {
|
|
108
132
|
const manager = new ChatComposerIntentManager();
|
|
109
133
|
const listener = vi.fn();
|
|
110
|
-
manager.subscribe(
|
|
134
|
+
manager.subscribe('session-1', listener);
|
|
111
135
|
|
|
112
136
|
manager.requestConversationExcerptReference({
|
|
113
|
-
targetSessionKey:
|
|
114
|
-
messageId:
|
|
115
|
-
role:
|
|
116
|
-
label:
|
|
117
|
-
excerpt:
|
|
137
|
+
targetSessionKey: 'session-1',
|
|
138
|
+
messageId: 'assistant-message-1',
|
|
139
|
+
role: 'assistant',
|
|
140
|
+
label: 'AI reply',
|
|
141
|
+
excerpt: 'Keep the visible tag concise.',
|
|
118
142
|
});
|
|
119
143
|
|
|
120
|
-
expect(listener).toHaveBeenCalledWith(
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
144
|
+
expect(listener).toHaveBeenCalledWith(
|
|
145
|
+
expect.objectContaining({
|
|
146
|
+
kind: 'conversation_excerpt',
|
|
147
|
+
messageId: 'assistant-message-1',
|
|
148
|
+
role: 'assistant',
|
|
149
|
+
label: 'AI reply',
|
|
150
|
+
excerpt: 'Keep the visible tag concise.',
|
|
151
|
+
tokenKey: expect.stringMatching(/^assistant-message-1#excerpt-/),
|
|
152
|
+
}),
|
|
153
|
+
);
|
|
128
154
|
});
|
|
129
155
|
});
|