@deepseek-ai/dsh-session-telemetry-otel 0.1.2-alpha.5 → 0.1.3-alpha.2
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 +15 -12
- package/README.zh.md +15 -12
- package/lib/index.js +37 -33
- package/lib/types/index.d.ts +8 -11
- package/package.json +22 -19
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/session/session-telemetry-otel/README.md
|
|
5
|
-
README.md:
|
|
6
|
-
README.zh.md:
|
|
5
|
+
README.md: 35dc351bd56fdce396eb4c89c321008eb14796ce
|
|
6
|
+
README.zh.md: a771a06b0e2dab39a2b1e9460a99e8c4c2828fb3
|
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@ English | [中文](README.zh.md)
|
|
|
9
9
|
|
|
10
10
|
## Summary
|
|
11
11
|
|
|
12
|
-
`dsh-session-telemetry-otel`
|
|
12
|
+
`dsh-session-telemetry-otel` exports session records through the OTel JS SDK only after new explicit feedback, for all users and providers, including `deepseek-official`. `FEEDBACK_ONLY` releases the canonical prefix through that feedback, including context; later records wait for the next explicit feedback. `DISABLED` constructs no transport. SDK batching can finish an authorized upload without another user interaction or model call. Deployments own their redaction rules.
|
|
13
13
|
|
|
14
14
|
## Table of Contents
|
|
15
15
|
|
|
@@ -31,11 +31,10 @@ Mount this plugin when a deployment should export session records through OpenTe
|
|
|
31
31
|
|
|
32
32
|
| `mode` | Behavior |
|
|
33
33
|
|---|---|
|
|
34
|
-
| `
|
|
35
|
-
| `
|
|
36
|
-
| `DISABLED` | Default. No coordinator, provider, processor, or exporter is constructed; no telemetry record leaves the process, and a `feedback/record` logs that nothing will be shared |
|
|
34
|
+
| `FEEDBACK_ONLY` | Default. Text feedback, rating creation/edit, note edit, and withdrawal release the unhanded prefix through that canonical feedback event; later records wait |
|
|
35
|
+
| `DISABLED` | No coordinator, provider, processor, or exporter is constructed; no telemetry record leaves the process. Live feedback warns locally; cold mutations stay silent |
|
|
37
36
|
|
|
38
|
-
Programmatic TypeScript configuration uses the exported `SessionTelemetryMode` enum; raw string literals are not assignable.
|
|
37
|
+
Programmatic TypeScript configuration uses the exported `SessionTelemetryMode` enum; raw string literals are not assignable. `FULL` is rejected, not an alias. The [`sharing` property](../session-telemetry/README.md#the-sharing-disclosure) reports `feedback-only` or `disabled`, not a delivery receipt. The `/feedback` acknowledgement confirms recording only.
|
|
39
38
|
|
|
40
39
|
### Minimal configuration
|
|
41
40
|
|
|
@@ -45,7 +44,7 @@ Uploading modes require an exporter URL and accept the SDK option blocks verbati
|
|
|
45
44
|
- id: sessionTelemetry-otel
|
|
46
45
|
name: '@deepseek-ai/dsh-session-telemetry-otel'
|
|
47
46
|
config:
|
|
48
|
-
mode:
|
|
47
|
+
mode: FEEDBACK_ONLY # optional; defaults to FEEDBACK_ONLY
|
|
49
48
|
shutdownTimeoutMillis: 3000 # optional; defaults to 3000
|
|
50
49
|
exporter: # passed verbatim to the SDK's OTLP/HTTP log exporter
|
|
51
50
|
url: https://collector.example.com/v1/logs
|
|
@@ -56,12 +55,14 @@ Uploading modes require an exporter URL and accept the SDK option blocks verbati
|
|
|
56
55
|
|
|
57
56
|
| Field | Default | Meaning |
|
|
58
57
|
|---|---|---|
|
|
59
|
-
| `mode` | `
|
|
58
|
+
| `mode` | `FEEDBACK_ONLY` | Sharing policy: `FEEDBACK_ONLY` or `DISABLED` |
|
|
60
59
|
| `exporter.url` | required in uploading modes | Full OTLP logs endpoint; must parse as `http(s)` |
|
|
61
60
|
| `exporter`, `processor` | — | Passed verbatim to the SDK exporter and batch processor |
|
|
62
61
|
| `shutdownTimeoutMillis` | `3,000` | Outer deadline for the SDK's complete shutdown sequence |
|
|
63
62
|
|
|
64
|
-
|
|
63
|
+
Direct `ctx.sessionTelemetry.emit()` calls are no-ops in every mode and cannot bypass feedback authorization. Inherited parent feedback does not authorize a child export: the child needs new feedback of its own. Its authorized prefix then includes inherited context.
|
|
64
|
+
|
|
65
|
+
Model requests, request headers, Session creation or adoption, restoration, and plugin mount or HMR do not authorize capture. Stored feedback alone triggers nothing. SDK scheduled flush and shutdown may finish batches authorized earlier, but never capture new records.
|
|
65
66
|
|
|
66
67
|
### What leaves the machine
|
|
67
68
|
|
|
@@ -83,7 +84,7 @@ This section explains the backend's composition; the observable behavior is full
|
|
|
83
84
|
|
|
84
85
|
### Design concept
|
|
85
86
|
|
|
86
|
-
The backend is a thin adapter over the OTel JS SDK: it owns
|
|
87
|
+
The backend is a thin adapter over the OTel JS SDK: it owns feedback authorization, resource identity, and an outer shutdown deadline. Canonical ledger records use the `@deepseek-ai/dsh-session-telemetry-otel` instrumentation scope; this backend captures no operational records. Resource identity carries `service.name`/`service.version` from `dsh-llm`'s `APP_IDENTITY` plus the anonymous `user.id` (from `$DSH_HOME/.anonymous-user-id`), once per export batch rather than per record.
|
|
87
88
|
|
|
88
89
|
### Source map
|
|
89
90
|
|
|
@@ -93,11 +94,11 @@ The backend is a thin adapter over the OTel JS SDK: it owns capture mode, resour
|
|
|
93
94
|
|
|
94
95
|
### Capture wiring
|
|
95
96
|
|
|
96
|
-
|
|
97
|
+
The backend uses on-demand capture with stored history included. Only new own `feedback/record`, `feedback/message-put`, or `feedback/message-delete` events trigger live capture, bounded by that event. A cold `feedback/committed` notification supplies its committed canonical snapshot without publishing a live Session or Agent. Same-object handoff cursors suppress repeated capture. The backend implements no `flush()`; the SDK owns batching and shutdown drain.
|
|
97
98
|
|
|
98
99
|
### Field mapping
|
|
99
100
|
|
|
100
|
-
Each
|
|
101
|
+
Each telemetry record maps to one SDK log record with captured timestamp, severity, body, and attributes. Feedback authorizes the complete unhanded prefix, not only the feedback payload.
|
|
101
102
|
|
|
102
103
|
</details>
|
|
103
104
|
|
|
@@ -133,7 +134,9 @@ These limits define where SDK behavior governs and where export guarantees end.
|
|
|
133
134
|
|
|
134
135
|
- **Upstream experimental tree** — `@opentelemetry/sdk-logs` is published from the upstream experimental tree; SDK API churn lands here and only here, while the seam contract does not move.
|
|
135
136
|
- **Live-collector behavior belongs to the SDK exporter** — authentication, TLS, throttling, and other real OTLP deployment behavior follow the upstream SDK rather than a package-owned compatibility layer.
|
|
136
|
-
- **
|
|
137
|
+
- **Best-effort handoff** — new cold snapshots and a new feedback submission after restart can repeat prefixes; receivers deduplicate by Session id, format version, and event seq. There is no durable outbox, delivery watermark, automatic retry promise, or collector-acceptance guarantee. OTel and the opt-in DeepSeek API path can overlap. Withdrawal exports a deletion event, not remote erasure.
|
|
138
|
+
|
|
139
|
+
- **Backend availability** — feedback submitted while this plugin is disabled or unloaded is recorded locally but not automatically replayed when it returns. Capture requires the subscriber to remain mounted until it observes the submission; unloading during a pending cold write can miss its post-flush notification.
|
|
137
140
|
|
|
138
141
|
<a id="dev-note"></a>
|
|
139
142
|
### Dev Note
|
package/README.zh.md
CHANGED
|
@@ -9,7 +9,7 @@ kind: "package-reference"
|
|
|
9
9
|
|
|
10
10
|
## 概述
|
|
11
11
|
|
|
12
|
-
`dsh-session-telemetry-otel`
|
|
12
|
+
`dsh-session-telemetry-otel` 仅在新的显式反馈后通过 OTel JS SDK 导出会话记录,适用于所有用户和提供方,包括 `deepseek-official`。`FEEDBACK_ONLY` 释放截至该反馈的权威日志前缀,包含上下文;后续记录等待下一次显式反馈。`DISABLED` 不构造传输。SDK 批处理可完成已授权的上传,无需另一次用户交互或模型调用。部署方负责脱敏规则。
|
|
13
13
|
|
|
14
14
|
## 目录
|
|
15
15
|
|
|
@@ -31,11 +31,10 @@ kind: "package-reference"
|
|
|
31
31
|
|
|
32
32
|
| `mode` | 行为 |
|
|
33
33
|
|---|---|
|
|
34
|
-
| `
|
|
35
|
-
| `
|
|
36
|
-
| `DISABLED` | 默认值。不构造协调器、提供方、处理器或导出器;没有遥测记录会离开进程,`feedback/record` 会记录「不会共享任何内容」 |
|
|
34
|
+
| `FEEDBACK_ONLY` | 默认值。文本反馈、评分创建或修改、备注修改和撤回释放尚未交接的前缀,截止该权威反馈事件;后续记录等待 |
|
|
35
|
+
| `DISABLED` | 不构造协调器、提供方、处理器或导出器;没有遥测记录离开进程。活跃会话反馈在本地告警;冷会话修改保持静默 |
|
|
37
36
|
|
|
38
|
-
程序化 TypeScript 配置使用导出的 `SessionTelemetryMode`
|
|
37
|
+
程序化 TypeScript 配置使用导出的 `SessionTelemetryMode` 枚举;原始字符串字面量不可赋值。`FULL` 会被拒绝,不是别名。[`sharing` 属性](../session-telemetry/README.zh.md#the-sharing-disclosure)报告 `feedback-only` 或 `disabled`,不代表投递回执。`/feedback` 确认文本只确认记录。
|
|
39
38
|
|
|
40
39
|
### 最小配置
|
|
41
40
|
|
|
@@ -45,7 +44,7 @@ kind: "package-reference"
|
|
|
45
44
|
- id: sessionTelemetry-otel
|
|
46
45
|
name: '@deepseek-ai/dsh-session-telemetry-otel'
|
|
47
46
|
config:
|
|
48
|
-
mode:
|
|
47
|
+
mode: FEEDBACK_ONLY # optional; defaults to FEEDBACK_ONLY
|
|
49
48
|
shutdownTimeoutMillis: 3000 # optional; defaults to 3000
|
|
50
49
|
exporter: # passed verbatim to the SDK's OTLP/HTTP log exporter
|
|
51
50
|
url: https://collector.example.com/v1/logs
|
|
@@ -56,12 +55,14 @@ kind: "package-reference"
|
|
|
56
55
|
|
|
57
56
|
| 字段 | 默认值 | 含义 |
|
|
58
57
|
|---|---|---|
|
|
59
|
-
| `mode` | `
|
|
58
|
+
| `mode` | `FEEDBACK_ONLY` | 共享策略:`FEEDBACK_ONLY` 或 `DISABLED` |
|
|
60
59
|
| `exporter.url` | 上传模式必填 | 完整 OTLP 日志端点;必须能解析为 `http(s)` |
|
|
61
60
|
| `exporter`、`processor` | — | 原样传给 SDK 导出器与批处理器 |
|
|
62
61
|
| `shutdownTimeoutMillis` | `3,000` | SDK 完整关闭序列的外层截止时间 |
|
|
63
62
|
|
|
64
|
-
|
|
63
|
+
直接调用 `ctx.sessionTelemetry.emit()` 在任何模式下都是空操作,不能绕过反馈授权。继承的父会话反馈不授权子会话导出:子会话需要新的自身反馈。授权后的前缀包含继承的上下文。
|
|
64
|
+
|
|
65
|
+
模型请求、请求头、Session 创建或接纳、恢复,以及插件挂载或 HMR(热模块替换) 均不授权捕获。仅有存储的反馈不会触发任何上传。SDK 定时刷新和关闭可以完成先前已授权的批次,但绝不捕获新记录。
|
|
65
66
|
|
|
66
67
|
### 哪些数据会离开本机
|
|
67
68
|
|
|
@@ -83,7 +84,7 @@ kind: "package-reference"
|
|
|
83
84
|
|
|
84
85
|
### 设计理念
|
|
85
86
|
|
|
86
|
-
后端是对 OTel JS SDK
|
|
87
|
+
后端是对 OTel JS SDK 的薄适配层:它拥有反馈授权、资源身份与外层关闭截止时间。权威 ledger 记录使用 `@deepseek-ai/dsh-session-telemetry-otel` 插桩作用域;此后端不捕获运维记录。资源身份携带 `service.name`/`service.version`(来自 `dsh-llm` 的 `APP_IDENTITY`)以及匿名 `user.id`(来自 `$DSH_HOME/.anonymous-user-id`),按导出批次携带一次,而非逐条记录。
|
|
87
88
|
|
|
88
89
|
### 源码地图
|
|
89
90
|
|
|
@@ -93,11 +94,11 @@ kind: "package-reference"
|
|
|
93
94
|
|
|
94
95
|
### 捕获接线
|
|
95
96
|
|
|
96
|
-
|
|
97
|
+
后端使用包含存储历史的按需捕获。只有新的自身 `feedback/record`、`feedback/message-put` 或 `feedback/message-delete` 事件触发活跃会话捕获,并以该事件为上限。冷会话 `feedback/committed` 通知提供已提交的权威快照,不发布存活 Session 或 Agent。同对象交接游标抑制重复捕获。后端不实现 `flush()`;SDK 负责批处理和关闭排空。
|
|
97
98
|
|
|
98
99
|
### 字段映射
|
|
99
100
|
|
|
100
|
-
|
|
101
|
+
每条遥测记录映射为一条 SDK 日志记录,携带捕获的时间戳、严重级别、正文和属性。反馈授权的是尚未交接的完整前缀,而非只有反馈载荷。
|
|
101
102
|
|
|
102
103
|
</details>
|
|
103
104
|
|
|
@@ -133,7 +134,9 @@ kind: "package-reference"
|
|
|
133
134
|
|
|
134
135
|
- **上游实验性源码树**——`@opentelemetry/sdk-logs` 从上游实验性源码树发布;SDK API 的变动只会落在本包,也仅落在本包,而 seam 约定不动。
|
|
135
136
|
- **真实 collector 行为属于 SDK 导出器**——身份验证、TLS、限流及其他真实 OTLP 部署行为遵循上游 SDK,不由本包自有兼容层处理。
|
|
136
|
-
-
|
|
137
|
+
- **尽力交接**——新冷快照以及重启后的新反馈提交可能重复前缀;接收方按 Session id、格式版本和事件 seq 去重。没有持久化 outbox、投递水位、自动重试承诺或采集端接受保证。OTel 与需显式启用的 DeepSeek API 路径可能重叠。撤回导出删除事件,不是远端擦除。
|
|
138
|
+
|
|
139
|
+
- **后端可用性**——本插件禁用或卸载期间提交的反馈会记录在本地,但恢复插件不会自动重放。捕获要求订阅方保持挂载直到观察到提交;在冷写入尚未完成时卸载,可能错过其 flush 后通知。
|
|
137
140
|
|
|
138
141
|
<a id="dev-note"></a>
|
|
139
142
|
### 开发备注
|
package/lib/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
2
|
import z from "@deepseek-ai/schemastery";
|
|
3
|
+
import { Session } from "@deepseek-ai/dsh-session";
|
|
3
4
|
import { SessionTelemetryBackend, SessionTelemetryCoordinator } from "@deepseek-ai/dsh-session-telemetry";
|
|
4
5
|
import { APP_IDENTITY } from "@deepseek-ai/dsh-llm";
|
|
5
6
|
import { getOrCreateAnonymousUserId } from "@deepseek-ai/dsh-anonymous-user-id";
|
|
@@ -25,20 +26,27 @@ const { version } = createRequire(import.meta.url)("../package.json");
|
|
|
25
26
|
/** Session-sharing policy selected by {@link Config.mode}. */
|
|
26
27
|
var SessionTelemetryMode;
|
|
27
28
|
(function(SessionTelemetryMode) {
|
|
28
|
-
SessionTelemetryMode["FULL"] = "FULL";
|
|
29
29
|
SessionTelemetryMode["FEEDBACK_ONLY"] = "FEEDBACK_ONLY";
|
|
30
30
|
SessionTelemetryMode["DISABLED"] = "DISABLED";
|
|
31
31
|
})(SessionTelemetryMode || (SessionTelemetryMode = {}));
|
|
32
32
|
/** Default session-sharing policy for schema and direct construction. */
|
|
33
|
-
const DEFAULT_TELEMETRY_MODE = SessionTelemetryMode.
|
|
34
|
-
const DISABLED_FEEDBACK_WARNING = "session
|
|
35
|
-
const
|
|
36
|
-
|
|
33
|
+
const DEFAULT_TELEMETRY_MODE = SessionTelemetryMode.FEEDBACK_ONLY;
|
|
34
|
+
const DISABLED_FEEDBACK_WARNING = "OpenTelemetry session upload is DISABLED; this feedback is not uploaded through OpenTelemetry";
|
|
35
|
+
const NON_CANONICAL_EVENT_WARNING = "session telemetry ignored an event absent from the canonical session log";
|
|
36
|
+
/** Only this Session's explicit feedback authorizes replay; fork seeds do not. */
|
|
37
|
+
function isFeedback(session, event) {
|
|
38
|
+
if (event.seq < session.inheritedEventCount) return false;
|
|
39
|
+
switch (event.type) {
|
|
40
|
+
case "feedback/record": return true;
|
|
41
|
+
case "feedback/message-put":
|
|
42
|
+
case "feedback/message-delete": return event.data.sessionId === session.id;
|
|
43
|
+
default: return false;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
37
46
|
/** Resolve the default and reject unknown runtime values before transport setup. */
|
|
38
47
|
function resolveMode(mode) {
|
|
39
48
|
const resolved = mode ?? DEFAULT_TELEMETRY_MODE;
|
|
40
49
|
switch (resolved) {
|
|
41
|
-
case SessionTelemetryMode.FULL:
|
|
42
50
|
case SessionTelemetryMode.FEEDBACK_ONLY:
|
|
43
51
|
case SessionTelemetryMode.DISABLED: return resolved;
|
|
44
52
|
default: return assertNever(resolved);
|
|
@@ -51,7 +59,6 @@ function assertNever(value) {
|
|
|
51
59
|
/** Map the serialized mode onto the seam's backend-independent sharing vocabulary. */
|
|
52
60
|
function sharingStatusFor(mode) {
|
|
53
61
|
switch (mode) {
|
|
54
|
-
case SessionTelemetryMode.FULL: return "full";
|
|
55
62
|
case SessionTelemetryMode.FEEDBACK_ONLY: return "feedback-only";
|
|
56
63
|
case SessionTelemetryMode.DISABLED: return "disabled";
|
|
57
64
|
/* v8 ignore next 2 -- resolveMode already rejected unknown values before this switch; the closed enum cannot reach the default. */
|
|
@@ -91,14 +98,13 @@ const SEVERITY = {
|
|
|
91
98
|
};
|
|
92
99
|
/**
|
|
93
100
|
* The backend plugin — the only entry a deployment loads. It always registers
|
|
94
|
-
* the `
|
|
95
|
-
* pipeline and
|
|
101
|
+
* the `sessionTelemetry` service (duplicate load throws). `FEEDBACK_ONLY` wires the SDK
|
|
102
|
+
* pipeline and on-demand {@link SessionTelemetryCoordinator}; `DISABLED` constructs no
|
|
96
103
|
* SDK state and listens only to warn when recorded feedback stays local.
|
|
97
104
|
*/
|
|
98
105
|
var OpenTelemetrySessionBackend = class extends SessionTelemetryBackend {
|
|
99
106
|
static inject = ["sessions"];
|
|
100
107
|
static Config = Config;
|
|
101
|
-
directEmit;
|
|
102
108
|
provider;
|
|
103
109
|
shutdownTimeoutMillis;
|
|
104
110
|
sharing;
|
|
@@ -107,11 +113,10 @@ var OpenTelemetrySessionBackend = class extends SessionTelemetryBackend {
|
|
|
107
113
|
super(ctx);
|
|
108
114
|
this.sharing = sharingStatusFor(mode);
|
|
109
115
|
if (mode === SessionTelemetryMode.DISABLED) {
|
|
110
|
-
this.directEmit = DROP_RECORD;
|
|
111
116
|
this.provider = void 0;
|
|
112
117
|
this.shutdownTimeoutMillis = DEFAULT_SHUTDOWN_TIMEOUT_MILLIS;
|
|
113
|
-
ctx.on("session/event", (
|
|
114
|
-
if (event
|
|
118
|
+
ctx.on("session/event", (session, event) => {
|
|
119
|
+
if (isFeedback(session, event)) ctx.logger.warn(DISABLED_FEEDBACK_WARNING);
|
|
115
120
|
});
|
|
116
121
|
return;
|
|
117
122
|
}
|
|
@@ -141,9 +146,8 @@ var OpenTelemetrySessionBackend = class extends SessionTelemetryBackend {
|
|
|
141
146
|
})]
|
|
142
147
|
});
|
|
143
148
|
const ledger = this.provider.getLogger("@deepseek-ai/dsh-session-telemetry-otel", version);
|
|
144
|
-
const ops = this.provider.getLogger("@deepseek-ai/dsh-session-telemetry-otel/ops", version);
|
|
145
149
|
const enqueue = (record) => {
|
|
146
|
-
|
|
150
|
+
ledger.emit({
|
|
147
151
|
timestamp: record.time,
|
|
148
152
|
observedTimestamp: record.time,
|
|
149
153
|
...SEVERITY[record.severity],
|
|
@@ -151,35 +155,35 @@ var OpenTelemetrySessionBackend = class extends SessionTelemetryBackend {
|
|
|
151
155
|
attributes: record.attributes
|
|
152
156
|
});
|
|
153
157
|
};
|
|
154
|
-
const
|
|
158
|
+
const coordinator = new SessionTelemetryCoordinator(ctx, {
|
|
155
159
|
emit: enqueue,
|
|
156
160
|
shutdown: () => this.shutdown()
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
return;
|
|
162
|
-
}
|
|
163
|
-
this.directEmit = DROP_RECORD;
|
|
164
|
-
const coordinator = new SessionTelemetryCoordinator(ctx, backend, "on-demand");
|
|
161
|
+
}, {
|
|
162
|
+
capture: "on-demand",
|
|
163
|
+
includeHistory: true
|
|
164
|
+
});
|
|
165
165
|
ctx.on("session/event", (session, event) => {
|
|
166
|
-
if (event
|
|
166
|
+
if (!isFeedback(session, event)) return;
|
|
167
167
|
if (session.eventAt(event.seq) !== event) {
|
|
168
|
-
ctx.logger.warn(
|
|
168
|
+
ctx.logger.warn(NON_CANONICAL_EVENT_WARNING);
|
|
169
169
|
return;
|
|
170
170
|
}
|
|
171
171
|
coordinator.captureSession(session, event.seq);
|
|
172
172
|
});
|
|
173
|
+
ctx.on("feedback/committed", (inspection) => {
|
|
174
|
+
const snapshot = structuredClone(inspection);
|
|
175
|
+
const committed = snapshot.events.at(-1);
|
|
176
|
+
if (committed === void 0) return;
|
|
177
|
+
const session = Session.fromRestore(snapshot.meta.id, snapshot.events, snapshot.meta, snapshot.inheritedEventCount, "detached");
|
|
178
|
+
if (isFeedback(session, committed)) coordinator.captureSession(session, committed.seq);
|
|
179
|
+
});
|
|
173
180
|
}
|
|
174
181
|
/**
|
|
175
|
-
*
|
|
176
|
-
*
|
|
177
|
-
*
|
|
178
|
-
* @param record - the logical record offered directly to the service.
|
|
182
|
+
* Drop direct records. Only a new canonical feedback submission can authorize
|
|
183
|
+
* capture through the private coordinator sink, for every provider.
|
|
184
|
+
* @param _record - the direct record, never uploaded.
|
|
179
185
|
*/
|
|
180
|
-
emit(
|
|
181
|
-
this.directEmit(record);
|
|
182
|
-
}
|
|
186
|
+
emit(_record) {}
|
|
183
187
|
/**
|
|
184
188
|
* Ask the SDK to drain and quiesce, but reject after the backend-owned
|
|
185
189
|
* deadline. OTel's processor export timeout wraps `exportCompleted` only;
|
package/lib/types/index.d.ts
CHANGED
|
@@ -18,19 +18,18 @@ import { type BatchLogRecordProcessorOptions } from '@opentelemetry/sdk-logs';
|
|
|
18
18
|
import type { OTLPExporterNodeConfigBase } from '@opentelemetry/otlp-exporter-base';
|
|
19
19
|
/** Session-sharing policy selected by {@link Config.mode}. */
|
|
20
20
|
export declare enum SessionTelemetryMode {
|
|
21
|
-
FULL = "FULL",
|
|
22
21
|
FEEDBACK_ONLY = "FEEDBACK_ONLY",
|
|
23
22
|
DISABLED = "DISABLED"
|
|
24
23
|
}
|
|
25
24
|
/** Default session-sharing policy for schema and direct construction. */
|
|
26
|
-
export declare const DEFAULT_TELEMETRY_MODE = SessionTelemetryMode.
|
|
25
|
+
export declare const DEFAULT_TELEMETRY_MODE = SessionTelemetryMode.FEEDBACK_ONLY;
|
|
27
26
|
/**
|
|
28
27
|
* Plugin configuration: one sharing policy, two verbatim SDK option objects,
|
|
29
28
|
* and one DSH-owned shutdown bound. Uploading modes validate their endpoint
|
|
30
29
|
* and shutdown deadline at plugin load; `DISABLED` reads neither.
|
|
31
30
|
*/
|
|
32
31
|
export interface Config {
|
|
33
|
-
/**
|
|
32
|
+
/** Defaults to `FEEDBACK_ONLY`: capture session history only when feedback is explicitly submitted. */
|
|
34
33
|
mode?: SessionTelemetryMode;
|
|
35
34
|
/**
|
|
36
35
|
* Passed verbatim to the SDK's OTLP/HTTP log exporter — the complete
|
|
@@ -62,25 +61,23 @@ export declare const Config: z<Config>;
|
|
|
62
61
|
export declare const DEFAULT_SHUTDOWN_TIMEOUT_MILLIS = 3000;
|
|
63
62
|
/**
|
|
64
63
|
* The backend plugin — the only entry a deployment loads. It always registers
|
|
65
|
-
* the `
|
|
66
|
-
* pipeline and
|
|
64
|
+
* the `sessionTelemetry` service (duplicate load throws). `FEEDBACK_ONLY` wires the SDK
|
|
65
|
+
* pipeline and on-demand {@link SessionTelemetryCoordinator}; `DISABLED` constructs no
|
|
67
66
|
* SDK state and listens only to warn when recorded feedback stays local.
|
|
68
67
|
*/
|
|
69
68
|
export declare class OpenTelemetrySessionBackend extends SessionTelemetryBackend {
|
|
70
69
|
static inject: string[];
|
|
71
70
|
static Config: z<Config>;
|
|
72
|
-
private readonly directEmit;
|
|
73
71
|
private readonly provider;
|
|
74
72
|
private readonly shutdownTimeoutMillis;
|
|
75
73
|
readonly sharing: SessionTelemetrySharingStatus;
|
|
76
74
|
constructor(ctx: Context, config: Config);
|
|
77
75
|
/**
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
* @param record - the logical record offered directly to the service.
|
|
76
|
+
* Drop direct records. Only a new canonical feedback submission can authorize
|
|
77
|
+
* capture through the private coordinator sink, for every provider.
|
|
78
|
+
* @param _record - the direct record, never uploaded.
|
|
82
79
|
*/
|
|
83
|
-
emit(
|
|
80
|
+
emit(_record: SessionTelemetryRecord): void;
|
|
84
81
|
/**
|
|
85
82
|
* Ask the SDK to drain and quiesce, but reject after the backend-owned
|
|
86
83
|
* deadline. OTel's processor export timeout wraps `exportCompleted` only;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deepseek-ai/dsh-session-telemetry-otel",
|
|
3
3
|
"description": "OpenTelemetry backend for the DeepSeek Harness telemetry seam: hands captured session records to the OTel JS SDK's log pipeline",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.3-alpha.2",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -36,27 +36,30 @@
|
|
|
36
36
|
"@deepseek-ai/schemastery": "^3.18.2"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
|
-
"@deepseek-ai/dsh-command-feedback": "^0.1.
|
|
40
|
-
"@deepseek-ai/dsh-
|
|
41
|
-
"@deepseek-ai/dsh-
|
|
42
|
-
"@deepseek-ai/dsh-
|
|
43
|
-
"@deepseek-ai/
|
|
44
|
-
"@deepseek-ai/dsh-
|
|
39
|
+
"@deepseek-ai/dsh-command-feedback": "^0.1.3-alpha.2",
|
|
40
|
+
"@deepseek-ai/dsh-message-feedback": "^0.1.3-alpha.2",
|
|
41
|
+
"@deepseek-ai/dsh-llm": "^0.1.3-alpha.2",
|
|
42
|
+
"@deepseek-ai/dsh-session": "^0.1.3-alpha.2",
|
|
43
|
+
"@deepseek-ai/dsh-session-telemetry": "^0.1.3-alpha.2",
|
|
44
|
+
"@deepseek-ai/dsh-anonymous-user-id": "^0.1.3-alpha.2",
|
|
45
|
+
"@deepseek-ai/cordis": "^4.0.2"
|
|
45
46
|
},
|
|
46
47
|
"devDependencies": {
|
|
48
|
+
"@deepseek-ai/dsh-bash-local": "^0.1.3-alpha.2",
|
|
49
|
+
"@deepseek-ai/dsh-command-feedback": "^0.1.3-alpha.2",
|
|
50
|
+
"@deepseek-ai/dsh-llm": "^0.1.3-alpha.2",
|
|
47
51
|
"@deepseek-ai/cordis-plugin-logger-console": "^1.0.2",
|
|
48
|
-
"@deepseek-ai/
|
|
49
|
-
"@deepseek-ai/dsh-
|
|
50
|
-
"@deepseek-ai/dsh-
|
|
51
|
-
"@deepseek-ai/dsh-
|
|
52
|
-
"@deepseek-ai/dsh-
|
|
53
|
-
"@deepseek-ai/dsh-
|
|
54
|
-
"@deepseek-ai/dsh-
|
|
55
|
-
"@deepseek-ai/dsh-session-checkpoint-policy": "^0.1.2-alpha.5",
|
|
56
|
-
"@deepseek-ai/dsh-session-telemetry": "^0.1.2-alpha.5",
|
|
57
|
-
"@deepseek-ai/dsh-subprocess-local": "^0.1.2-alpha.5",
|
|
58
|
-
"@deepseek-ai/dsh-anonymous-user-id": "^0.1.2-alpha.5",
|
|
52
|
+
"@deepseek-ai/dsh-loader-smoke": "^0.1.3-alpha.2",
|
|
53
|
+
"@deepseek-ai/dsh-message-feedback": "^0.1.3-alpha.2",
|
|
54
|
+
"@deepseek-ai/dsh-session": "^0.1.3-alpha.2",
|
|
55
|
+
"@deepseek-ai/dsh-session-checkpoint-policy": "^0.1.3-alpha.2",
|
|
56
|
+
"@deepseek-ai/dsh-session-persistence-jsonl": "^0.1.3-alpha.2",
|
|
57
|
+
"@deepseek-ai/dsh-session-telemetry": "^0.1.3-alpha.2",
|
|
58
|
+
"@deepseek-ai/dsh-anonymous-user-id": "^0.1.3-alpha.2",
|
|
59
59
|
"@deepseek-ai/cordis": "^4.0.2",
|
|
60
|
-
"@deepseek-ai/dsh-
|
|
60
|
+
"@deepseek-ai/dsh-subprocess-local": "^0.1.3-alpha.2",
|
|
61
|
+
"@deepseek-ai/dsh-http-proxy": "^0.1.3-alpha.2",
|
|
62
|
+
"@deepseek-ai/cordis-plugin-loader": "^1.0.3",
|
|
63
|
+
"@deepseek-ai/dsh-app-boot": "^0.1.3-alpha.2"
|
|
61
64
|
}
|
|
62
65
|
}
|