@morlay/ui-conversation-message-actions 0.0.19-alpha.8 → 0.0.19
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 +5 -5
- package/dist/client.cjs +1 -1
- package/dist/testing.d.cts +6 -7
- package/dist/testing.d.mts +6 -7
- package/dist/testing.mjs +56 -24
- package/package.json +25 -30
- package/src/client/chat-node/MessageItem.styles.ts +2 -1
- package/cordis.patch.yml +0 -9
package/README.md
CHANGED
|
@@ -7,10 +7,10 @@
|
|
|
7
7
|
|
|
8
8
|
## 用法
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
`ctx.sessionPersistence
|
|
13
|
-
|
|
10
|
+
装配入口是聚合层 [`@morlay/better-session`](../../bundles/better-session/README.md):由它的 bundle patch 插入本包的行并注册
|
|
11
|
+
`ctx.sessionEditor`(本包自己没有 bundle patch,不作为独立 bundle 安装)。依赖 `ctx.sessionBranch` /
|
|
12
|
+
`ctx.sessionPersistence`(provider 由同一聚合层装配,如 `@morlay/session-rdb`)与 `ctx.sessions`;`agents` 可选,
|
|
13
|
+
缺失时重放退化为「已 durable 的就地版本」。
|
|
14
14
|
|
|
15
15
|
```ts
|
|
16
16
|
// host:装配后直接调服务
|
|
@@ -34,4 +34,4 @@ edit / retry / reroll 就地重写**同一会话**(session id 不变),只
|
|
|
34
34
|
- 决策:[`.agents/adrs/`](./.agents/adrs)(接管官方 `ui-conversation` 行、client bundle 单文件与 shadow 渲染、引用解析、
|
|
35
35
|
编辑入口门控…)
|
|
36
36
|
- 接缝、测试落点与未覆盖:[本包规范 how-to-verify](./.agents/standards/how-to-verify.md)
|
|
37
|
-
- 整体设计:[设计 20260917
|
|
37
|
+
- 整体设计:[设计 20260917-会话编辑闭环装配](../../bundles/better-session/.agents/designs/20260917-会话编辑闭环装配.md)
|
package/dist/client.cjs
CHANGED
|
@@ -470,7 +470,7 @@ window.__ModuleLoader__.load({
|
|
|
470
470
|
},
|
|
471
471
|
"&:hover": { color: "var(--dsw-alias-label-secondary)" },
|
|
472
472
|
"&:focus-visible": {
|
|
473
|
-
outline: "1.5px solid var(--dsw-alias-
|
|
473
|
+
outline: "1.5px solid var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary))",
|
|
474
474
|
outlineOffset: "2px"
|
|
475
475
|
}
|
|
476
476
|
},
|
package/dist/testing.d.cts
CHANGED
|
@@ -2855,16 +2855,15 @@ declare class WorkspaceRegistry extends Service {
|
|
|
2855
2855
|
* Initialize the default Workspace only while both the registry and Session
|
|
2856
2856
|
* history are empty. Repeated requests reuse its durable identity; deleting
|
|
2857
2857
|
* that registration permanently disables automatic creation.
|
|
2858
|
-
* @param resolveDirectory - resolve the absolute directory
|
|
2859
|
-
*
|
|
2860
|
-
*
|
|
2858
|
+
* @param resolveDirectory - resolve the absolute directory; called only for
|
|
2859
|
+
* eligible creation, inside the registry mutation queue. Missing directories
|
|
2860
|
+
* are created recursively before registration, and the initial title is the
|
|
2861
|
+
* requested directory's own final segment — not the canonical one, so a
|
|
2862
|
+
* symlink at that path does not retitle the Workspace after its target.
|
|
2861
2863
|
* After resolution, caller cancellation does not roll back creation or registration.
|
|
2862
2864
|
* @returns the initialized Workspace, or undefined when automatic creation is ineligible.
|
|
2863
2865
|
*/
|
|
2864
|
-
initializeDefault(resolveDirectory: () => Promise<
|
|
2865
|
-
path: string;
|
|
2866
|
-
title: string;
|
|
2867
|
-
}>): Promise<Workspace | undefined>;
|
|
2866
|
+
initializeDefault(resolveDirectory: () => Promise<string>): Promise<Workspace | undefined>;
|
|
2868
2867
|
/**
|
|
2869
2868
|
* Look up a workspace by id.
|
|
2870
2869
|
* @param id - Workspace id.
|
package/dist/testing.d.mts
CHANGED
|
@@ -2855,16 +2855,15 @@ declare class WorkspaceRegistry extends Service {
|
|
|
2855
2855
|
* Initialize the default Workspace only while both the registry and Session
|
|
2856
2856
|
* history are empty. Repeated requests reuse its durable identity; deleting
|
|
2857
2857
|
* that registration permanently disables automatic creation.
|
|
2858
|
-
* @param resolveDirectory - resolve the absolute directory
|
|
2859
|
-
*
|
|
2860
|
-
*
|
|
2858
|
+
* @param resolveDirectory - resolve the absolute directory; called only for
|
|
2859
|
+
* eligible creation, inside the registry mutation queue. Missing directories
|
|
2860
|
+
* are created recursively before registration, and the initial title is the
|
|
2861
|
+
* requested directory's own final segment — not the canonical one, so a
|
|
2862
|
+
* symlink at that path does not retitle the Workspace after its target.
|
|
2861
2863
|
* After resolution, caller cancellation does not roll back creation or registration.
|
|
2862
2864
|
* @returns the initialized Workspace, or undefined when automatic creation is ineligible.
|
|
2863
2865
|
*/
|
|
2864
|
-
initializeDefault(resolveDirectory: () => Promise<
|
|
2865
|
-
path: string;
|
|
2866
|
-
title: string;
|
|
2867
|
-
}>): Promise<Workspace | undefined>;
|
|
2866
|
+
initializeDefault(resolveDirectory: () => Promise<string>): Promise<Workspace | undefined>;
|
|
2868
2867
|
/**
|
|
2869
2868
|
* Look up a workspace by id.
|
|
2870
2869
|
* @param id - Workspace id.
|
package/dist/testing.mjs
CHANGED
|
@@ -35340,6 +35340,7 @@ var SessionObservationReader = class {
|
|
|
35340
35340
|
* @param sessionId - logical Session identity.
|
|
35341
35341
|
* @param options - cancellation and all-or-none projection computation for this read.
|
|
35342
35342
|
* @returns one exact immutable observation.
|
|
35343
|
+
* @throws {@link SessionQueryError} with code `SESSION_QUERY_CORRUPT_SESSION` when live or prepared projection computation fails.
|
|
35343
35344
|
*/
|
|
35344
35345
|
async read(sessionId, options = {}) {
|
|
35345
35346
|
const { signal, projectionMode = "all" } = options;
|
|
@@ -35471,7 +35472,12 @@ var SessionObservationReader = class {
|
|
|
35471
35472
|
live(session, projectionMode) {
|
|
35472
35473
|
const seq = session.seq;
|
|
35473
35474
|
let materialized;
|
|
35474
|
-
|
|
35475
|
+
let projections;
|
|
35476
|
+
try {
|
|
35477
|
+
projections = projectionMode === "none" ? void 0 : this.ctx.get("sessionProjections")?.snapshot(session);
|
|
35478
|
+
} catch (error) {
|
|
35479
|
+
throw new SessionQueryError(`failed to project session "${session.id}": ${errorMessage(error)}`, "SESSION_QUERY_CORRUPT_SESSION", { cause: error });
|
|
35480
|
+
}
|
|
35475
35481
|
const lease = () => {
|
|
35476
35482
|
let disposed = false;
|
|
35477
35483
|
return {
|
|
@@ -36884,38 +36890,62 @@ var RdbSessionHandle = class RdbSessionHandle {
|
|
|
36884
36890
|
}
|
|
36885
36891
|
static LIVE_WRITE_BATCH_MAX_DELAY_MS = 200;
|
|
36886
36892
|
};
|
|
36893
|
+
/**
|
|
36894
|
+
* 本地化说明:`description()` 的类型签名只声明 `string`,而 meta 本身接受 `Dict<string>`
|
|
36895
|
+
* (`vendor/schemastery/src/index.ts` 的 `mergeDesc` 就是按字典合并的),所以这里只做一次类型放行。
|
|
36896
|
+
*/
|
|
36897
|
+
const localized = (text) => text;
|
|
36898
|
+
/** 投影 checkpoint 的写回节流:两个分支共用。 */
|
|
36899
|
+
const projectionCacheSchema = Schema.object({
|
|
36900
|
+
writeEveryEvents: Schema.natural().min(1).default(DEFAULT_PROJECTION_WRITE_EVERY_EVENTS).description(localized({
|
|
36901
|
+
zh: "每累计这么多事件写回一次投影 checkpoint。",
|
|
36902
|
+
en: "Write the projection checkpoint back after this many events."
|
|
36903
|
+
})),
|
|
36904
|
+
writeIntervalMs: Schema.natural().min(1).default(DEFAULT_PROJECTION_WRITE_INTERVAL_MS).description(localized({
|
|
36905
|
+
zh: "距离上次写回超过这个间隔(毫秒)时也写一次。",
|
|
36906
|
+
en: "Also write back when this many ms passed since the last one."
|
|
36907
|
+
}))
|
|
36908
|
+
}).default({
|
|
36909
|
+
writeEveryEvents: DEFAULT_PROJECTION_WRITE_EVERY_EVENTS,
|
|
36910
|
+
writeIntervalMs: DEFAULT_PROJECTION_WRITE_INTERVAL_MS
|
|
36911
|
+
});
|
|
36887
36912
|
var SessionPersistenceRdb = class extends SessionPersistence {
|
|
36888
|
-
config;
|
|
36889
36913
|
static inject = ["sessions"];
|
|
36890
36914
|
static Config = Schema.union([Schema.object({
|
|
36891
36915
|
type: Schema.const("sqlite"),
|
|
36892
|
-
path: Schema.string().required()
|
|
36916
|
+
path: Schema.string().required().description(localized({
|
|
36917
|
+
zh: "SQLite 数据库文件路径;`:memory:` 是内存库(进程结束即丢)。",
|
|
36918
|
+
en: "SQLite database file path; `:memory:` keeps it in memory and loses it with the process."
|
|
36919
|
+
})),
|
|
36893
36920
|
journalMode: Schema.union([
|
|
36894
36921
|
"wal",
|
|
36895
36922
|
"delete",
|
|
36896
36923
|
"truncate",
|
|
36897
36924
|
"persist"
|
|
36898
|
-
]).default("wal")
|
|
36899
|
-
|
|
36900
|
-
|
|
36901
|
-
|
|
36902
|
-
|
|
36903
|
-
|
|
36904
|
-
|
|
36905
|
-
|
|
36906
|
-
|
|
36925
|
+
]).default("wal").description(localized({
|
|
36926
|
+
zh: "SQLite 日志模式;默认 wal(并发读最好)。",
|
|
36927
|
+
en: "SQLite journal mode; `wal` by default (best concurrent reads)."
|
|
36928
|
+
})),
|
|
36929
|
+
busyTimeout: Schema.number().step(1).min(0).default(DEFAULT_BUSY_TIMEOUT_MS).description(localized({
|
|
36930
|
+
zh: "写锁冲突时的忙等超时(毫秒)。",
|
|
36931
|
+
en: "Busy timeout in ms while a write lock is contended."
|
|
36932
|
+
})),
|
|
36933
|
+
projectionCache: projectionCacheSchema
|
|
36907
36934
|
}), Schema.object({
|
|
36908
36935
|
type: Schema.const("postgres"),
|
|
36909
|
-
connectionString: Schema.string().required()
|
|
36910
|
-
|
|
36911
|
-
|
|
36912
|
-
|
|
36913
|
-
|
|
36914
|
-
|
|
36915
|
-
|
|
36916
|
-
|
|
36917
|
-
|
|
36918
|
-
})])
|
|
36936
|
+
connectionString: Schema.string().required().description(localized({
|
|
36937
|
+
zh: "PostgreSQL 连接串(含库名与凭证)。",
|
|
36938
|
+
en: "PostgreSQL connection string (database and credentials)."
|
|
36939
|
+
})),
|
|
36940
|
+
schema: Schema.string().default("public").description(localized({
|
|
36941
|
+
zh: "库内的 schema 名;默认 public。",
|
|
36942
|
+
en: "Schema name inside the database; `public` by default."
|
|
36943
|
+
})),
|
|
36944
|
+
projectionCache: projectionCacheSchema
|
|
36945
|
+
})]).description(localized({
|
|
36946
|
+
zh: "会话持久化后端:改这里的连接参数会在这一行重挂时生效(Loader 会重装被改的行)。",
|
|
36947
|
+
en: "Session persistence backend: edits apply when this row is remounted (the Loader re-installs changed rows)."
|
|
36948
|
+
})).volatile();
|
|
36919
36949
|
name = "session-rdb";
|
|
36920
36950
|
tracker = new RdbBackendTracker(this.name);
|
|
36921
36951
|
backend;
|
|
@@ -36925,10 +36955,12 @@ var SessionPersistenceRdb = class extends SessionPersistence {
|
|
|
36925
36955
|
reuseEventIds = /* @__PURE__ */ new Map();
|
|
36926
36956
|
liveBuffers = /* @__PURE__ */ new Map();
|
|
36927
36957
|
liveReady = /* @__PURE__ */ new Map();
|
|
36958
|
+
/** 本次装配用的配置快照(整段 Config 是 volatile,重挂会给新的)。 */
|
|
36959
|
+
config;
|
|
36928
36960
|
constructor(ctx, config, injectedBackend) {
|
|
36929
36961
|
super(ctx);
|
|
36930
|
-
this.config = config;
|
|
36931
|
-
this.backend = injectedBackend ?? createBackend(config);
|
|
36962
|
+
this.config = config.get();
|
|
36963
|
+
this.backend = injectedBackend ?? createBackend(this.config);
|
|
36932
36964
|
this.ready = this.init();
|
|
36933
36965
|
this.installLiveRouting(ctx);
|
|
36934
36966
|
new SessionBranchRdb(this.ctx);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@morlay/ui-conversation-message-actions",
|
|
3
|
-
"version": "0.0.19
|
|
3
|
+
"version": "0.0.19",
|
|
4
4
|
"description": "Rewind / retry / recall / fork orchestration (host) plus the browser half — replaces the conversation.chat.node user / steering rendering and overrides the conversation.composer.dock stats row.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"conversation-chat-node",
|
|
@@ -22,17 +22,15 @@
|
|
|
22
22
|
"locale/*.json",
|
|
23
23
|
"dist",
|
|
24
24
|
"src",
|
|
25
|
-
"cordis.patch.yml",
|
|
26
25
|
"!**/__tests__"
|
|
27
26
|
],
|
|
28
27
|
"type": "module",
|
|
29
28
|
"exports": {
|
|
30
29
|
".": "./dist/index.mjs",
|
|
31
|
-
"./invariant": "./dist/invariant.mjs",
|
|
32
30
|
"./plan": "./dist/plan.mjs",
|
|
33
31
|
"./testing": "./dist/testing.mjs",
|
|
32
|
+
"./invariant": "./dist/invariant.mjs",
|
|
34
33
|
"./package.json": "./package.json",
|
|
35
|
-
"./cordis.patch.yml": "./cordis.patch.yml",
|
|
36
34
|
"./client": {
|
|
37
35
|
"types": "./dist/client.d.cts",
|
|
38
36
|
"default": "./dist/client.cjs"
|
|
@@ -40,42 +38,39 @@
|
|
|
40
38
|
"./locale/*.json": "./locale/*.json"
|
|
41
39
|
},
|
|
42
40
|
"dependencies": {
|
|
43
|
-
"@morlay/session-branch": "0.0.10
|
|
41
|
+
"@morlay/session-branch": "0.0.10"
|
|
44
42
|
},
|
|
45
43
|
"devDependencies": {
|
|
46
|
-
"@deepseek-ai/dsh-session-stats": "0.1.7-rc.
|
|
47
|
-
"@morlay/dsh-client-ui-primitives": "0.0.2
|
|
48
|
-
"@morlay/session-rdb": "0.0.21
|
|
44
|
+
"@deepseek-ai/dsh-session-stats": "0.1.7-rc.2",
|
|
45
|
+
"@morlay/dsh-client-ui-primitives": "0.0.2",
|
|
46
|
+
"@morlay/session-rdb": "0.0.21",
|
|
49
47
|
"@types/react": "~18.3.1",
|
|
50
48
|
"@types/react-dom": "~18.3.0",
|
|
51
49
|
"react": "^18.2.0",
|
|
52
50
|
"react-dom": "^18.2.0"
|
|
53
51
|
},
|
|
54
52
|
"peerDependencies": {
|
|
55
|
-
"@deepseek-ai/cordis": "4.0.4",
|
|
56
|
-
"@deepseek-ai/dsh-api-session-controller": "0.1.7-rc.
|
|
57
|
-
"@deepseek-ai/dsh-attachment": "0.1.7-rc.
|
|
58
|
-
"@deepseek-ai/dsh-client-connection": "0.1.7-rc.
|
|
59
|
-
"@deepseek-ai/dsh-client-store": "0.1.7-rc.
|
|
60
|
-
"@deepseek-ai/dsh-client-ui-attachment": "0.1.7-rc.
|
|
61
|
-
"@deepseek-ai/dsh-client-ui-chat": "0.1.7-rc.
|
|
62
|
-
"@deepseek-ai/dsh-client-ui-primitives": "0.1.7-rc.
|
|
63
|
-
"@deepseek-ai/dsh-client-ui-renderer": "0.1.7-rc.
|
|
64
|
-
"@deepseek-ai/dsh-client-ui-slots": "0.1.7-rc.
|
|
65
|
-
"@deepseek-ai/dsh-client-ui-workspace": "0.1.7-rc.
|
|
66
|
-
"@deepseek-ai/dsh-invariants": "0.1.7-rc.
|
|
67
|
-
"@deepseek-ai/dsh-llm": "0.1.7-rc.
|
|
68
|
-
"@deepseek-ai/dsh-session": "0.1.7-rc.
|
|
69
|
-
"@deepseek-ai/dsh-session-persistence": "0.1.7-rc.
|
|
70
|
-
"@deepseek-ai/dsh-session-projection": "0.1.7-rc.
|
|
71
|
-
"@deepseek-ai/dsh-token-meter": "0.1.7-rc.
|
|
72
|
-
"@morlay/dsh-client-ui-conversation": "0.0.2
|
|
73
|
-
"@morlay/dsh-client-ui-primitives": "0.0.2
|
|
53
|
+
"@deepseek-ai/cordis": "^4.0.4",
|
|
54
|
+
"@deepseek-ai/dsh-api-session-controller": "^0.1.7-rc.2",
|
|
55
|
+
"@deepseek-ai/dsh-attachment": "^0.1.7-rc.2",
|
|
56
|
+
"@deepseek-ai/dsh-client-connection": "^0.1.7-rc.2",
|
|
57
|
+
"@deepseek-ai/dsh-client-store": "^0.1.7-rc.2",
|
|
58
|
+
"@deepseek-ai/dsh-client-ui-attachment": "^0.1.7-rc.2",
|
|
59
|
+
"@deepseek-ai/dsh-client-ui-chat": "^0.1.7-rc.2",
|
|
60
|
+
"@deepseek-ai/dsh-client-ui-primitives": "^0.1.7-rc.2",
|
|
61
|
+
"@deepseek-ai/dsh-client-ui-renderer": "^0.1.7-rc.2",
|
|
62
|
+
"@deepseek-ai/dsh-client-ui-slots": "^0.1.7-rc.2",
|
|
63
|
+
"@deepseek-ai/dsh-client-ui-workspace": "^0.1.7-rc.2",
|
|
64
|
+
"@deepseek-ai/dsh-invariants": "^0.1.7-rc.2",
|
|
65
|
+
"@deepseek-ai/dsh-llm": "^0.1.7-rc.2",
|
|
66
|
+
"@deepseek-ai/dsh-session": "^0.1.7-rc.2",
|
|
67
|
+
"@deepseek-ai/dsh-session-persistence": "^0.1.7-rc.2",
|
|
68
|
+
"@deepseek-ai/dsh-session-projection": "^0.1.7-rc.2",
|
|
69
|
+
"@deepseek-ai/dsh-token-meter": "^0.1.7-rc.2",
|
|
70
|
+
"@morlay/dsh-client-ui-conversation": "0.0.2",
|
|
71
|
+
"@morlay/dsh-client-ui-primitives": "0.0.2"
|
|
74
72
|
},
|
|
75
73
|
"dsh": {
|
|
76
|
-
"bundle": {
|
|
77
|
-
"patch": "./cordis.patch.yml"
|
|
78
|
-
},
|
|
79
74
|
"client": {
|
|
80
75
|
"platform": "web",
|
|
81
76
|
"inject": [
|
|
@@ -164,7 +164,8 @@ export const styles = {
|
|
|
164
164
|
color: "var(--dsw-alias-label-secondary)",
|
|
165
165
|
},
|
|
166
166
|
"&:focus-visible": {
|
|
167
|
-
|
|
167
|
+
// 上游 ui-chat 的 MessageItem 这轮把焦点环改成读官方焦点变量(`focus.css` 口径)。
|
|
168
|
+
outline: "1.5px solid var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary))",
|
|
168
169
|
outlineOffset: "2px",
|
|
169
170
|
},
|
|
170
171
|
},
|
package/cordis.patch.yml
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
# @morlay/ui-conversation-message-actions bundle patch.
|
|
2
|
-
#
|
|
3
|
-
# 在 profile 的 dsh.profile.bundles 中列出本包后,本 patch 插入编排层插件行,
|
|
4
|
-
# 注册 ctx.sessionEditor。依赖 ctx.sessionBranch(由 provider 实现插件如
|
|
5
|
-
# @morlay/session-rdb 提供),请确保其在 bundles 中排在前面。
|
|
6
|
-
|
|
7
|
-
- insert:
|
|
8
|
-
- id: ui-conversation-message-actions
|
|
9
|
-
name: "@morlay/ui-conversation-message-actions"
|