@morlay/ui-conversation-message-actions 0.0.19-alpha.3 → 0.0.19-alpha.4

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/src/plan.ts CHANGED
@@ -1,14 +1,8 @@
1
1
  import { randomUUID } from "node:crypto";
2
2
  import type { AssistantMessage, ContentBlock, UserMessage } from "@deepseek-ai/dsh-llm";
3
3
  import { SessionSeq } from "@deepseek-ai/dsh-session";
4
- import type { SessionEvent, SessionId } from "@deepseek-ai/dsh-session";
5
- import {
6
- SESSION_BRANCH_VERSION_SCHEMA,
7
- SessionBranchError,
8
- type EditableBlockKind,
9
- type SessionBranchEffect,
10
- type SessionBranchVersionEvent,
11
- } from "@morlay/session-branch";
4
+ import type { SessionEvent } from "@deepseek-ai/dsh-session";
5
+ import { SessionBranchError } from "@morlay/session-branch";
12
6
  import type {
13
7
  EditOperation,
14
8
  EditableMessageBlock,
@@ -34,7 +28,6 @@ export interface OperationPlan {
34
28
  anchorSeq: number;
35
29
 
36
30
  rewindBoundary?: number;
37
- version: SessionBranchVersionEvent;
38
31
 
39
32
  manualTurn?: { turn: number; user: UserMessage; assistant: AssistantMessage };
40
33
 
@@ -220,17 +213,6 @@ function assistantReplacement(
220
213
  }) as AssistantMessage;
221
214
  }
222
215
 
223
- function pairVersionEffect(
224
- sourceSessionId: SessionId,
225
- effect: Omit<SessionBranchEffect, "id">,
226
- ): SessionBranchVersionEvent {
227
- return {
228
- schemaVersion: SESSION_BRANCH_VERSION_SCHEMA,
229
- effect: { ...effect, id: randomUUID() },
230
- inverse: { kind: "restore-version", sessionId: sourceSessionId },
231
- };
232
- }
233
-
234
216
  export function editPlan(operation: EditOperation, turns: readonly ClosedTurn[]): OperationPlan {
235
217
  const turnIndex = turns.findIndex(
236
218
  (turn) =>
@@ -262,16 +244,6 @@ export function editPlan(operation: EditOperation, turns: readonly ClosedTurn[])
262
244
  anchorSeq: turn.startSeq,
263
245
 
264
246
  ...(userIndex === 0 ? {} : { rewindBoundary: event.seq }),
265
- version: pairVersionEffect(operation.sessionId, {
266
- operation: "edit",
267
- cascade: operation.cascade,
268
- targetTurn: turn.turn,
269
- targetEventSeq: event.seq,
270
- targetBlockIndex: operation.blockIndex,
271
- blockKind: "user",
272
- before: before.text,
273
- after: operation.text,
274
- }),
275
247
  queuedUsers: [edited, ...sameTurnFollowups, ...later],
276
248
  targetSeq: event.seq,
277
249
  };
@@ -282,22 +254,10 @@ export function editPlan(operation: EditOperation, turns: readonly ClosedTurn[])
282
254
  const before = event.data.message.content[operation.blockIndex];
283
255
  if (!isTextualBlock(before))
284
256
  throw new SessionBranchError("所选助手消息块不是文本或思考。", "INVALID_BOUNDARY");
285
- const blockKind: EditableBlockKind =
286
- before.type === "reasoning" ? "assistant.reasoning" : "assistant.response";
287
257
  if (turn.user === undefined)
288
258
  throw new SessionBranchError("所选助手消息没有可重建的用户输入。", "INVALID_BOUNDARY");
289
259
  return {
290
260
  anchorSeq: turn.startSeq,
291
- version: pairVersionEffect(operation.sessionId, {
292
- operation: "edit",
293
- cascade: operation.cascade,
294
- targetTurn: turn.turn,
295
- targetEventSeq: event.seq,
296
- targetBlockIndex: operation.blockIndex,
297
- blockKind,
298
- before: before.text,
299
- after: operation.text,
300
- }),
301
261
  manualTurn: {
302
262
  turn: turn.turn,
303
263
  user: cloneUser(turn.user.data),
@@ -315,12 +275,6 @@ export function retryPlan(operation: RetryOperation, turns: readonly ClosedTurn[
315
275
  throw new SessionBranchError("所选回合没有可重放的用户输入。", "INVALID_BOUNDARY");
316
276
  return {
317
277
  anchorSeq: turn.startSeq,
318
- version: pairVersionEffect(operation.sessionId, {
319
- operation: "retry",
320
- cascade: operation.cascade,
321
- targetTurn: turn.turn,
322
- targetEventSeq: turn.user.seq,
323
- }),
324
278
  queuedUsers:
325
279
  operation.cascade === "preserve"
326
280
  ? downstreamUsers(turns, turnIndex)
@@ -343,12 +297,6 @@ export function rerollPlan(
343
297
  if (target === undefined) continue;
344
298
  return {
345
299
  anchorSeq: turn.startSeq,
346
- version: pairVersionEffect(operation.sessionId, {
347
- operation: "reroll",
348
- cascade: "truncate",
349
- targetTurn: turn.turn,
350
- targetEventSeq: target.seq,
351
- }),
352
300
  queuedUsers: turn.users.map((user) => cloneUser(user.data)),
353
301
  targetSeq: target.seq,
354
302
  };
package/src/shared.ts CHANGED
@@ -1,6 +1,5 @@
1
1
  import type { SessionId } from "@deepseek-ai/dsh-session";
2
- import type { BranchTimeline, CascadePolicy } from "@morlay/session-branch";
3
- import type { VersionOperation } from "@morlay/session-branch";
2
+ import type { CascadePolicy } from "@morlay/session-branch";
4
3
 
5
4
  export const SESSION_EDITOR_PATH = "/session-editor";
6
5
 
@@ -79,97 +78,3 @@ export interface RetryableTurn {
79
78
  time: number;
80
79
  }
81
80
 
82
- export interface VersionSummary {
83
- sessionId: string;
84
- parentSessionId?: string;
85
- effectId?: string;
86
- inverseSessionId?: string;
87
- createdAt: number;
88
- depth: number;
89
- current: boolean;
90
- onCurrentEffectPath: boolean;
91
- operation?: VersionOperation;
92
- cascade?: CascadePolicy;
93
- targetTurn?: number;
94
- blockKind?: EditableMessageBlock["kind"];
95
- before?: string;
96
- after?: string;
97
- }
98
-
99
- export interface SessionEditorTimeline {
100
- sessionId: string;
101
- messages: EditableMessageBlock[];
102
- retryableTurns: RetryableTurn[];
103
- versions: VersionSummary[];
104
-
105
- undoStack: string[];
106
-
107
- redoSessionIds: string[];
108
- }
109
-
110
- export function toTimelinePayload(
111
- sessionId: SessionId,
112
- timeline: BranchTimeline,
113
- messages: EditableMessageBlock[],
114
- retryableTurns: RetryableTurn[],
115
- ): SessionEditorTimeline {
116
- const currentPath = new Set<string>();
117
- for (const node of timeline.nodes) currentPath.add(String(node.sessionId));
118
- const versions: VersionSummary[] = timeline.nodes.map((node) => ({
119
- sessionId: String(node.sessionId),
120
- ...(node.parentSessionId === undefined
121
- ? {}
122
- : { parentSessionId: String(node.parentSessionId) }),
123
- ...(node.effect === undefined
124
- ? {}
125
- : {
126
- effectId: node.effect.id,
127
- inverseSessionId: String(node.inverseSessionId),
128
- operation: node.effect.operation,
129
- cascade: node.effect.cascade,
130
- targetTurn: node.effect.targetTurn,
131
- ...(node.effect.blockKind === undefined ? {} : { blockKind: node.effect.blockKind }),
132
- ...(node.effect.before === undefined ? {} : { before: node.effect.before }),
133
- ...(node.effect.after === undefined ? {} : { after: node.effect.after }),
134
- }),
135
- createdAt: node.createdAt,
136
- depth: depthOf(timeline, node.sessionId),
137
- current: String(node.sessionId) === String(sessionId),
138
- onCurrentEffectPath: currentPath.has(String(node.sessionId)),
139
- }));
140
- const versionsById = new Map(versions.map((version) => [version.sessionId, version]));
141
- const undoStack: string[] = [];
142
- let cursor = versionsById.get(String(sessionId));
143
- while (cursor?.inverseSessionId !== undefined) {
144
- if (undoStack.includes(cursor.inverseSessionId)) break;
145
- undoStack.push(cursor.inverseSessionId);
146
- cursor = versionsById.get(cursor.inverseSessionId);
147
- }
148
- const redoSessionIds = versions
149
- .filter((version) => version.inverseSessionId === String(sessionId))
150
- .map((version) => version.sessionId);
151
- return {
152
- sessionId: String(sessionId),
153
- messages,
154
- retryableTurns,
155
- versions,
156
- undoStack,
157
- redoSessionIds,
158
- };
159
- }
160
-
161
- function depthOf(
162
- timeline: BranchTimeline,
163
- sessionId: import("@deepseek-ai/dsh-session").SessionId,
164
- ): number {
165
- const byId = new Map(timeline.nodes.map((node) => [String(node.sessionId), node]));
166
- let depth = 0;
167
- let cursor = byId.get(String(sessionId));
168
- const seen = new Set<string>();
169
- while (cursor?.parentSessionId !== undefined && !seen.has(String(cursor.sessionId))) {
170
- seen.add(String(cursor.sessionId));
171
- depth += 1;
172
- cursor = byId.get(String(cursor.parentSessionId));
173
- }
174
- return depth;
175
- }
package/src/testing.ts CHANGED
@@ -9,7 +9,6 @@ import {
9
9
  type SessionHeader,
10
10
  } from "@deepseek-ai/dsh-session";
11
11
  import SessionProjectionRegistry from "@deepseek-ai/dsh-session-projection";
12
- import { type BranchTimeline } from "@morlay/session-branch";
13
12
  import SessionPersistenceSqlite from "@morlay/session-rdb";
14
13
  import { parseJsonlArtifact } from "@morlay/session-rdb/artifact";
15
14
  import { EmptySettings, meta, oneTurnLog } from "@morlay/session-rdb/testing";
@@ -17,7 +16,6 @@ import { SESSION_EDITOR_PATH } from "./shared.ts";
17
16
  import { SessionEditor } from "@morlay/ui-conversation-message-actions";
18
17
 
19
18
  export {
20
- BranchTimeline,
21
19
  SESSION_EDITOR_PATH,
22
20
  Session,
23
21
  SessionIdBrand,
package/src/types.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { SessionId } from "@deepseek-ai/dsh-session";
2
- import type { BranchTimeline, CascadePolicy } from "@morlay/session-branch";
2
+ import type { CascadePolicy } from "@morlay/session-branch";
3
3
 
4
4
  export interface EditOperation {
5
5
  action: "edit";
@@ -61,8 +61,6 @@ export interface SessionEditorResult {
61
61
  live?: boolean;
62
62
  }
63
63
 
64
- export type SessionEditorTimeline = BranchTimeline;
65
-
66
64
  export interface EditableMessageBlock {
67
65
  key: string;
68
66
 
@@ -1,55 +0,0 @@
1
- //#region src/shared.ts
2
- const SESSION_EDITOR_PATH = "/session-editor";
3
- function toTimelinePayload(sessionId, timeline, messages, retryableTurns) {
4
- const currentPath = /* @__PURE__ */ new Set();
5
- for (const node of timeline.nodes) currentPath.add(String(node.sessionId));
6
- const versions = timeline.nodes.map((node) => ({
7
- sessionId: String(node.sessionId),
8
- ...node.parentSessionId === void 0 ? {} : { parentSessionId: String(node.parentSessionId) },
9
- ...node.effect === void 0 ? {} : {
10
- effectId: node.effect.id,
11
- inverseSessionId: String(node.inverseSessionId),
12
- operation: node.effect.operation,
13
- cascade: node.effect.cascade,
14
- targetTurn: node.effect.targetTurn,
15
- ...node.effect.blockKind === void 0 ? {} : { blockKind: node.effect.blockKind },
16
- ...node.effect.before === void 0 ? {} : { before: node.effect.before },
17
- ...node.effect.after === void 0 ? {} : { after: node.effect.after }
18
- },
19
- createdAt: node.createdAt,
20
- depth: depthOf(timeline, node.sessionId),
21
- current: String(node.sessionId) === String(sessionId),
22
- onCurrentEffectPath: currentPath.has(String(node.sessionId))
23
- }));
24
- const versionsById = new Map(versions.map((version) => [version.sessionId, version]));
25
- const undoStack = [];
26
- let cursor = versionsById.get(String(sessionId));
27
- while (cursor?.inverseSessionId !== void 0) {
28
- if (undoStack.includes(cursor.inverseSessionId)) break;
29
- undoStack.push(cursor.inverseSessionId);
30
- cursor = versionsById.get(cursor.inverseSessionId);
31
- }
32
- const redoSessionIds = versions.filter((version) => version.inverseSessionId === String(sessionId)).map((version) => version.sessionId);
33
- return {
34
- sessionId: String(sessionId),
35
- messages,
36
- retryableTurns,
37
- versions,
38
- undoStack,
39
- redoSessionIds
40
- };
41
- }
42
- function depthOf(timeline, sessionId) {
43
- const byId = new Map(timeline.nodes.map((node) => [String(node.sessionId), node]));
44
- let depth = 0;
45
- let cursor = byId.get(String(sessionId));
46
- const seen = /* @__PURE__ */ new Set();
47
- while (cursor?.parentSessionId !== void 0 && !seen.has(String(cursor.sessionId))) {
48
- seen.add(String(cursor.sessionId));
49
- depth += 1;
50
- cursor = byId.get(String(cursor.parentSessionId));
51
- }
52
- return depth;
53
- }
54
- //#endregion
55
- export { toTimelinePayload as n, SESSION_EDITOR_PATH as t };