@morlay/ui-conversation-message-actions 0.0.19-alpha.5 → 0.0.19-alpha.6
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/dist/client.cjs +39 -64
- package/dist/index.mjs +8 -9
- package/dist/testing.d.cts +203 -414
- package/dist/testing.d.mts +203 -414
- package/dist/testing.mjs +2160 -825
- package/package.json +24 -24
- package/src/client/chat-node/MessageIconActions.tsx +12 -56
- package/src/client/chat-node/message-chrome.ts +0 -15
- package/src/client/composer-stats/StatsPills.tsx +6 -6
- package/src/client/controller.ts +31 -5
- package/src/index.ts +17 -12
- package/src/plan.ts +1 -1
- package/src/testing.ts +2 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@morlay/ui-conversation-message-actions",
|
|
3
|
-
"version": "0.0.19-alpha.
|
|
3
|
+
"version": "0.0.19-alpha.6",
|
|
4
4
|
"description": "Rewind / retry / fork orchestration (host) plus conversation.chat.node renderer replacement (browser) — message edit / retry actions on user bubbles.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"conversation-chat-node",
|
|
@@ -38,37 +38,37 @@
|
|
|
38
38
|
}
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@morlay/session-branch": "0.0.10-alpha.
|
|
41
|
+
"@morlay/session-branch": "0.0.10-alpha.6"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
|
-
"@deepseek-ai/dsh-session-stats": "0.1.
|
|
45
|
-
"@morlay/dsh-client-ui-primitives": "0.0.2-alpha.
|
|
46
|
-
"@morlay/session-rdb": "0.0.21-alpha.
|
|
44
|
+
"@deepseek-ai/dsh-session-stats": "0.1.7-alpha.1",
|
|
45
|
+
"@morlay/dsh-client-ui-primitives": "0.0.2-alpha.6",
|
|
46
|
+
"@morlay/session-rdb": "0.0.21-alpha.6",
|
|
47
47
|
"@types/react": "~18.3.1",
|
|
48
48
|
"@types/react-dom": "~18.3.0",
|
|
49
49
|
"react": "^18.2.0",
|
|
50
50
|
"react-dom": "^18.2.0"
|
|
51
51
|
},
|
|
52
52
|
"peerDependencies": {
|
|
53
|
-
"@deepseek-ai/cordis": "4.0.
|
|
54
|
-
"@deepseek-ai/dsh-api-session-controller": "0.1.
|
|
55
|
-
"@deepseek-ai/dsh-attachment": "0.1.
|
|
56
|
-
"@deepseek-ai/dsh-client-connection": "0.1.
|
|
57
|
-
"@deepseek-ai/dsh-client-store": "0.1.
|
|
58
|
-
"@deepseek-ai/dsh-client-ui-attachment": "0.1.
|
|
59
|
-
"@deepseek-ai/dsh-client-ui-chat": "0.1.
|
|
60
|
-
"@deepseek-ai/dsh-client-ui-primitives": "0.1.
|
|
61
|
-
"@deepseek-ai/dsh-client-ui-renderer": "0.1.
|
|
62
|
-
"@deepseek-ai/dsh-client-ui-slots": "0.1.
|
|
63
|
-
"@deepseek-ai/dsh-client-ui-workspace": "0.1.
|
|
64
|
-
"@deepseek-ai/dsh-invariants": "0.1.
|
|
65
|
-
"@deepseek-ai/dsh-llm": "0.1.
|
|
66
|
-
"@deepseek-ai/dsh-session": "0.1.
|
|
67
|
-
"@deepseek-ai/dsh-session-persistence": "0.1.
|
|
68
|
-
"@deepseek-ai/dsh-session-projection": "0.1.
|
|
69
|
-
"@deepseek-ai/dsh-token-meter": "0.1.
|
|
70
|
-
"@morlay/dsh-client-ui-conversation": "0.0.2-alpha.
|
|
71
|
-
"@morlay/dsh-client-ui-primitives": "0.0.2-alpha.
|
|
53
|
+
"@deepseek-ai/cordis": "4.0.3",
|
|
54
|
+
"@deepseek-ai/dsh-api-session-controller": "0.1.7-alpha.1",
|
|
55
|
+
"@deepseek-ai/dsh-attachment": "0.1.7-alpha.1",
|
|
56
|
+
"@deepseek-ai/dsh-client-connection": "0.1.7-alpha.1",
|
|
57
|
+
"@deepseek-ai/dsh-client-store": "0.1.7-alpha.1",
|
|
58
|
+
"@deepseek-ai/dsh-client-ui-attachment": "0.1.7-alpha.1",
|
|
59
|
+
"@deepseek-ai/dsh-client-ui-chat": "0.1.7-alpha.1",
|
|
60
|
+
"@deepseek-ai/dsh-client-ui-primitives": "0.1.7-alpha.1",
|
|
61
|
+
"@deepseek-ai/dsh-client-ui-renderer": "0.1.7-alpha.1",
|
|
62
|
+
"@deepseek-ai/dsh-client-ui-slots": "0.1.7-alpha.1",
|
|
63
|
+
"@deepseek-ai/dsh-client-ui-workspace": "0.1.7-alpha.1",
|
|
64
|
+
"@deepseek-ai/dsh-invariants": "0.1.7-alpha.1",
|
|
65
|
+
"@deepseek-ai/dsh-llm": "0.1.7-alpha.1",
|
|
66
|
+
"@deepseek-ai/dsh-session": "0.1.7-alpha.1",
|
|
67
|
+
"@deepseek-ai/dsh-session-persistence": "0.1.7-alpha.1",
|
|
68
|
+
"@deepseek-ai/dsh-session-projection": "0.1.7-alpha.1",
|
|
69
|
+
"@deepseek-ai/dsh-token-meter": "0.1.7-alpha.1",
|
|
70
|
+
"@morlay/dsh-client-ui-conversation": "0.0.2-alpha.6",
|
|
71
|
+
"@morlay/dsh-client-ui-primitives": "0.0.2-alpha.6"
|
|
72
72
|
},
|
|
73
73
|
"dsh": {
|
|
74
74
|
"bundle": {
|
|
@@ -4,21 +4,16 @@
|
|
|
4
4
|
import { styling } from "@morlay/dsh-client-ui-primitives/client";
|
|
5
5
|
import { useCallback, useEffect, useId, useRef, useState, type ReactNode } from "react";
|
|
6
6
|
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
IconBranchOutlineRegular,
|
|
8
|
+
IconCheckOutlineRegular,
|
|
9
|
+
IconCopyOutlineRegular,
|
|
10
|
+
IconEditOutlineRegular,
|
|
11
|
+
IconRefreshOutlineRegular,
|
|
12
12
|
Tooltip,
|
|
13
13
|
writeClipboard,
|
|
14
14
|
} from "@deepseek-ai/dsh-client-ui-primitives";
|
|
15
15
|
import type { ChatViewSlotProps } from "@deepseek-ai/dsh-client-ui-chat/client";
|
|
16
|
-
import {
|
|
17
|
-
formatLatencySeconds,
|
|
18
|
-
formatMessageClock,
|
|
19
|
-
formatRunDuration,
|
|
20
|
-
formatTokensPerSecond,
|
|
21
|
-
} from "./message-chrome.ts";
|
|
16
|
+
import { formatMessageClock } from "./message-chrome.ts";
|
|
22
17
|
import { useCalendarDay } from "./use-calendar-day.ts";
|
|
23
18
|
import { styles } from "./MessageIconActions.styles.ts";
|
|
24
19
|
|
|
@@ -27,12 +22,6 @@ export interface MessageIconActionsProps {
|
|
|
27
22
|
|
|
28
23
|
time?: number | undefined;
|
|
29
24
|
|
|
30
|
-
runMs?: number | undefined;
|
|
31
|
-
|
|
32
|
-
ttftMs?: number | undefined;
|
|
33
|
-
|
|
34
|
-
tokensPerSecond?: number | undefined;
|
|
35
|
-
|
|
36
25
|
clock: "start" | "end";
|
|
37
26
|
|
|
38
27
|
onBranch?: (() => void) | undefined;
|
|
@@ -53,9 +42,6 @@ export interface MessageIconActionsProps {
|
|
|
53
42
|
export function MessageIconActions({
|
|
54
43
|
text,
|
|
55
44
|
time,
|
|
56
|
-
runMs,
|
|
57
|
-
ttftMs,
|
|
58
|
-
tokensPerSecond,
|
|
59
45
|
clock,
|
|
60
46
|
onBranch,
|
|
61
47
|
branchUnavailable = false,
|
|
@@ -96,10 +82,8 @@ export function MessageIconActions({
|
|
|
96
82
|
}, 1000);
|
|
97
83
|
});
|
|
98
84
|
}, [copied, text]);
|
|
99
|
-
//
|
|
100
|
-
//
|
|
101
|
-
// run-on string ("Ran for 13sTime to first token (TTFT) 0.2s12 tok/s")
|
|
102
|
-
// instead of three facts.
|
|
85
|
+
// 只剩时钟:耗时 / TTFT / tok-s 的读数在 0.1.7 已不属于消息 chrome(上游把它们收进
|
|
86
|
+
// 会话统计弹窗与轮次过程节点),上游那套聊天文案表也不再提供这三个 key。
|
|
103
87
|
const clockEl =
|
|
104
88
|
time === undefined ? null : (
|
|
105
89
|
<span
|
|
@@ -107,34 +91,6 @@ export function MessageIconActions({
|
|
|
107
91
|
{...styling.props(clock === "start" ? styles.timeStart : styles.timeEnd)}
|
|
108
92
|
>
|
|
109
93
|
{formatMessageClock(time, t, day)}
|
|
110
|
-
{runMs !== undefined && (
|
|
111
|
-
<>
|
|
112
|
-
{" "}
|
|
113
|
-
<span {...styling.props(styles.runTimeDot)} aria-hidden>
|
|
114
|
-
·
|
|
115
|
-
</span>{" "}
|
|
116
|
-
{t("message.ranFor", { duration: formatRunDuration(runMs, t) })}
|
|
117
|
-
</>
|
|
118
|
-
)}
|
|
119
|
-
{ttftMs !== undefined && (
|
|
120
|
-
<>
|
|
121
|
-
{" "}
|
|
122
|
-
<span {...styling.props(styles.runTimeDot)} aria-hidden>
|
|
123
|
-
·
|
|
124
|
-
</span>{" "}
|
|
125
|
-
{t("message.turnTime.ttft")}{" "}
|
|
126
|
-
{t("duration.seconds", { seconds: formatLatencySeconds(ttftMs) })}
|
|
127
|
-
</>
|
|
128
|
-
)}
|
|
129
|
-
{tokensPerSecond !== undefined && (
|
|
130
|
-
<>
|
|
131
|
-
{" "}
|
|
132
|
-
<span {...styling.props(styles.runTimeDot)} aria-hidden>
|
|
133
|
-
·
|
|
134
|
-
</span>{" "}
|
|
135
|
-
{t("message.tokensPerSecond", { tps: formatTokensPerSecond(tokensPerSecond) })}
|
|
136
|
-
</>
|
|
137
|
-
)}
|
|
138
94
|
</span>
|
|
139
95
|
);
|
|
140
96
|
// 外部 className 需要拼接:给 actions 一个真实类名(而不是 data-css 属性)。
|
|
@@ -152,7 +108,7 @@ export function MessageIconActions({
|
|
|
152
108
|
aria-label={copied ? t("copied" as never) : t("copy" as never)}
|
|
153
109
|
onClick={onCopy}
|
|
154
110
|
>
|
|
155
|
-
{copied ? <
|
|
111
|
+
{copied ? <IconCheckOutlineRegular /> : <IconCopyOutlineRegular />}
|
|
156
112
|
</button>
|
|
157
113
|
</Tooltip>
|
|
158
114
|
{extraActions}
|
|
@@ -164,7 +120,7 @@ export function MessageIconActions({
|
|
|
164
120
|
aria-label="编辑"
|
|
165
121
|
onClick={onEdit}
|
|
166
122
|
>
|
|
167
|
-
<
|
|
123
|
+
<IconEditOutlineRegular />
|
|
168
124
|
</button>
|
|
169
125
|
</Tooltip>
|
|
170
126
|
)}
|
|
@@ -176,7 +132,7 @@ export function MessageIconActions({
|
|
|
176
132
|
aria-label="重试此回合"
|
|
177
133
|
onClick={onRetry}
|
|
178
134
|
>
|
|
179
|
-
<
|
|
135
|
+
<IconRefreshOutlineRegular />
|
|
180
136
|
</button>
|
|
181
137
|
</Tooltip>
|
|
182
138
|
)}
|
|
@@ -195,7 +151,7 @@ export function MessageIconActions({
|
|
|
195
151
|
data-unavailable={branchUnavailable || undefined}
|
|
196
152
|
onClick={branchUnavailable ? undefined : onBranch}
|
|
197
153
|
>
|
|
198
|
-
<
|
|
154
|
+
<IconBranchOutlineRegular />
|
|
199
155
|
</button>
|
|
200
156
|
</Tooltip>
|
|
201
157
|
)}
|
|
@@ -2,7 +2,6 @@ import type { Translate } from "@deepseek-ai/dsh-client-ui-slots";
|
|
|
2
2
|
|
|
3
3
|
export type ClockTranslate = Translate<"clock.md" | "clock.ymd">;
|
|
4
4
|
|
|
5
|
-
export type RunDurationTranslate = Translate<"duration.seconds" | "duration.minutes">;
|
|
6
5
|
function pad2(n: number): string {
|
|
7
6
|
return String(n).padStart(2, "0");
|
|
8
7
|
}
|
|
@@ -19,20 +18,6 @@ export function msUntilNextLocalMidnight(ms: number): number {
|
|
|
19
18
|
return Math.max(next.getTime() - ms, 1);
|
|
20
19
|
}
|
|
21
20
|
|
|
22
|
-
export function formatRunDuration(ms: number, t: RunDurationTranslate): string {
|
|
23
|
-
const total = Math.max(0, Math.floor(ms / 1000));
|
|
24
|
-
const minutes = Math.floor(total / 60);
|
|
25
|
-
const seconds = total % 60;
|
|
26
|
-
return minutes > 0
|
|
27
|
-
? t("duration.minutes", { minutes, seconds: String(seconds).padStart(2, "0") })
|
|
28
|
-
: t("duration.seconds", { seconds });
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export function formatLatencySeconds(ms: number): string {
|
|
32
|
-
const s = Math.max(0, ms) / 1000;
|
|
33
|
-
return s < 10 ? String(Math.round(s * 10) / 10) : String(Math.round(s));
|
|
34
|
-
}
|
|
35
|
-
|
|
36
21
|
export function formatTokensPerSecond(tps: number): string {
|
|
37
22
|
const clamped = Math.max(0, tps);
|
|
38
23
|
return clamped >= 10 ? String(Math.round(clamped)) : String(Math.round(clamped * 10) / 10);
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
import { memo, useMemo, useState } from "react";
|
|
10
10
|
import { createPortal } from "react-dom";
|
|
11
|
-
import {
|
|
11
|
+
import { IconDatabaseOutlineRegular, IconGaugeOutlineRegular } from "@deepseek-ai/dsh-client-ui-primitives";
|
|
12
12
|
import type { UseProjection } from "@deepseek-ai/dsh-api-session-controller/client";
|
|
13
13
|
import type { SnapshotSelectorHook } from "@deepseek-ai/dsh-client-ui-slots";
|
|
14
14
|
// Type-only: merges the sessionStats key into SessionProjectionMap for useProjection.
|
|
@@ -172,7 +172,7 @@ function TimePill({
|
|
|
172
172
|
return (
|
|
173
173
|
<span {...styling.props(styles.anchor)}>
|
|
174
174
|
<span {...styling.props(styles.pill)}>
|
|
175
|
-
<
|
|
175
|
+
<IconGaugeOutlineRegular />
|
|
176
176
|
{label}
|
|
177
177
|
</span>
|
|
178
178
|
</span>
|
|
@@ -190,7 +190,7 @@ function TimePill({
|
|
|
190
190
|
setOpen(!open);
|
|
191
191
|
}}
|
|
192
192
|
>
|
|
193
|
-
<
|
|
193
|
+
<IconGaugeOutlineRegular />
|
|
194
194
|
{label}
|
|
195
195
|
</button>
|
|
196
196
|
{open &&
|
|
@@ -204,7 +204,7 @@ function TimePill({
|
|
|
204
204
|
>
|
|
205
205
|
<div {...styling.props(dialogStyles.title)}>
|
|
206
206
|
<span {...styling.props(dialogStyles.titleLabel)}>
|
|
207
|
-
<
|
|
207
|
+
<IconGaugeOutlineRegular />
|
|
208
208
|
{t("stats.dialog.title")}
|
|
209
209
|
</span>
|
|
210
210
|
</div>
|
|
@@ -273,7 +273,7 @@ function UsagePill({
|
|
|
273
273
|
setOpen(!open);
|
|
274
274
|
}}
|
|
275
275
|
>
|
|
276
|
-
<
|
|
276
|
+
<IconDatabaseOutlineRegular />
|
|
277
277
|
<span {...styling.props(styles.label)}>
|
|
278
278
|
{totalText}
|
|
279
279
|
{cacheHitText !== null && (
|
|
@@ -297,7 +297,7 @@ function UsagePill({
|
|
|
297
297
|
>
|
|
298
298
|
<div {...styling.props(dialogStyles.title)}>
|
|
299
299
|
<span {...styling.props(dialogStyles.titleLabel)}>
|
|
300
|
-
<
|
|
300
|
+
<IconDatabaseOutlineRegular />
|
|
301
301
|
{t("stats.dialog.usageTitle")}
|
|
302
302
|
</span>
|
|
303
303
|
<span {...styling.props(dialogStyles.titleValue)}>{exactCount(total, t)}</span>
|
package/src/client/controller.ts
CHANGED
|
@@ -41,14 +41,22 @@ export class SessionEditorController {
|
|
|
41
41
|
this.face = {
|
|
42
42
|
retry: (turn, cascade) =>
|
|
43
43
|
this.mutate({ action: "retry", sessionId: this.sessionId, turn, cascade }),
|
|
44
|
-
recall: (message, texts) =>
|
|
45
|
-
this.mutate(
|
|
46
|
-
{ action: "recall", sessionId: this.sessionId, eventSeq: message.eventSeq },
|
|
47
|
-
() => this.setComposerDraft(texts.join("\n\n")),
|
|
48
|
-
),
|
|
44
|
+
recall: (message, texts) => this.recallAndEdit(message, texts),
|
|
49
45
|
};
|
|
50
46
|
}
|
|
51
47
|
|
|
48
|
+
private async recallAndEdit(
|
|
49
|
+
message: EditableMessageBlock,
|
|
50
|
+
texts: readonly string[],
|
|
51
|
+
): Promise<boolean> {
|
|
52
|
+
const applied = await this.mutate(
|
|
53
|
+
{ action: "recall", sessionId: this.sessionId, eventSeq: message.eventSeq },
|
|
54
|
+
() => this.setComposerDraft(texts.join("\n\n")),
|
|
55
|
+
);
|
|
56
|
+
if (applied) this.returnViewportToEnd();
|
|
57
|
+
return applied;
|
|
58
|
+
}
|
|
59
|
+
|
|
52
60
|
private async mutate(
|
|
53
61
|
operation: SessionEditorOperation,
|
|
54
62
|
onApplied?: () => void,
|
|
@@ -114,6 +122,24 @@ export class SessionEditorController {
|
|
|
114
122
|
);
|
|
115
123
|
}
|
|
116
124
|
|
|
125
|
+
/**
|
|
126
|
+
* 撤回后把会话视口送回底部:rewind 把窗口换短,而上游 ChatView 只在读者已经贴底时
|
|
127
|
+
* 才跟随(`tipMoved && atBottom`),停在中途的视口会悬在被截断的位置上;撤回的下一步
|
|
128
|
+
* 是改完再发,所以这里无条件送到底。容器用上游既有契约 `[data-conversation-scroll]`
|
|
129
|
+
* (ChatView / ConversationWidthControls / StatsPills 同用)。
|
|
130
|
+
*
|
|
131
|
+
* 窗口替换的渲染落在 resync 之后:写早了会被下一轮布局覆盖,因此等两帧再写。
|
|
132
|
+
*/
|
|
133
|
+
private returnViewportToEnd(): void {
|
|
134
|
+
const scrollport = document.querySelector<HTMLElement>("[data-conversation-scroll]");
|
|
135
|
+
if (scrollport === null) return;
|
|
136
|
+
requestAnimationFrame(() => {
|
|
137
|
+
requestAnimationFrame(() => {
|
|
138
|
+
scrollport.scrollTop = scrollport.scrollHeight;
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
|
|
117
143
|
private setComposerDraft(text: string): void {
|
|
118
144
|
if (this.sessions.binding(this.sessionId) === undefined) return;
|
|
119
145
|
const scoped = this.sessions.scope(this.sessionId);
|
package/src/index.ts
CHANGED
|
@@ -179,7 +179,7 @@ export class SessionEditor extends Service {
|
|
|
179
179
|
constructor(ctx: Context) {
|
|
180
180
|
super(ctx, "sessionEditor");
|
|
181
181
|
|
|
182
|
-
registerHttpRoutes(ctx);
|
|
182
|
+
registerHttpRoutes(ctx, this);
|
|
183
183
|
}
|
|
184
184
|
|
|
185
185
|
readBranchPrefix(
|
|
@@ -643,17 +643,22 @@ async function handleRoute(
|
|
|
643
643
|
}
|
|
644
644
|
}
|
|
645
645
|
|
|
646
|
-
function registerHttpRoutes(ctx: Context): void {
|
|
647
|
-
ctx.
|
|
646
|
+
function registerHttpRoutes(ctx: Context, editor: SessionEditor): void {
|
|
647
|
+
// webServer **必须等**:它可能比本行晚激活,而 `ctx.get` 取到 undefined 之后不会再试一次——路由没注册的
|
|
648
|
+
// 后果是请求落到 frontend-static 的 fallback,非 GET/HEAD 一律 405(编辑撤回 / 重试就是这个症状)。
|
|
649
|
+
ctx.inject(["webServer"], (scope) => {
|
|
648
650
|
// webServer 的类型由上游 @deepseek-ai/dsh-host-webserver 声明(`Context.webServer: WebServer`);
|
|
649
651
|
// 这里只按用到的 register 面做结构转换,不再 declare module 覆盖,否则两处声明冲突(TS2717)。
|
|
650
|
-
const webServer =
|
|
651
|
-
if (webServer === undefined) return
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
652
|
+
const webServer = scope.get("webServer") as unknown as HttpServerLike | undefined;
|
|
653
|
+
if (webServer === undefined) return;
|
|
654
|
+
scope.effect(
|
|
655
|
+
() =>
|
|
656
|
+
webServer.register({
|
|
657
|
+
kind: "exact",
|
|
658
|
+
path: SESSION_EDITOR_PATH,
|
|
659
|
+
handler: (request, response) => handleRoute(editor, request, response),
|
|
660
|
+
}),
|
|
661
|
+
"session-editor: HTTP route",
|
|
662
|
+
);
|
|
663
|
+
});
|
|
659
664
|
}
|
package/src/plan.ts
CHANGED
|
@@ -52,7 +52,7 @@ function userText(message: UserMessage): string {
|
|
|
52
52
|
|
|
53
53
|
function cloneUser(
|
|
54
54
|
message: UserMessage,
|
|
55
|
-
content: ContentBlock[] = structuredClone(message.content),
|
|
55
|
+
content: readonly ContentBlock[] = structuredClone(message.content) as ContentBlock[],
|
|
56
56
|
): UserMessage {
|
|
57
57
|
return Object.freeze({
|
|
58
58
|
id: randomUUID(),
|
package/src/testing.ts
CHANGED
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
import SessionProjectionRegistry from "@deepseek-ai/dsh-session-projection";
|
|
12
12
|
import SessionPersistenceSqlite from "@morlay/session-rdb";
|
|
13
13
|
import { parseJsonlArtifact } from "@morlay/session-rdb/artifact";
|
|
14
|
-
import {
|
|
14
|
+
import { meta, oneTurnLog } from "@morlay/session-rdb/testing";
|
|
15
15
|
import { SESSION_EDITOR_PATH } from "./shared.ts";
|
|
16
16
|
import { SessionEditor } from "@morlay/ui-conversation-message-actions";
|
|
17
17
|
|
|
@@ -22,7 +22,6 @@ export {
|
|
|
22
22
|
SessionSeq,
|
|
23
23
|
SessionStore,
|
|
24
24
|
TokenMeter,
|
|
25
|
-
EmptySettings,
|
|
26
25
|
meta,
|
|
27
26
|
oneTurnLog,
|
|
28
27
|
parseJsonlArtifact,
|
|
@@ -37,7 +36,6 @@ export interface Harness {
|
|
|
37
36
|
|
|
38
37
|
export async function harness(provide?: (ctx: Context) => void): Promise<Harness> {
|
|
39
38
|
const ctx = new Context();
|
|
40
|
-
await ctx.plugin(EmptySettings);
|
|
41
39
|
await ctx.plugin(SessionStore);
|
|
42
40
|
new SessionProjectionRegistry(ctx);
|
|
43
41
|
const fiber = await ctx.plugin(SessionPersistenceSqlite, { type: "sqlite", path: ":memory:" });
|
|
@@ -87,7 +85,7 @@ export function userMessage(seq: number, id: string, text: string, time = seq):
|
|
|
87
85
|
source: { kind: "user" },
|
|
88
86
|
},
|
|
89
87
|
surfaceOp: "append",
|
|
90
|
-
} as SessionEvent;
|
|
88
|
+
} as unknown as SessionEvent;
|
|
91
89
|
}
|
|
92
90
|
|
|
93
91
|
export function assistantMessage(
|