@deepseek-ai/dsh-message-feedback 0.1.2-rc.1 → 0.1.5-alpha.1
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.i18n.yaml +2 -2
- package/README.md +32 -91
- package/README.zh.md +32 -91
- package/lib/index.js +138 -231
- package/lib/typert.host.js +36 -14
- package/lib/typert.remote-client.js +3 -3
- package/lib/types/index.d.ts +28 -43
- package/lib/types/index.js +139 -194
- package/lib/types/types.d.ts +24 -2
- package/package.json +14 -18
- package/lib/types/spec.d.ts +0 -48
- package/lib/types/spec.js +0 -74
package/README.i18n.yaml
CHANGED
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
|
3
3
|
# after editing either side, bring the other along and re-record with:
|
|
4
4
|
# pnpm run verify-translation-pairing --write packages/feedback/message-feedback/README.md
|
|
5
|
-
README.md:
|
|
6
|
-
README.zh.md:
|
|
5
|
+
README.md: e1defa8d8fd6149f124267ffa0c382f4a82cf2ab
|
|
6
|
+
README.zh.md: d16f8f4416288e5373e3221e8f43a8b2d84e5f80
|
package/README.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: "
|
|
2
|
+
description: "Canonical Session-log ratings and notes for finalized assistant messages."
|
|
3
3
|
kind: "package-reference"
|
|
4
4
|
---
|
|
5
5
|
|
|
@@ -9,154 +9,95 @@ English | [中文](README.zh.md)
|
|
|
9
9
|
|
|
10
10
|
## Summary
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
This service records positive or negative ratings and optional verbatim notes for finalized assistant messages. The canonical Session log owns every creation, edit, and deletion; `list`, `put`, and `delete` expose current feedback without constructing or waking an Agent. Feedback is log-only and does not enter model history.
|
|
13
13
|
|
|
14
14
|
## Table of Contents
|
|
15
15
|
|
|
16
16
|
- [Use this package](#use-this-package)
|
|
17
17
|
- [Understand the implementation](#understand-the-implementation)
|
|
18
|
-
- [Further Exploration](#further-exploration)
|
|
19
18
|
- [Model Experience](#model-experience)
|
|
20
19
|
- [Known Limitations and Deferred Work](#known-limitations-and-deferred-work)
|
|
21
20
|
- [Dev Note](#dev-note)
|
|
22
21
|
|
|
23
|
-
-----
|
|
24
|
-
|
|
25
22
|
<a id="use-this-package"></a>
|
|
26
23
|
## Use this package
|
|
27
24
|
|
|
28
|
-
|
|
25
|
+
Mount `dsh-message-feedback` alongside `sessions` and `sessionPersistence`. It needs no storage-domain service. The Web bundle supplies the browser consumer and a note limit of 8192 bytes.
|
|
29
26
|
|
|
30
27
|
### Configuration
|
|
31
28
|
|
|
32
29
|
| Field | Default | Meaning |
|
|
33
30
|
|---|---|---|
|
|
34
|
-
| `maxNoteBytes` | required |
|
|
35
|
-
|
|
36
|
-
```yaml
|
|
37
|
-
- id: message-feedback
|
|
38
|
-
name: '@deepseek-ai/dsh-message-feedback'
|
|
39
|
-
config:
|
|
40
|
-
maxNoteBytes: 8192
|
|
41
|
-
```
|
|
31
|
+
| `maxNoteBytes` | required | Positive safe-integer maximum UTF-8 bytes in one optional note. |
|
|
42
32
|
|
|
43
|
-
A note must contain
|
|
33
|
+
A supplied note must contain a non-whitespace character and fit the configured byte limit. Blank notes return `note-blank`; oversized notes return `note-too-large`. Accepted text is preserved exactly, including surrounding whitespace. Omitting a note clears it. Note validation precedes Session lookup.
|
|
44
34
|
|
|
45
35
|
### Reading and changing feedback
|
|
46
36
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
| Operation | Request | Success | Rejected when |
|
|
37
|
+
| Operation | Request | Success | Business failures |
|
|
50
38
|
|---|---|---|---|
|
|
51
|
-
| `list` |
|
|
52
|
-
| `put` |
|
|
53
|
-
| `delete` |
|
|
54
|
-
|
|
55
|
-
Every change must be based on the version the service returned for that rating: a change based on an older version is rejected with `version-conflict`, and the reply carries the current rating so the caller can see what changed without another read. Deleting a rating that is already absent succeeds, and concurrent changes to different messages do not conflict. An omitted note clears an existing note.
|
|
56
|
-
|
|
57
|
-
### What you can rate
|
|
58
|
-
|
|
59
|
-
A rating attaches to one finalized assistant message: the message must exist and be an assistant message that was sent. User messages, empty assistant placeholders, and replaced messages are not valid targets and are rejected with `target-not-found`. Once recorded, the rating and note stay with that message and survive restarts; a fork of the session starts with no feedback.
|
|
39
|
+
| `list` | Session id | Current items in creation order | Session not found |
|
|
40
|
+
| `put` | Session, message, rating, optional note, expected version | Current item | Session or target not found, version conflict, invalid note |
|
|
41
|
+
| `delete` | Session, message, expected version | Item absent | Session not found, version conflict |
|
|
60
42
|
|
|
61
|
-
|
|
43
|
+
Create with `ifVersion: null`; edit or delete with the returned version. Stale mutations return `version-conflict` and the current item. Each material put mints a fresh token and preserves the original creation time. A matching no-op put returns the same item without appending an event. Deleting an absent item succeeds regardless of the supplied version, without appending an event. Recreating a deleted item starts a new creation time and ordering position.
|
|
62
44
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
-----
|
|
45
|
+
Targets must be non-empty assistant messages produced by append-origin events. User messages, empty assistant placeholders, and replacement-origin messages return `target-not-found`. Feedback survives restart; a fork starts without owned feedback even when its inherited prefix contains parent feedback.
|
|
66
46
|
|
|
67
47
|
<a id="understand-the-implementation"></a>
|
|
68
48
|
## Understand the implementation
|
|
69
49
|
|
|
70
|
-
|
|
71
|
-
<summary>Implementation internals — click to expand</summary>
|
|
72
|
-
|
|
73
|
-
### Design concept
|
|
74
|
-
|
|
75
|
-
The service keeps feedback outside the session log entirely: each session owns one sidecar row in a storage domain, so a rating can never be confused with conversation content, model history, or telemetry. The sidecar is only ever committed after the message it references is durable — the row extends the target log instead of preceding it. Every operation returns a business result that distinguishes a handled failure (missing session, invalid target, stale version, bad note) from an infrastructure failure, which rejects instead of being mislabeled.
|
|
76
|
-
|
|
77
|
-
### What a sidecar holds
|
|
78
|
-
|
|
79
|
-
One row per session binds the inspected session identity (`createdAt`, `cwd`) to its feedback items; the identity fences a reused session id, so a row from an earlier lifecycle is invisible and a fork starts with no feedback. Items are immutable values — a change writes a new version of the item, preserving its creation time — and the row schema rejects duplicate message ids and reused versions so lookup stays unambiguous. The exact row schema and validation live in [`src/spec.ts`](src/spec.ts).
|
|
50
|
+
### Canonical log and durability
|
|
80
51
|
|
|
81
|
-
|
|
52
|
+
`feedback/message-put` stores the owning Session id and complete item, including its version and timestamps. `feedback/message-delete` stores the owner and message id. Current state is derived from these events, ignoring other Session owners. Durable payloads are validated before use. No second feedback store or cache exists.
|
|
82
53
|
|
|
83
|
-
|
|
54
|
+
Live operations append through `Session.append` and await `sessions.flush`, then verify the captured log endpoint and Session header through a persistence read handle before reporting success. Cold mutations hold a persistence write handle across read, validation, comparison, append, flush, and close. Cold reads use a read handle. Neither path constructs a Session or appends lifecycle events.
|
|
84
55
|
|
|
85
|
-
|
|
56
|
+
A per-Session queue serializes operations within one service instance; the persistence write handle excludes competing cold writers. Disposal stops admission and drains admitted operations before releasing the service. Persistence failures reject instead of becoming business failures. A failed flush does not roll back an accepted event; callers can list and retry with its version. Successful no-op mutations also flush the current prefix.
|
|
86
57
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
### Failure modes
|
|
90
|
-
|
|
91
|
-
The service fails closed: disposal drains in-flight writes before closing the domain, a write submitted after disposal starts is rejected as a lifecycle failure, and invalid configuration or a read before domain initialization fails loudly.
|
|
58
|
+
Cold material mutations notify `feedback/committed` after flush with a borrowed read-only canonical prefix; observers must deep-clone it before transferring ownership. Observers finish before write ownership is released, must not await another feedback operation for that Session, and cannot reject an already committed mutation. Live consumers observe `session/event`.
|
|
92
59
|
|
|
93
60
|
### Source map
|
|
94
61
|
|
|
95
62
|
| File | Role |
|
|
96
63
|
|---|---|
|
|
97
|
-
| [`src/index.ts`](src/index.ts) |
|
|
98
|
-
| [`src/types.ts`](src/types.ts) |
|
|
99
|
-
| [`src/spec.ts`](src/spec.ts) | Storage-domain declaration: `message_feedback` domain, `sessions` table, row schemas |
|
|
100
|
-
| — | No runtime invariant companion is published; the private typed writer owns current row mutations, the domain schema validates rows on reopen, and no second authority exists. |
|
|
101
|
-
|
|
102
|
-
</details>
|
|
103
|
-
|
|
104
|
-
-----
|
|
105
|
-
|
|
106
|
-
<a id="further-exploration"></a>
|
|
107
|
-
## Further Exploration
|
|
108
|
-
|
|
109
|
-
Read these pages when the package-level contract is not enough. They move from the subsystem types and design boundary to the persistence primitives and the browser consumer that drives this service.
|
|
64
|
+
| [`src/index.ts`](src/index.ts) | Remote service, payload validation, event projection, and persistence ownership |
|
|
65
|
+
| [`src/types.ts`](src/types.ts) | Requests, results, and Session event declarations; types only |
|
|
110
66
|
|
|
111
|
-
|
|
112
|
-
- [Message-feedback sidecar decision](../../../.agents/notes/implemented/architecture/2026-08-10-message-feedback-sidecar.md) — the design boundary that keeps this sidecar out of Session-log content.
|
|
113
|
-
- [Session persistence subsystem](../../../docs/subsystems/persistence.md) — `inspect`, `readFrom`, and `flush` semantics behind the durability barrier.
|
|
114
|
-
- [dsh-client-ui-message-feedback](../../client/ui-message-feedback/README.md) — the browser consumer that drives the Host Remote contract.
|
|
115
|
-
- [Feedback package map](../README.md) — where per-message feedback sits next to the log-only capture command.
|
|
67
|
+
No runtime invariant companion is published: the service derives feedback directly from validated canonical events and owns no independently mutable projection.
|
|
116
68
|
|
|
117
|
-
|
|
69
|
+
See the [feedback subsystem](../../../docs/subsystems/feedback.md), [Session persistence](../../../docs/subsystems/persistence.md), and [browser consumer](../../client/ui-message-feedback/README.md) for their respective APIs.
|
|
118
70
|
|
|
119
71
|
<a id="model-experience"></a>
|
|
120
72
|
## Model Experience
|
|
121
73
|
|
|
122
|
-
###
|
|
74
|
+
### Message feedback
|
|
123
75
|
|
|
124
76
|
#### What the model sees
|
|
125
77
|
|
|
126
|
-
Nothing. `
|
|
78
|
+
Nothing. `feedback/message-put` and `feedback/message-delete` carry no surface placement, tool, prompt section, or model-facing context. Log export and delivery policies belong to their consumers.
|
|
127
79
|
|
|
128
80
|
#### Token effect
|
|
129
81
|
|
|
130
|
-
Zero.
|
|
82
|
+
Zero. Ratings, notes, and service results do not enter model requests.
|
|
131
83
|
|
|
132
84
|
#### KV Cache effect
|
|
133
85
|
|
|
134
|
-
Independent.
|
|
86
|
+
Independent. Feedback does not change the model request prefix.
|
|
135
87
|
|
|
136
88
|
## Known Limitations and Deferred Work
|
|
137
89
|
|
|
138
90
|
<a id="known-limitations-and-deferred-work"></a>
|
|
139
91
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
- **
|
|
144
|
-
- **
|
|
145
|
-
- **
|
|
146
|
-
- **
|
|
147
|
-
- **Trusted caller boundary** — `list`/`put`/`delete` carry no authenticated actor or audit identity. A deployment must expose the Host gateway only through its trusted or separately authenticated boundary until authorization and attribution are added.
|
|
148
|
-
- **Catalog and row bounds** — a cold request scans the complete Session snapshot catalog because persistence has no lookup-by-id metadata operation. `maxNoteBytes` bounds one note, but the item count and aggregate retained bytes of one Session row are not capped; an indexed metadata read and deployment-owned row bound remain deferred until a concrete consumer defines their policy.
|
|
92
|
+
- **Log-only authority:** existing `message_feedback` sidecar data is neither read nor migrated. Those files remain untouched, but their feedback is unavailable through this service.
|
|
93
|
+
- **Deletion retains history:** delete removes current feedback, not earlier ratings or notes from the append-only log; it is not a privacy-erasure operation.
|
|
94
|
+
- **Writer ownership:** another process holding a Session write handle causes cold mutations to reject. The service does not wake that owner or coordinate Remote calls across processes.
|
|
95
|
+
- **Trusted callers:** requests contain no authenticated actor or audit identity. Deployments must protect the Host gateway.
|
|
96
|
+
- **Telemetry export:** for all users and providers, including `deepseek-official`, the shipped OTel backend in `FEEDBACK_ONLY` releases the complete canonical prefix only after new explicit text feedback, rating/note edits, or withdrawal. The prefix includes context and verbatim notes; later records wait for the next feedback, and `DISABLED` prevents capture. Deployments own redaction; see the [OTel export policy](../../session/session-telemetry-otel/README.md).
|
|
97
|
+
- **Scan cost:** each `list`, `put`, or `delete` that reaches an existing Session scans its full event log to derive current feedback; cold operations also read the full log from persistence. Work grows with total Session history, not just the number of feedback items.
|
|
98
|
+
- **Retention:** `maxNoteBytes` limits one note, not aggregate log size or mutation count.
|
|
149
99
|
|
|
150
100
|
<a id="dev-note"></a>
|
|
151
101
|
### Dev Note
|
|
152
102
|
|
|
153
|
-
|
|
154
|
-
<summary>Working context for maintainers — click to expand</summary>
|
|
155
|
-
|
|
156
|
-
This Dev Note is working context for maintainers; it is explicitly non-authoritative. Shipped behavior, limits, and rationale live in the sections above, the package code, and the linked Agent Note.
|
|
157
|
-
|
|
158
|
-
- The browser controls and the client Remote mount live in `dsh-client-ui-message-feedback` and `dsh-api-remotes`; their open items belong to those packages' notes.
|
|
159
|
-
- The trusted-caller limitation is the open authorization direction: the Host gateway records no actor or audit identity, and any authentication layer must land at the deployment boundary before the service exposes per-user attribution.
|
|
160
|
-
- Note validation precedes Session lookup by design, so `note-blank` and `note-too-large` win over `session-not-found` for a missing Session; tests pin this order.
|
|
161
|
-
|
|
162
|
-
</details>
|
|
103
|
+
The [package tests](tests/message-feedback.spec.ts) cover current-state and durable-history semantics; the [Loader composition](tests/loader-composition.spec.ts) verifies live and cold JSONL operations across restart.
|
package/README.zh.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: "
|
|
2
|
+
description: "在权威 Session 日志中保存已完成 assistant 消息的评分与备注。"
|
|
3
3
|
kind: "package-reference"
|
|
4
4
|
---
|
|
5
5
|
|
|
@@ -9,154 +9,95 @@ kind: "package-reference"
|
|
|
9
9
|
|
|
10
10
|
## 概述
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
本服务为已完成的 assistant 消息记录好评、差评及可选的原样备注。每次创建、编辑和删除都由权威 Session 日志保存;`list`、`put` 和 `delete` 提供当前反馈,不会构造或唤醒 Agent。反馈仅写入日志,不进入模型历史。
|
|
13
13
|
|
|
14
14
|
## 目录
|
|
15
15
|
|
|
16
16
|
- [使用本包](#use-this-package)
|
|
17
17
|
- [理解实现](#understand-the-implementation)
|
|
18
|
-
- [进一步探索](#further-exploration)
|
|
19
18
|
- [模型体验](#model-experience)
|
|
20
19
|
- [已知限制与延期工作](#known-limitations-and-deferred-work)
|
|
21
20
|
- [开发备注](#dev-note)
|
|
22
21
|
|
|
23
|
-
-----
|
|
24
|
-
|
|
25
22
|
<a id="use-this-package"></a>
|
|
26
23
|
## 使用本包
|
|
27
24
|
|
|
28
|
-
|
|
25
|
+
将 `dsh-message-feedback` 与 `sessions`、`sessionPersistence` 一起挂载。它不需要 storage-domain 服务。Web 组合提供浏览器消费方,并将备注上限设为 8192 字节。
|
|
29
26
|
|
|
30
27
|
### 配置
|
|
31
28
|
|
|
32
29
|
| 字段 | 默认值 | 含义 |
|
|
33
30
|
|---|---|---|
|
|
34
|
-
| `maxNoteBytes` | 必填 |
|
|
35
|
-
|
|
36
|
-
```yaml
|
|
37
|
-
- id: message-feedback
|
|
38
|
-
name: '@deepseek-ai/dsh-message-feedback'
|
|
39
|
-
config:
|
|
40
|
-
maxNoteBytes: 8192
|
|
41
|
-
```
|
|
31
|
+
| `maxNoteBytes` | 必填 | 单条可选备注的 UTF-8 字节上限,必须为正安全整数。 |
|
|
42
32
|
|
|
43
|
-
|
|
33
|
+
提交的备注必须包含非空白字符,且不超过配置的字节上限。空白备注返回 `note-blank`;过长备注返回 `note-too-large`。通过校验的文本会完整保留,包括首尾空白。省略备注会清除它。备注校验先于 Session 查找。
|
|
44
34
|
|
|
45
35
|
### 读取与修改反馈
|
|
46
36
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
| 操作 | 请求 | 成功 | 拒绝时机 |
|
|
37
|
+
| 操作 | 请求 | 成功 | 业务失败 |
|
|
50
38
|
|---|---|---|---|
|
|
51
|
-
| `list` |
|
|
52
|
-
| `put` |
|
|
53
|
-
| `delete` |
|
|
54
|
-
|
|
55
|
-
每次修改都必须基于服务为该项评分返回的 version:基于更旧 version 的修改会以 `version-conflict` 拒绝,且回复携带当前评分,调用方无需再次读取即可看到变化。删除一条已经不存在的评分会成功;对不同消息的并发修改互不冲突。省略 `note` 会清除已有备注。
|
|
56
|
-
|
|
57
|
-
### 可以对什么评分
|
|
58
|
-
|
|
59
|
-
评分绑定一条已完成的 assistant 消息:消息必须存在,并且是发送过的 assistant 消息。用户消息、空的 assistant 占位与已被替换的消息都不是有效目标,会以 `target-not-found` 拒绝。评分与备注一旦记录就与该消息绑定并跨重启保留;会话的 fork 从没有反馈开始。
|
|
39
|
+
| `list` | Session id | 按创建顺序返回当前条目 | Session 不存在 |
|
|
40
|
+
| `put` | Session、消息、评分、可选备注、预期版本 | 当前条目 | Session 或目标不存在、版本冲突、备注无效 |
|
|
41
|
+
| `delete` | Session、消息、预期版本 | 条目不存在 | Session 不存在、版本冲突 |
|
|
60
42
|
|
|
61
|
-
|
|
43
|
+
创建时传入 `ifVersion: null`;编辑或删除时使用返回的版本。陈旧修改返回 `version-conflict` 及当前条目。每次实质 put 都生成新 token,并保留原始创建时间。匹配的无变化 put 返回相同条目,不追加事件。删除不存在的条目始终成功,不受所传版本影响,也不追加事件。重新创建已删除条目会产生新的创建时间和排序位置。
|
|
62
44
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
-----
|
|
45
|
+
目标必须是由 append 来源事件产生的非空 assistant 消息。用户消息、空 assistant 占位及 replacement 来源消息返回 `target-not-found`。反馈跨重启保留;fork 即使继承了包含父会话反馈的前缀,也从没有自有反馈开始。
|
|
66
46
|
|
|
67
47
|
<a id="understand-the-implementation"></a>
|
|
68
48
|
## 理解实现
|
|
69
49
|
|
|
70
|
-
|
|
71
|
-
<summary>实现细节——点击展开</summary>
|
|
72
|
-
|
|
73
|
-
### 设计理念
|
|
74
|
-
|
|
75
|
-
服务把反馈完全放在会话日志之外:每个会话在存储域中拥有一条伴随记录行,因此评分绝不会与对话内容、模型历史或遥测混淆。伴随记录只在所引用消息已持久之后提交——该行是目标日志的延伸,而不是先于它。每个操作都返回业务结果,把已处理的失败(会话缺失、目标无效、版本陈旧、备注不合格)与基础设施故障区分开,后者会 reject 而非被误标。
|
|
76
|
-
|
|
77
|
-
### 伴随记录里有什么
|
|
78
|
-
|
|
79
|
-
每个会话一行,把检查所得的会话身份(`createdAt`、`cwd`)与其反馈条目绑定;该身份隔离复用的会话 id,因此更早生命周期的行不可见,fork 也从无反馈开始。条目是不可变值——修改会写入条目新版本并保留其创建时间——行 schema 拒绝重复消息 id 与复用的版本,保证查找无歧义。精确的行 schema 与校验见 [`src/spec.ts`](src/spec.ts)。
|
|
50
|
+
### 权威日志与持久性
|
|
80
51
|
|
|
81
|
-
|
|
52
|
+
`feedback/message-put` 保存所属 Session id 及完整条目,包括版本和时间戳。`feedback/message-delete` 保存所属 Session 和消息 id。当前状态从这些事件推导,忽略属于其他 Session 的事件。持久化 payload 在使用前经过校验。不存在第二个反馈存储或缓存。
|
|
82
53
|
|
|
83
|
-
|
|
54
|
+
活跃会话通过 `Session.append` 追加,并等待 `sessions.flush`,然后通过持久化读 handle 核实捕获的日志末端与 Session header,才会报告成功。冷会话修改在读取、校验、比较、追加、flush 和关闭期间持有持久化写 handle。冷读取使用读 handle。两条路径都不会构造 Session 或追加生命周期事件。
|
|
84
55
|
|
|
85
|
-
|
|
56
|
+
每个 Session 的队列在同一服务实例内串行化操作;持久化写 handle 排除其他冷写入方。销毁时停止接收操作并排空已接收操作,然后释放服务。持久化故障会 reject,而非变成业务失败。flush 失败不会回滚已接受的事件;调用方可以读取并使用其版本重试。成功的无变化修改也会 flush 当前前缀。
|
|
86
57
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
### 故障模式
|
|
90
|
-
|
|
91
|
-
服务失败时保持封闭:disposal 先排空在途写入再关闭域,disposal 开始后提交的写入会以生命周期故障拒绝,无效配置或域初始化前的读取都会明确失败。
|
|
58
|
+
冷会话的实质修改在 flush 后通过 `feedback/committed` 通知借用的只读权威日志前缀;观察方在转移所有权前必须深拷贝。观察方在写入所有权释放前完成,不得等待同一 Session 的其他反馈操作,也不能使已提交的修改失败。活跃会话消费方观察 `session/event`。
|
|
92
59
|
|
|
93
60
|
### 源码地图
|
|
94
61
|
|
|
95
62
|
| 文件 | 职责 |
|
|
96
63
|
|---|---|
|
|
97
|
-
| [`src/index.ts`](src/index.ts) |
|
|
98
|
-
| [`src/types.ts`](src/types.ts) |
|
|
99
|
-
| [`src/spec.ts`](src/spec.ts) | storage-domain 声明:`message_feedback` 域、`sessions` 表、行 schema |
|
|
100
|
-
| — | 不发布运行时不变式伴生入口;域 schema 在重开时校验行。 |
|
|
101
|
-
|
|
102
|
-
</details>
|
|
103
|
-
|
|
104
|
-
-----
|
|
105
|
-
|
|
106
|
-
<a id="further-exploration"></a>
|
|
107
|
-
## 进一步探索
|
|
108
|
-
|
|
109
|
-
当包级约定不够用时阅读以下页面。它们从子系统类型与设计边界,逐步进入持久化原语与驱动此服务的浏览器消费方。
|
|
64
|
+
| [`src/index.ts`](src/index.ts) | Remote 服务、payload 校验、事件投影与持久化所有权 |
|
|
65
|
+
| [`src/types.ts`](src/types.ts) | 请求、结果和 Session 事件声明;仅类型 |
|
|
110
66
|
|
|
111
|
-
|
|
112
|
-
- [消息反馈伴随记录决策](../../../.agents/notes/implemented/architecture/2026-08-10-message-feedback-sidecar.zh.md)——让此伴随记录不进入会话日志内容的设计边界。
|
|
113
|
-
- [会话持久化子系统](../../../docs/subsystems/persistence.zh.md)——持久性屏障背后的 `inspect`、`readFrom` 与 `flush` 语义。
|
|
114
|
-
- [dsh-client-ui-message-feedback](../../client/ui-message-feedback/README.zh.md)——驱动 Host Remote 契约的浏览器消费方。
|
|
115
|
-
- [反馈包映射](../README.zh.md)——逐消息反馈与仅写入日志的采集命令并存的组。
|
|
67
|
+
不发布运行时不变式伴生入口:服务直接从校验后的权威事件推导反馈,不持有可独立修改的投影。
|
|
116
68
|
|
|
117
|
-
|
|
69
|
+
各自的 API 见[反馈子系统](../../../docs/subsystems/feedback.zh.md)、[Session 持久化](../../../docs/subsystems/persistence.zh.md)和[浏览器消费方](../../client/ui-message-feedback/README.zh.md)。
|
|
118
70
|
|
|
119
71
|
<a id="model-experience"></a>
|
|
120
72
|
## 模型体验
|
|
121
73
|
|
|
122
|
-
###
|
|
74
|
+
### 消息反馈
|
|
123
75
|
|
|
124
76
|
#### 模型看到什么
|
|
125
77
|
|
|
126
|
-
无。`
|
|
78
|
+
无。`feedback/message-put` 和 `feedback/message-delete` 不携带 surface 位置、工具、提示词段落或模型可见上下文。日志导出与投递策略由相应消费方负责。
|
|
127
79
|
|
|
128
80
|
#### Token 影响
|
|
129
81
|
|
|
130
|
-
|
|
82
|
+
为零。评分、备注和服务结果不进入模型请求。
|
|
131
83
|
|
|
132
84
|
#### KV Cache 影响
|
|
133
85
|
|
|
134
|
-
|
|
86
|
+
相互独立。反馈不改变模型请求前缀。
|
|
135
87
|
|
|
136
88
|
## 已知限制与延期工作
|
|
137
89
|
|
|
138
90
|
<a id="known-limitations-and-deferred-work"></a>
|
|
139
91
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
-
|
|
144
|
-
-
|
|
145
|
-
-
|
|
146
|
-
-
|
|
147
|
-
- **调用方边界受信任**——`list`/`put`/`delete` 不携带已认证的 actor 或审计身份。在加入授权与归属信息前,部署方必须只通过受信任或另行认证的边界暴露 Host gateway。
|
|
148
|
-
- **目录与行边界**——由于 persistence 没有按 id 读取元数据的操作,cold 请求会扫描完整的 Session snapshot 目录。`maxNoteBytes` 只限制单条备注,单个 Session 行的条目数和聚合保留字节尚无上限;按索引读取元数据和由部署决定的行边界,延后到具体消费方明确策略时处理。
|
|
92
|
+
- **仅日志具有权威性:**不读取或迁移现有 `message_feedback` 伴随数据。这些文件保持不变,但其反馈无法通过本服务访问。
|
|
93
|
+
- **删除保留历史:**delete 移除当前反馈,不会从只追加日志中清除更早的评分或备注;它不是隐私擦除操作。
|
|
94
|
+
- **写入所有权:**另一个进程持有 Session 写 handle 时,冷会话修改会 reject。服务不会唤醒该所有者,也不协调跨进程 Remote 调用。
|
|
95
|
+
- **受信任调用方:**请求不包含经过认证的 actor 或审计身份。部署方必须保护 Host gateway。
|
|
96
|
+
- **遥测导出:**对于所有用户和提供方,包括 `deepseek-official`,随附 OTel 后端在 `FEEDBACK_ONLY` 模式下仅在新的显式文本反馈、评分或备注编辑、撤回后释放完整权威日志前缀。前缀包含上下文和原样备注;后续记录等待下一次反馈,`DISABLED` 阻止捕获。部署方负责脱敏;见 [OTel 导出策略](../../session/session-telemetry-otel/README.zh.md)。
|
|
97
|
+
- **扫描成本:**每次访问已有 Session 的 `list`、`put` 或 `delete` 都会扫描完整事件日志来推导当前反馈;冷会话操作还会从持久化存储读取完整日志。工作量随 Session 历史总量增长,而不只是反馈条目数。
|
|
98
|
+
- **保留量:**`maxNoteBytes` 只限制单条备注,不限制日志总大小或修改次数。
|
|
149
99
|
|
|
150
100
|
<a id="dev-note"></a>
|
|
151
101
|
### 开发备注
|
|
152
102
|
|
|
153
|
-
|
|
154
|
-
<summary>维护者的工作上下文——点击展开</summary>
|
|
155
|
-
|
|
156
|
-
本开发备注是维护者的工作上下文,明确不具权威性。已交付的行为、限制与理由以上文、包代码与所链接的 Agent Note 为准。
|
|
157
|
-
|
|
158
|
-
- 浏览器控件与客户端 Remote 挂载位于 `dsh-client-ui-message-feedback` 与 `dsh-api-remotes`;它们的开放事项属于这些包的备注。
|
|
159
|
-
- 受信任调用方限制是开放的授权方向:Host gateway 不记录任何 actor 或审计身份,任何认证层都必须在部署边界落地,之后服务才能暴露按用户归属。
|
|
160
|
-
- 按设计,备注校验早于 Session 查找,因此对不存在的 Session,`note-blank` 与 `note-too-large` 优先于 `session-not-found`;测试固定了这一顺序。
|
|
161
|
-
|
|
162
|
-
</details>
|
|
103
|
+
[包测试](tests/message-feedback.spec.ts)覆盖当前状态与持久历史语义;[Loader 组合](tests/loader-composition.spec.ts)验证跨重启的活跃和冷 JSONL 操作。
|