@jingyi0605/codingns4dsh 0.1.2 → 0.1.7-rc.3
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.en.md +4 -4
- package/README.md +14 -5
- package/data/build/dist/client/account-bar.js +57 -3
- package/data/build/dist/client/bundle.js +36246 -268
- package/data/build/dist/client/cli-slots.js +60 -18
- package/data/build/dist/client/dsh-h5-bootstrap.d.ts +2 -0
- package/data/build/dist/client/dsh-h5-bootstrap.js +79 -13
- package/data/build/dist/client/features/file-management-panel.d.ts +5 -0
- package/data/build/dist/client/features/file-management-panel.js +48 -0
- package/data/build/dist/client/features/file-management.d.ts +4 -0
- package/data/build/dist/client/features/file-management.js +50 -0
- package/data/build/dist/client/features/index.d.ts +10 -1
- package/data/build/dist/client/features/index.js +12 -1
- package/data/build/dist/client/features/login-protection-panel.js +1 -1
- package/data/build/dist/client/features/login-protection-session.d.ts +2 -0
- package/data/build/dist/client/features/login-protection-session.js +18 -0
- package/data/build/dist/client/features/peer-host.d.ts +4 -0
- package/data/build/dist/client/features/peer-host.js +89 -0
- package/data/build/dist/client/features/reverse-proxy-panel.js +23 -7
- package/data/build/dist/client/features/reverse-proxy.d.ts +1 -2
- package/data/build/dist/client/features/reverse-proxy.js +75 -5
- package/data/build/dist/client/features/types.d.ts +9 -0
- package/data/build/dist/client/features/workspace-session-enhancement-panel.js +10 -0
- package/data/build/dist/client/features/workspace-session-enhancement.js +18 -1
- package/data/build/dist/client/file-management-dom.d.ts +12 -0
- package/data/build/dist/client/file-management-dom.js +527 -0
- package/data/build/dist/client/git-management.js +24 -5
- package/data/build/dist/client/host-navigation.d.ts +29 -0
- package/data/build/dist/client/host-navigation.js +29 -0
- package/data/build/dist/client/host-router.d.ts +3 -0
- package/data/build/dist/client/host-router.js +2 -0
- package/data/build/dist/client/index.d.ts +6 -1
- package/data/build/dist/client/index.js +30 -10
- package/data/build/dist/client/locale.js +36 -7
- package/data/build/dist/client/peer-host-connection-button.d.ts +13 -0
- package/data/build/dist/client/peer-host-connection-button.js +69 -0
- package/data/build/dist/client/peer-host-management-api.d.ts +40 -0
- package/data/build/dist/client/peer-host-management-api.js +33 -0
- package/data/build/dist/client/peer-host-management-panel.d.ts +13 -0
- package/data/build/dist/client/peer-host-management-panel.js +181 -0
- package/data/build/dist/client/peer-host-native-session-ui.d.ts +60 -0
- package/data/build/dist/client/peer-host-native-session-ui.js +372 -0
- package/data/build/dist/client/peer-host-scoped-client.d.ts +67 -0
- package/data/build/dist/client/peer-host-scoped-client.js +316 -0
- package/data/build/dist/client/peer-host-session-controller.d.ts +30 -0
- package/data/build/dist/client/peer-host-session-controller.js +95 -0
- package/data/build/dist/client/quick-phrase-slot.js +14 -0
- package/data/build/dist/client/remote-web-context.js +26 -4
- package/data/build/dist/client/session-changed-files-view.d.ts +15 -0
- package/data/build/dist/client/session-changed-files-view.js +337 -0
- package/data/build/dist/client/settings-bridge.d.ts +14 -4
- package/data/build/dist/client/settings-bridge.js +59 -12
- package/data/build/dist/client/settings-section.js +17 -4
- package/data/build/dist/client/subscription-slot.js +21 -8
- package/data/build/dist/client/workspace-session-rightbar-dom.d.ts +28 -0
- package/data/build/dist/client/workspace-session-rightbar-dom.js +291 -0
- package/data/build/dist/dsh-capabilities/client/config-forms-adapter.js +25 -33
- package/data/build/dist/dsh-capabilities/client/settings-scope-adapter.d.ts +7 -1
- package/data/build/dist/dsh-capabilities/client/settings-scope-adapter.js +34 -11
- package/data/build/dist/dsh-capabilities/matrix.js +9 -0
- package/data/build/dist/dsh-capabilities/routes.js +35 -0
- package/data/build/dist/dsh-capabilities/settings-store.d.ts +12 -0
- package/data/build/dist/dsh-capabilities/settings-store.js +34 -0
- package/data/build/dist/dsh-capabilities/types.d.ts +1 -1
- package/data/build/dist/features/host-router.d.ts +26 -0
- package/data/build/dist/features/host-router.js +110 -0
- package/data/build/dist/features/registry.js +3 -0
- package/data/build/dist/host/cli-adapters/codex-driver.d.ts +13 -1
- package/data/build/dist/host/cli-adapters/codex-driver.js +528 -72
- package/data/build/dist/host/cli-adapters/command-code-driver.d.ts +21 -2
- package/data/build/dist/host/cli-adapters/command-code-driver.js +408 -105
- package/data/build/dist/host/cli-adapters/driver.d.ts +2 -0
- package/data/build/dist/host/cli-adapters/dsh-message-projector.d.ts +2 -0
- package/data/build/dist/host/cli-adapters/dsh-message-projector.js +47 -28
- package/data/build/dist/host/cli-adapters/dsh-tool-history.js +37 -0
- package/data/build/dist/host/cli-adapters/feature.js +94 -10
- package/data/build/dist/host/cli-adapters/json-rpc-process.d.ts +6 -0
- package/data/build/dist/host/cli-adapters/json-rpc-process.js +14 -3
- package/data/build/dist/host/cli-adapters/kimi-driver.js +3 -3
- package/data/build/dist/host/cli-adapters/model-catalog.d.ts +6 -0
- package/data/build/dist/host/cli-adapters/model-catalog.js +8 -0
- package/data/build/dist/host/cli-adapters/opencode-driver.js +14 -2
- package/data/build/dist/host/cli-adapters/pi-driver.js +2 -2
- package/data/build/dist/host/cli-adapters/process-utils.d.ts +8 -0
- package/data/build/dist/host/cli-adapters/process-utils.js +48 -0
- package/data/build/dist/host/cli-adapters/registry.d.ts +6 -1
- package/data/build/dist/host/cli-adapters/registry.js +41 -7
- package/data/build/dist/host/cli-adapters/rpc-driver-utils.js +23 -4
- package/data/build/dist/host/cli-adapters/standard-stream-driver.d.ts +3 -0
- package/data/build/dist/host/cli-adapters/standard-stream-driver.js +36 -15
- package/data/build/dist/host/dsh-device-runtime.d.ts +2 -0
- package/data/build/dist/host/dsh-device-runtime.js +55 -29
- package/data/build/dist/host/dsh-runtime-version.d.ts +3 -2
- package/data/build/dist/host/dsh-runtime-version.js +71 -2
- package/data/build/dist/host/features/auth.js +10 -2
- package/data/build/dist/host/features/file-management.d.ts +5 -0
- package/data/build/dist/host/features/file-management.js +267 -0
- package/data/build/dist/host/features/git-management.js +24 -2
- package/data/build/dist/host/features/index.d.ts +2 -0
- package/data/build/dist/host/features/index.js +6 -0
- package/data/build/dist/host/features/peer-host.d.ts +22 -0
- package/data/build/dist/host/features/peer-host.js +322 -0
- package/data/build/dist/host/features/types.d.ts +4 -0
- package/data/build/dist/host/host-router.d.ts +3 -0
- package/data/build/dist/host/host-router.js +2 -0
- package/data/build/dist/host/index-injection.d.ts +17 -0
- package/data/build/dist/host/index-injection.js +24 -0
- package/data/build/dist/host/index.d.ts +4 -1
- package/data/build/dist/host/index.js +41 -7
- package/data/build/dist/host/lan-access-dsh.d.ts +34 -1
- package/data/build/dist/host/lan-access-dsh.js +145 -26
- package/data/build/dist/host/modules/peer-host/host-api-proxy-service.d.ts +52 -0
- package/data/build/dist/host/modules/peer-host/host-api-proxy-service.js +166 -0
- package/data/build/dist/host/modules/peer-host/host-ws-connector.d.ts +31 -0
- package/data/build/dist/host/modules/peer-host/host-ws-connector.js +108 -0
- package/data/build/dist/host/modules/peer-host/host-ws-proxy-service.d.ts +26 -0
- package/data/build/dist/host/modules/peer-host/host-ws-proxy-service.js +159 -0
- package/data/build/dist/host/modules/peer-host/peer-host-aggregate-service.d.ts +50 -0
- package/data/build/dist/host/modules/peer-host/peer-host-aggregate-service.js +97 -0
- package/data/build/dist/host/modules/peer-host/peer-host-diagnostics.d.ts +19 -0
- package/data/build/dist/host/modules/peer-host/peer-host-diagnostics.js +54 -0
- package/data/build/dist/host/modules/peer-host/peer-host-handshake.d.ts +44 -0
- package/data/build/dist/host/modules/peer-host/peer-host-handshake.js +133 -0
- package/data/build/dist/host/modules/peer-host/peer-host-relay.d.ts +65 -0
- package/data/build/dist/host/modules/peer-host/peer-host-relay.js +196 -0
- package/data/build/dist/host/modules/peer-host/peer-host-session.d.ts +42 -0
- package/data/build/dist/host/modules/peer-host/peer-host-session.js +152 -0
- package/data/build/dist/host/modules/peer-host/peer-host-store.d.ts +92 -0
- package/data/build/dist/host/modules/peer-host/peer-host-store.js +323 -0
- package/data/build/dist/host/modules/peer-host/peer-host-ws-gateway.d.ts +34 -0
- package/data/build/dist/host/modules/peer-host/peer-host-ws-gateway.js +156 -0
- package/data/build/dist/host/native-session-bridge.d.ts +18 -2
- package/data/build/dist/host/native-session-bridge.js +236 -8
- package/data/build/dist/host/remote-web-runtime.js +26 -1
- package/data/build/dist/host/rpc.js +8 -3
- package/data/build/dist/host/session-changes.d.ts +5 -0
- package/data/build/dist/host/session-changes.js +163 -0
- package/data/build/dist/host/settings.js +6 -0
- package/data/build/dist/index.d.ts +1 -1
- package/data/build/dist/index.js +1 -1
- package/data/build/dist/shared/contracts/cli-adapter.d.ts +23 -2
- package/data/build/dist/shared/contracts/config.d.ts +15 -0
- package/data/build/dist/shared/contracts/config.js +10 -0
- package/data/build/dist/shared/contracts/dsh-device.d.ts +2 -0
- package/data/build/dist/shared/contracts/errors.d.ts +14 -0
- package/data/build/dist/shared/contracts/errors.js +15 -0
- package/data/build/dist/shared/contracts/feature.d.ts +2 -0
- package/data/build/dist/shared/contracts/file-management.d.ts +6 -0
- package/data/build/dist/shared/contracts/file-management.js +3 -0
- package/data/build/dist/shared/contracts/peer-host.d.ts +116 -15
- package/data/build/dist/shared/contracts/peer-host.js +19 -0
- package/data/build/dist/shared/contracts/version.d.ts +1 -1
- package/data/build/dist/shared/contracts/version.js +1 -1
- package/data/build/dist/shared/index.d.ts +4 -3
- package/data/build/dist/shared/index.js +2 -2
- package/data/build/dist/transport/debug.d.ts +5 -0
- package/data/build/dist/transport/debug.js +23 -1
- package/data/build/dist/transport/dsh-transport.d.ts +2 -0
- package/data/build/dist/transport/dsh-transport.js +11 -0
- package/data/build/dist/transport/webrtc-client.d.ts +2 -0
- package/data/build/dist/transport/webrtc-client.js +2 -1
- package/data/build/dist/transport/webrtc-host.d.ts +2 -0
- package/data/build/dist/transport/webrtc-host.js +6 -3
- package/data/build/dist/typert.host.d.ts +1 -1
- package/data/build/dist/typert.host.js +2 -1
- package/dsh.bundle.patch +10 -0
- package/package.json +19 -11
- package/profile/README.md +2 -2
- package/profile/package.json +2 -2
- package/profile/version.json +1 -1
- package/version.json +1 -1
|
@@ -16,9 +16,17 @@ export function createCodingNsNativeSessionBridge(ctx, dshVersion) {
|
|
|
16
16
|
? ctx.on.bind(ctx)
|
|
17
17
|
: undefined;
|
|
18
18
|
const externalHandles = new Map();
|
|
19
|
+
const compactionStates = new Map();
|
|
20
|
+
const confirmedContextWindows = new Map();
|
|
21
|
+
// Agent.inject() 只是把消息放进队列,新的 DSH step 会在稍后的事件循环中
|
|
22
|
+
// 才创建。此期间 activeStep 仍然指向旧 step,工具追加必须暂缓,否则会把
|
|
23
|
+
// 下一步的工具写进旧 step;step/start 到达后由工具投影器重试。
|
|
24
|
+
const pendingStepTransitions = new Set();
|
|
19
25
|
let injectedStepSequence = 0;
|
|
20
26
|
const modernInjectedSource = isModernDshVersion(dshVersion);
|
|
21
27
|
const appendNativeToolCall = (sessionId, call) => {
|
|
28
|
+
if (on !== undefined && pendingStepTransitions.has(sessionId))
|
|
29
|
+
return null;
|
|
22
30
|
const session = appendableSession(store?.get(sessionId));
|
|
23
31
|
const position = session === null ? null : activeStep(session);
|
|
24
32
|
if (session === null || position === null)
|
|
@@ -91,11 +99,60 @@ export function createCodingNsNativeSessionBridge(ctx, dshVersion) {
|
|
|
91
99
|
// 投影先清空旧 pressure,再等待下一条 usage,ContextMeter 因而闪烁。
|
|
92
100
|
// 保留已有容量并跳过等价事件,让用量更新直接落到同一个组件上。
|
|
93
101
|
const previous = latestRequestContext(session);
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
102
|
+
const contextKey = `${sessionId}\u0000${context.provider}\u0000${context.model}`;
|
|
103
|
+
if (previous !== null && previous.provider === context.provider && previous.model === context.model) {
|
|
104
|
+
const historicalWindow = historicalUsageContextWindow(session);
|
|
105
|
+
if (context.contextWindow === undefined) {
|
|
106
|
+
if (historicalWindow !== undefined && previous.contextWindow !== historicalWindow) {
|
|
107
|
+
session.append('request/context', {
|
|
108
|
+
provider: context.provider,
|
|
109
|
+
model: context.model,
|
|
110
|
+
contextWindow: historicalWindow,
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
return true;
|
|
114
|
+
}
|
|
115
|
+
if (previous.contextWindow === context.contextWindow
|
|
116
|
+
&& context.confirmed === true
|
|
117
|
+
&& historicalWindow !== undefined
|
|
118
|
+
&& historicalWindow !== context.contextWindow) {
|
|
119
|
+
session.append('request/context', {
|
|
120
|
+
provider: context.provider,
|
|
121
|
+
model: context.model,
|
|
122
|
+
contextWindow: historicalWindow,
|
|
123
|
+
});
|
|
124
|
+
confirmedContextWindows.set(contextKey, historicalWindow);
|
|
125
|
+
return true;
|
|
126
|
+
}
|
|
127
|
+
if (previous.contextWindow === context.contextWindow) {
|
|
128
|
+
if (context.confirmed === true && context.source !== 'catalog' && context.contextWindow !== undefined) {
|
|
129
|
+
confirmedContextWindows.set(contextKey, context.contextWindow);
|
|
130
|
+
}
|
|
131
|
+
return true;
|
|
132
|
+
}
|
|
133
|
+
// 已经确认过的同一路由容量是会话级事实。迟到/全局 usage 不能覆盖它。
|
|
134
|
+
// DSH 每个新 step 会先写入一次通用 1M 占位值。catalog 提示必须能把
|
|
135
|
+
// 这个占位值恢复为已知容量,但真实 Provider usage 仍由锁定值保护。
|
|
136
|
+
if (confirmedContextWindows.has(contextKey) && context.source !== 'catalog')
|
|
137
|
+
return true;
|
|
138
|
+
// 进程重启后仍可从历史 usage 恢复稳定容量,避免尾部遗留的错误
|
|
139
|
+
// request/context=1M 在第二轮开始时再次成为当前窗口。
|
|
140
|
+
if (context.confirmed === true && historicalWindow !== undefined && historicalWindow !== context.contextWindow) {
|
|
141
|
+
if (previous.contextWindow !== historicalWindow) {
|
|
142
|
+
session.append('request/context', {
|
|
143
|
+
provider: context.provider,
|
|
144
|
+
model: context.model,
|
|
145
|
+
contextWindow: historicalWindow,
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
confirmedContextWindows.set(contextKey, historicalWindow);
|
|
149
|
+
return true;
|
|
150
|
+
}
|
|
151
|
+
// 允许本次运行首次明确确认的 usage 修正历史遗留的路由占位值,
|
|
152
|
+
// 例如旧日志中的 1M 随后被 Codex usage 明确纠正为 258400。
|
|
153
|
+
if (context.confirmed !== true)
|
|
154
|
+
return true;
|
|
155
|
+
}
|
|
99
156
|
// Registry 在一轮开始时只能提供适配器身份,不能提供 Provider 容量。
|
|
100
157
|
// 继承上一条已知容量,避免先写无容量事件导致 ContextMeter 卸载;
|
|
101
158
|
// 真正的 usage 到达后,投影器会用 Provider 的最新容量覆盖它。
|
|
@@ -105,6 +162,9 @@ export function createCodingNsNativeSessionBridge(ctx, dshVersion) {
|
|
|
105
162
|
model: context.model,
|
|
106
163
|
...(contextWindow === undefined ? {} : { contextWindow }),
|
|
107
164
|
});
|
|
165
|
+
if (context.confirmed === true && context.source !== 'catalog' && context.contextWindow !== undefined) {
|
|
166
|
+
confirmedContextWindows.set(contextKey, context.contextWindow);
|
|
167
|
+
}
|
|
108
168
|
return true;
|
|
109
169
|
}
|
|
110
170
|
catch {
|
|
@@ -117,6 +177,18 @@ export function createCodingNsNativeSessionBridge(ctx, dshVersion) {
|
|
|
117
177
|
if (session === null || position === null)
|
|
118
178
|
return false;
|
|
119
179
|
try {
|
|
180
|
+
const previousContext = latestRequestContext(session);
|
|
181
|
+
const normalizedUsage = previousContext?.contextWindow !== undefined
|
|
182
|
+
&& usage.contextWindow !== undefined
|
|
183
|
+
&& usage.contextWindow !== previousContext.contextWindow
|
|
184
|
+
? {
|
|
185
|
+
...usage,
|
|
186
|
+
contextWindow: previousContext.contextWindow,
|
|
187
|
+
...(usage.contextTokens === undefined ? {} : {
|
|
188
|
+
contextUsageRatio: Number(Math.min(1, usage.contextTokens / previousContext.contextWindow).toFixed(6)),
|
|
189
|
+
}),
|
|
190
|
+
}
|
|
191
|
+
: usage;
|
|
120
192
|
session.append('assistant/attempt', {
|
|
121
193
|
turn: position.turn,
|
|
122
194
|
step: position.step,
|
|
@@ -125,7 +197,7 @@ export function createCodingNsNativeSessionBridge(ctx, dshVersion) {
|
|
|
125
197
|
time: Date.now(),
|
|
126
198
|
chunk: {
|
|
127
199
|
type: 'usage',
|
|
128
|
-
usage: compactUsage(
|
|
200
|
+
usage: compactUsage(normalizedUsage),
|
|
129
201
|
},
|
|
130
202
|
}],
|
|
131
203
|
});
|
|
@@ -135,6 +207,76 @@ export function createCodingNsNativeSessionBridge(ctx, dshVersion) {
|
|
|
135
207
|
return false;
|
|
136
208
|
}
|
|
137
209
|
};
|
|
210
|
+
const appendNativeCompactionEvent = (sessionId, event) => {
|
|
211
|
+
const session = appendableSession(store?.get(sessionId));
|
|
212
|
+
if (session === null)
|
|
213
|
+
return false;
|
|
214
|
+
try {
|
|
215
|
+
if (event.phase === 'start') {
|
|
216
|
+
if (compactionStates.has(sessionId))
|
|
217
|
+
return true;
|
|
218
|
+
const compactionId = event.compactionId?.trim() || `codingns-compaction-${randomUUID()}`;
|
|
219
|
+
const position = activeStep(session);
|
|
220
|
+
session.append('compaction/start', {
|
|
221
|
+
compactionId,
|
|
222
|
+
turn: position?.turn ?? null,
|
|
223
|
+
});
|
|
224
|
+
compactionStates.set(sessionId, {
|
|
225
|
+
compactionId,
|
|
226
|
+
turn: position?.turn ?? null,
|
|
227
|
+
summaryAppended: false,
|
|
228
|
+
});
|
|
229
|
+
return true;
|
|
230
|
+
}
|
|
231
|
+
const state = compactionStates.get(sessionId);
|
|
232
|
+
if (state === undefined)
|
|
233
|
+
return false;
|
|
234
|
+
if ((event.phase === 'summary' || event.phase === 'end' && event.summary !== undefined) && !state.summaryAppended) {
|
|
235
|
+
const range = compactionSurfaceRange(session);
|
|
236
|
+
if (range !== null) {
|
|
237
|
+
const summary = boundCompactionSummary(event.summary);
|
|
238
|
+
session.append('compaction/summary', {
|
|
239
|
+
compactionId: state.compactionId,
|
|
240
|
+
summary: [{ type: 'text', text: summary }],
|
|
241
|
+
shadowedRange: { start: range.start, end: range.end },
|
|
242
|
+
shadowedSeqs: range.seqs,
|
|
243
|
+
shadowedTokenCount: safeCount(event.shadowedTokenCount),
|
|
244
|
+
provider: event.provider?.trim() || 'codingns-external',
|
|
245
|
+
model: event.model?.trim() || 'external-agent',
|
|
246
|
+
});
|
|
247
|
+
// DSH 前端的 compaction 节点由紧随 summary 的 checkpoint 替换事件生成。
|
|
248
|
+
// DSH 0.1.7 起会话格式只接受生产者自持的 source.kind,旧的 plugin 包装
|
|
249
|
+
// 会让整轮持久化失败;0.1.6 及更早仍由 dsh-compaction 的 plugin 标记识别。
|
|
250
|
+
session.append('user/message', {
|
|
251
|
+
id: `codingns-compaction-${state.compactionId}`,
|
|
252
|
+
role: 'user',
|
|
253
|
+
content: [{ type: 'text', text: summary }],
|
|
254
|
+
source: modernInjectedSource
|
|
255
|
+
? { kind: 'compact-checkpoint', compactionId: state.compactionId }
|
|
256
|
+
: { kind: 'plugin', plugin: 'compact' },
|
|
257
|
+
}, {
|
|
258
|
+
surfaceOp: { op: 'replace', startSeq: range.start, endSeq: range.end },
|
|
259
|
+
sourceEventSeqs: range.seqs,
|
|
260
|
+
});
|
|
261
|
+
state.summaryAppended = true;
|
|
262
|
+
}
|
|
263
|
+
return true;
|
|
264
|
+
}
|
|
265
|
+
if (event.phase === 'end') {
|
|
266
|
+
session.append('compaction/end', {
|
|
267
|
+
compactionId: state.compactionId,
|
|
268
|
+
turn: state.turn,
|
|
269
|
+
...(event.error?.trim() ? { error: event.error.trim().slice(0, 512) } : !state.summaryAppended ? { error: 'Provider 未返回可投影的压缩摘要。' } : {}),
|
|
270
|
+
});
|
|
271
|
+
compactionStates.delete(sessionId);
|
|
272
|
+
}
|
|
273
|
+
return true;
|
|
274
|
+
}
|
|
275
|
+
catch {
|
|
276
|
+
// 原生服务缺失或版本不支持 compaction 事件时,不能阻断 Provider 回合。
|
|
277
|
+
return false;
|
|
278
|
+
}
|
|
279
|
+
};
|
|
138
280
|
const injectNativeNextStep = (sessionId, summary = '外部工具已完成,继续处理当前任务。') => {
|
|
139
281
|
const agent = nativeAgent(ctx, sessionId);
|
|
140
282
|
if (agent === null || typeof agent.inject !== 'function')
|
|
@@ -142,7 +284,8 @@ export function createCodingNsNativeSessionBridge(ctx, dshVersion) {
|
|
|
142
284
|
injectedStepSequence += 1;
|
|
143
285
|
const boundedSummary = summary.trim().slice(0, 120) || '外部工具已完成,继续处理当前任务。';
|
|
144
286
|
try {
|
|
145
|
-
|
|
287
|
+
if (on !== undefined)
|
|
288
|
+
pendingStepTransitions.add(sessionId);
|
|
146
289
|
agent.inject({
|
|
147
290
|
id: `codingns-external-step-${injectedStepSequence}-${randomUUID()}`,
|
|
148
291
|
role: 'user',
|
|
@@ -154,6 +297,7 @@ export function createCodingNsNativeSessionBridge(ctx, dshVersion) {
|
|
|
154
297
|
return true;
|
|
155
298
|
}
|
|
156
299
|
catch {
|
|
300
|
+
pendingStepTransitions.delete(sessionId);
|
|
157
301
|
return false;
|
|
158
302
|
}
|
|
159
303
|
};
|
|
@@ -222,6 +366,9 @@ export function createCodingNsNativeSessionBridge(ctx, dshVersion) {
|
|
|
222
366
|
appendUsageSample(sessionId, usage) {
|
|
223
367
|
return appendNativeUsageSample(sessionId, usage);
|
|
224
368
|
},
|
|
369
|
+
appendCompactionEvent(sessionId, event) {
|
|
370
|
+
return appendNativeCompactionEvent(sessionId, event);
|
|
371
|
+
},
|
|
225
372
|
canInjectNextStep(sessionId) {
|
|
226
373
|
return canInjectNativeNextStep(sessionId);
|
|
227
374
|
},
|
|
@@ -319,7 +466,15 @@ export function createCodingNsNativeSessionBridge(ctx, dshVersion) {
|
|
|
319
466
|
subscribe(handlers) {
|
|
320
467
|
const disposers = [];
|
|
321
468
|
if (on !== undefined && handlers.onEvent !== undefined) {
|
|
322
|
-
disposers.push(on('session/event', (session, event) =>
|
|
469
|
+
disposers.push(on('session/event', (session, event) => {
|
|
470
|
+
if (isNativeStepStart(event)) {
|
|
471
|
+
for (const sessionId of pendingStepTransitions) {
|
|
472
|
+
if (store?.get(sessionId) === session)
|
|
473
|
+
pendingStepTransitions.delete(sessionId);
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
handlers.onEvent?.(session, event);
|
|
477
|
+
}));
|
|
323
478
|
}
|
|
324
479
|
if (on !== undefined && handlers.onFlush !== undefined) {
|
|
325
480
|
disposers.push(on('session/flush', (session) => handlers.onFlush?.(session)));
|
|
@@ -336,6 +491,9 @@ function appendableSession(value) {
|
|
|
336
491
|
return null;
|
|
337
492
|
return value;
|
|
338
493
|
}
|
|
494
|
+
function isNativeStepStart(value) {
|
|
495
|
+
return isRecord(value) && value.type === 'step/start';
|
|
496
|
+
}
|
|
339
497
|
function latestRequestContext(session) {
|
|
340
498
|
let events;
|
|
341
499
|
try {
|
|
@@ -362,6 +520,37 @@ function latestRequestContext(session) {
|
|
|
362
520
|
}
|
|
363
521
|
return null;
|
|
364
522
|
}
|
|
523
|
+
function historicalUsageContextWindow(session) {
|
|
524
|
+
let events;
|
|
525
|
+
try {
|
|
526
|
+
events = session.snapshotEvents();
|
|
527
|
+
}
|
|
528
|
+
catch {
|
|
529
|
+
return undefined;
|
|
530
|
+
}
|
|
531
|
+
const counts = new Map();
|
|
532
|
+
for (const candidate of events) {
|
|
533
|
+
const event = isRecord(candidate) && candidate.type === 'assistant/attempt' ? candidate : null;
|
|
534
|
+
const data = isRecord(event?.data) ? event.data : null;
|
|
535
|
+
const stream = Array.isArray(data?.stream) ? data.stream : [];
|
|
536
|
+
for (const entry of stream) {
|
|
537
|
+
const chunk = isRecord(entry) && isRecord(entry.chunk) ? entry.chunk : null;
|
|
538
|
+
const usage = isRecord(chunk?.usage) ? chunk.usage : null;
|
|
539
|
+
const window = usage?.contextWindow;
|
|
540
|
+
if (typeof window === 'number' && Number.isFinite(window) && window > 0)
|
|
541
|
+
counts.set(window, (counts.get(window) ?? 0) + 1);
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
let selected;
|
|
545
|
+
let count = 0;
|
|
546
|
+
for (const [window, occurrences] of counts) {
|
|
547
|
+
if (occurrences >= count) {
|
|
548
|
+
selected = window;
|
|
549
|
+
count = occurrences;
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
return selected;
|
|
553
|
+
}
|
|
365
554
|
function activeStep(session) {
|
|
366
555
|
let events;
|
|
367
556
|
try {
|
|
@@ -390,6 +579,45 @@ function activeStep(session) {
|
|
|
390
579
|
function eventSeq(value) {
|
|
391
580
|
return isRecord(value) ? finiteInteger(value.seq) : null;
|
|
392
581
|
}
|
|
582
|
+
function compactionSurfaceRange(session) {
|
|
583
|
+
let nodes = [];
|
|
584
|
+
try {
|
|
585
|
+
if (Array.isArray(session.surface?.nodes))
|
|
586
|
+
nodes = session.surface.nodes;
|
|
587
|
+
if (nodes.length === 0) {
|
|
588
|
+
nodes = session.snapshotEvents().flatMap((candidate) => {
|
|
589
|
+
if (!isRecord(candidate) || typeof candidate.seq !== 'number' || candidate.type === 'system/message')
|
|
590
|
+
return [];
|
|
591
|
+
const op = candidate.surfaceOp;
|
|
592
|
+
return op === 'append' ? [candidate.seq] : [];
|
|
593
|
+
});
|
|
594
|
+
}
|
|
595
|
+
const events = session.snapshotEvents();
|
|
596
|
+
let usable = nodes.filter((seq) => {
|
|
597
|
+
const event = session.eventAt?.(seq) ?? events[seq];
|
|
598
|
+
return !(isRecord(event) && event.type === 'system/message');
|
|
599
|
+
});
|
|
600
|
+
// 当前回合刚追加的 user/message 不是历史压缩对象,保留它避免把用户本轮
|
|
601
|
+
// 输入一并替换;旧 assistant/tool 节点仍可作为压缩范围。
|
|
602
|
+
const last = usable.at(-1);
|
|
603
|
+
const lastEvent = last === undefined ? undefined : session.eventAt?.(last) ?? events[last];
|
|
604
|
+
if (last !== undefined && isRecord(lastEvent) && lastEvent.type === 'user/message')
|
|
605
|
+
usable = usable.slice(0, -1);
|
|
606
|
+
if (usable.length === 0)
|
|
607
|
+
return null;
|
|
608
|
+
return { start: usable[0], end: usable.at(-1), seqs: usable };
|
|
609
|
+
}
|
|
610
|
+
catch {
|
|
611
|
+
return null;
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
function boundCompactionSummary(summary) {
|
|
615
|
+
const value = summary?.trim() || 'Codex 已压缩较早的上下文。';
|
|
616
|
+
return value.slice(0, 120);
|
|
617
|
+
}
|
|
618
|
+
function safeCount(value) {
|
|
619
|
+
return value !== undefined && Number.isSafeInteger(value) && value >= 0 ? value : 0;
|
|
620
|
+
}
|
|
393
621
|
function finiteInteger(value) {
|
|
394
622
|
return typeof value === 'number' && Number.isSafeInteger(value) && value >= 0 ? value : null;
|
|
395
623
|
}
|
|
@@ -358,7 +358,7 @@ export function createLocalDshWebRuntimeProvider(options) {
|
|
|
358
358
|
if (input.headers !== undefined)
|
|
359
359
|
init.headers = Object.fromEntries(input.headers);
|
|
360
360
|
if (input.body !== undefined)
|
|
361
|
-
init.body = input.body;
|
|
361
|
+
init.body = normalizeConnectionRpcBody(path, input.method ?? 'GET', input.body);
|
|
362
362
|
await ensureAuthenticated();
|
|
363
363
|
const response = await fetchLocal(path, init);
|
|
364
364
|
debug.log('web.provider.request.response', { sessionId: session.sessionId, path, method: input.method ?? 'GET', status: response.status });
|
|
@@ -409,6 +409,31 @@ function getSetCookie(headers) {
|
|
|
409
409
|
}
|
|
410
410
|
return undefined;
|
|
411
411
|
}
|
|
412
|
+
/**
|
|
413
|
+
* DSH Gateway 的 Connection RPC 要求请求参数位于 payload.args。
|
|
414
|
+
* 旧版 DSH Web Client 曾把单个参数对象直接放进 payload;只在 `/api/*`
|
|
415
|
+
* 的 POST RPC 请求上补这一层,已经符合协议的请求保持字节级语义不变。
|
|
416
|
+
*/
|
|
417
|
+
function normalizeConnectionRpcBody(path, method, body) {
|
|
418
|
+
if (method.toUpperCase() !== 'POST' || !path.startsWith('/api/'))
|
|
419
|
+
return body;
|
|
420
|
+
try {
|
|
421
|
+
const message = JSON.parse(body);
|
|
422
|
+
if (!isOfficialConnectionRpcMessage(message) || !isRecord(message.payload) || 'args' in message.payload)
|
|
423
|
+
return body;
|
|
424
|
+
return JSON.stringify({ ...message, payload: { args: message.payload } });
|
|
425
|
+
}
|
|
426
|
+
catch {
|
|
427
|
+
return body;
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
/** 只兼容 DSH 官方两段式 Remote endpoint,不能改写 CodingNS 自有 RPC。 */
|
|
431
|
+
function isOfficialConnectionRpcMessage(value) {
|
|
432
|
+
if (!isRecord(value) || value.type !== 'client-request' || typeof value.method !== 'string')
|
|
433
|
+
return false;
|
|
434
|
+
const parts = value.method.split('/');
|
|
435
|
+
return parts.length === 2 && parts.every((part) => part !== '') && parts[0] !== 'codingns';
|
|
436
|
+
}
|
|
412
437
|
class RemoteWebRuntimeError extends Error {
|
|
413
438
|
code;
|
|
414
439
|
constructor(code, message) {
|
|
@@ -179,7 +179,9 @@ const CODINGNS_RPC_ENDPOINTS = [
|
|
|
179
179
|
'debug/runtime/get', 'debug/runtime/list', 'debug/runtime/stop',
|
|
180
180
|
'debug/port/check', 'debug/port/terminate', 'debug/port/kill', 'debug/proxy/get', 'debug/proxy/enable', 'debug/proxy/disable',
|
|
181
181
|
'git/status', 'git/init', 'git/diff', 'git/stage', 'git/unstage', 'git/discard', 'git/commit', 'git/commit-diff', 'git/history', 'git/branches', 'git/switch', 'git/fetch', 'git/pull', 'git/push', 'git/undo',
|
|
182
|
-
'
|
|
182
|
+
'fileManagement/session-changes', 'fileManagement/read', 'fileManagement/download', 'fileManagement/write', 'fileManagement/create-file', 'fileManagement/create-directory', 'fileManagement/rename', 'fileManagement/copy', 'fileManagement/move', 'fileManagement/delete', 'fileManagement/git-ignore',
|
|
183
|
+
'lanAccessDsh/addresses', 'lanAccessDsh/detect', 'lanAccessDsh/get', 'lanAccessDsh/settings/get', 'lanAccessDsh/settings/set', 'lanAccessDsh/login/get', 'lanAccessDsh/login/set', 'lanAccessDsh/login/session/open', 'lanAccessDsh/login/session/refresh', 'lanAccessDsh/start', 'lanAccessDsh/stop',
|
|
184
|
+
'peerHost/list', 'peerHost/diagnostics', 'peerHost/create', 'peerHost/update', 'peerHost/remove', 'peerHost/check', 'peerHost/reconnect', 'peerHost/login', 'peerHost/logout', 'peerHost/request', 'peerHost/wsEndpoint', 'peerHost/aggregate',
|
|
183
185
|
'cli/catalog', 'cli/models', 'cli/adapter/set', 'cli/session/get', 'cli/session/set', 'cli/session/list', 'cli/session/adapter-map', 'cli/session/archive', 'cli/session/steer', 'cli/session/follow-up', 'cli/session/interrupt', 'cli/subscription',
|
|
184
186
|
];
|
|
185
187
|
/** 创建远程设置处理器;只允许 Codingns4DSH 自己的 namespace 和路径编辑。 */
|
|
@@ -249,9 +251,12 @@ function isAllowedSettingsPath(path) {
|
|
|
249
251
|
if (path.length === 1)
|
|
250
252
|
return ['controlBaseUrl', 'controlBaseUrls', 'terminalEnhancement', 'workspaceSessionEnhancement'].includes(path[0] ?? '');
|
|
251
253
|
if (path[0] === 'modules')
|
|
252
|
-
return path.length === 2 && ['lanAccess', 'reverseProxy', 'cliAdapters', 'terminalEnhancement', 'workspaceSessionEnhancement', 'debug', 'gitManagement'].includes(path[1] ?? '');
|
|
254
|
+
return path.length === 2 && ['lanAccess', 'reverseProxy', 'cliAdapters', 'terminalEnhancement', 'workspaceSessionEnhancement', 'debug', 'gitManagement', 'fileManagement', 'peerHost'].includes(path[1] ?? '');
|
|
253
255
|
if (path[0] === 'workspaceSessionEnhancement') {
|
|
254
|
-
return path.length === 2 && ['showAdapterLogo', 'showArchivedSessions', 'showWorkspaceHiding', 'hiddenWorkspaceIds', 'showSubscriptionUsage', 'showQuickPhrases', 'quickPhrases', 'quickPhrasesSeeded'].includes(path[1] ?? '');
|
|
256
|
+
return path.length === 2 && ['showAdapterLogo', 'showArchivedSessions', 'showWorkspaceHiding', 'hiddenWorkspaceIds', 'showSubscriptionUsage', 'showQuickPhrases', 'rememberConversationRightbarRatio', 'quickPhrases', 'quickPhrasesSeeded'].includes(path[1] ?? '');
|
|
257
|
+
}
|
|
258
|
+
if (path[0] === 'fileManagement') {
|
|
259
|
+
return path.length === 2 && ['menuEnhancement', 'fileEditor', 'sessionChangedFiles'].includes(path[1] ?? '');
|
|
255
260
|
}
|
|
256
261
|
return path[0] === 'lanAccessDsh' && path.length === 2 && ['autoStart', 'listenHost', 'listenPort', 'dshPort'].includes(path[1] ?? '');
|
|
257
262
|
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { SessionChangedFiles } from '../shared/contracts/file-management.js';
|
|
2
|
+
import type { CodingNsHostServices } from './features/types.js';
|
|
3
|
+
/** 优先从 DSH 原生 Session 事件读取,原生事件不可用时回退到 JSONL。 */
|
|
4
|
+
export declare function readSessionChangedFiles(services: CodingNsHostServices, sessionId: string, workspaceRoot: string): Promise<SessionChangedFiles>;
|
|
5
|
+
//# sourceMappingURL=session-changes.d.ts.map
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import { isAbsolute, normalize, relative, resolve } from 'node:path';
|
|
3
|
+
const PATH_KEYS = new Set([
|
|
4
|
+
'path', 'paths', 'filePath', 'file_path', 'srcPath', 'src_path',
|
|
5
|
+
'dstPath', 'dst_path', 'oldPath', 'old_path', 'newPath', 'new_path',
|
|
6
|
+
'sourcePath', 'source_path', 'targetPath', 'target_path',
|
|
7
|
+
]);
|
|
8
|
+
/** 优先从 DSH 原生 Session 事件读取,原生事件不可用时回退到 JSONL。 */
|
|
9
|
+
export async function readSessionChangedFiles(services, sessionId, workspaceRoot) {
|
|
10
|
+
let session = services.nativeSessions?.get(sessionId);
|
|
11
|
+
if (session === undefined && services.nativeSessions?.listRemote !== undefined) {
|
|
12
|
+
try {
|
|
13
|
+
const candidates = await services.nativeSessions.listRemote();
|
|
14
|
+
session = candidates.find((candidate) => sessionIdentity(candidate) === sessionId);
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
// 原生列表接口不可用时继续走 JSONL 降级。
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
const root = resolve(workspaceRoot);
|
|
21
|
+
const nativeEvents = snapshotEvents(session);
|
|
22
|
+
const nativePaths = extractToolPaths(nativeEvents, root);
|
|
23
|
+
if (nativePaths.size > 0)
|
|
24
|
+
return { paths: [...nativePaths].sort() };
|
|
25
|
+
const jsonlPath = findJsonlReference(session);
|
|
26
|
+
if (jsonlPath === undefined)
|
|
27
|
+
return { paths: [] };
|
|
28
|
+
try {
|
|
29
|
+
const content = await readFile(jsonlPath, 'utf8');
|
|
30
|
+
const events = content.split(/\r?\n/u).flatMap((line) => {
|
|
31
|
+
try {
|
|
32
|
+
const parsed = JSON.parse(line);
|
|
33
|
+
return [parsed];
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
return [];
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
return { paths: [...extractToolPaths(events, root)].sort() };
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
// JSONL 是降级数据源;文件不存在或不可读时保持可解释的空结果。
|
|
43
|
+
return { paths: [] };
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
function snapshotEvents(value) {
|
|
47
|
+
if (!isRecord(value))
|
|
48
|
+
return [];
|
|
49
|
+
if (typeof value.snapshotEvents === 'function') {
|
|
50
|
+
try {
|
|
51
|
+
const events = value.snapshotEvents();
|
|
52
|
+
if (Array.isArray(events))
|
|
53
|
+
return events;
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
// 单个会话损坏时继续尝试其内嵌事件数组。
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return Array.isArray(value.events) ? value.events : [];
|
|
60
|
+
}
|
|
61
|
+
function extractToolPaths(events, workspaceRoot) {
|
|
62
|
+
const paths = new Set();
|
|
63
|
+
for (const candidate of events) {
|
|
64
|
+
const event = isRecord(candidate) ? candidate : undefined;
|
|
65
|
+
if (event === undefined)
|
|
66
|
+
continue;
|
|
67
|
+
const data = isRecord(event.data) ? event.data : event;
|
|
68
|
+
if (event.type === 'tool/call') {
|
|
69
|
+
collectInputPaths(data.arguments, workspaceRoot, paths);
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
if (event.type === 'tool/result') {
|
|
73
|
+
collectInputPaths(data.meta, workspaceRoot, paths);
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
if (event.type !== 'assistant/message')
|
|
77
|
+
continue;
|
|
78
|
+
const message = isRecord(data.message) ? data.message : undefined;
|
|
79
|
+
const content = message?.content;
|
|
80
|
+
if (!Array.isArray(content))
|
|
81
|
+
continue;
|
|
82
|
+
for (const block of content) {
|
|
83
|
+
if (!isRecord(block) || block.type !== 'tool-call')
|
|
84
|
+
continue;
|
|
85
|
+
collectInputPaths(block.arguments, workspaceRoot, paths);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return paths;
|
|
89
|
+
}
|
|
90
|
+
function collectInputPaths(value, workspaceRoot, paths) {
|
|
91
|
+
if (typeof value !== 'string') {
|
|
92
|
+
if (Array.isArray(value)) {
|
|
93
|
+
for (const item of value)
|
|
94
|
+
collectInputPaths(item, workspaceRoot, paths);
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
if (isRecord(value)) {
|
|
98
|
+
for (const [key, nested] of Object.entries(value)) {
|
|
99
|
+
if (typeof nested === 'string' && PATH_KEYS.has(key))
|
|
100
|
+
addPath(nested, workspaceRoot, paths);
|
|
101
|
+
else
|
|
102
|
+
collectInputPaths(nested, workspaceRoot, paths);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
const trimmed = value.trim();
|
|
108
|
+
if (!trimmed.startsWith('{') && !trimmed.startsWith('[')) {
|
|
109
|
+
for (const line of trimmed.split(/\r?\n/u)) {
|
|
110
|
+
const match = /^\*\*\* (?:Update|Add|Delete) File:\s+(.+)$/u.exec(line)
|
|
111
|
+
?? /^\*\*\* Move to:\s+(.+)$/u.exec(line);
|
|
112
|
+
if (match?.[1] !== undefined)
|
|
113
|
+
addPath(match[1], workspaceRoot, paths);
|
|
114
|
+
}
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
try {
|
|
118
|
+
collectInputPaths(JSON.parse(trimmed), workspaceRoot, paths);
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
// 工具参数不是 JSON 时只使用 apply_patch 文本格式。
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
function addPath(value, workspaceRoot, paths) {
|
|
125
|
+
const trimmed = value.trim().replace(/^['"]+|['"]+$/gu, '');
|
|
126
|
+
if (trimmed === '' || trimmed === '.' || trimmed === './')
|
|
127
|
+
return;
|
|
128
|
+
const candidate = isAbsolute(trimmed) ? normalize(trimmed) : resolve(workspaceRoot, trimmed);
|
|
129
|
+
const relativePath = relative(workspaceRoot, candidate).replaceAll('\\', '/');
|
|
130
|
+
if (relativePath === '' || relativePath.startsWith('../') || isAbsolute(relativePath))
|
|
131
|
+
return;
|
|
132
|
+
paths.add(relativePath.replace(/^\.\//u, ''));
|
|
133
|
+
}
|
|
134
|
+
function findJsonlReference(value, depth = 0) {
|
|
135
|
+
if (depth > 5 || !isRecord(value))
|
|
136
|
+
return undefined;
|
|
137
|
+
for (const key of ['rawStoreRef', 'jsonlPath', 'sessionPath', 'filePath']) {
|
|
138
|
+
const candidate = value[key];
|
|
139
|
+
if (typeof candidate === 'string' && /\.jsonl(?:\.zstd)?$/u.test(candidate.trim()))
|
|
140
|
+
return candidate.trim();
|
|
141
|
+
}
|
|
142
|
+
for (const nested of Object.values(value)) {
|
|
143
|
+
const result = findJsonlReference(nested, depth + 1);
|
|
144
|
+
if (result !== undefined)
|
|
145
|
+
return result;
|
|
146
|
+
}
|
|
147
|
+
return undefined;
|
|
148
|
+
}
|
|
149
|
+
function sessionIdentity(value) {
|
|
150
|
+
if (!isRecord(value))
|
|
151
|
+
return undefined;
|
|
152
|
+
for (const key of ['sessionId', 'id']) {
|
|
153
|
+
const candidate = value[key];
|
|
154
|
+
if (typeof candidate === 'string' && candidate.trim() !== '')
|
|
155
|
+
return candidate.trim();
|
|
156
|
+
}
|
|
157
|
+
const header = value.header;
|
|
158
|
+
return isRecord(header) && typeof header.id === 'string' ? header.id.trim() : undefined;
|
|
159
|
+
}
|
|
160
|
+
function isRecord(value) {
|
|
161
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
162
|
+
}
|
|
163
|
+
//# sourceMappingURL=session-changes.js.map
|
|
@@ -60,6 +60,7 @@ export const CodingNsSettingsSchema = z.object({
|
|
|
60
60
|
hiddenWorkspaceIds: z.array(z.string().min(1).max(512)).default(DEFAULT_CODINGNS_SETTINGS.workspaceSessionEnhancement.hiddenWorkspaceIds),
|
|
61
61
|
showSubscriptionUsage: z.boolean().default(DEFAULT_CODINGNS_SETTINGS.workspaceSessionEnhancement.showSubscriptionUsage),
|
|
62
62
|
showQuickPhrases: z.boolean().default(DEFAULT_CODINGNS_SETTINGS.workspaceSessionEnhancement.showQuickPhrases),
|
|
63
|
+
rememberConversationRightbarRatio: z.boolean().default(DEFAULT_CODINGNS_SETTINGS.workspaceSessionEnhancement.rememberConversationRightbarRatio),
|
|
63
64
|
quickPhrases: z.array(z.object({
|
|
64
65
|
id: z.string().min(1).max(128),
|
|
65
66
|
text: z.string().min(1).max(4000),
|
|
@@ -67,6 +68,11 @@ export const CodingNsSettingsSchema = z.object({
|
|
|
67
68
|
// 缺少该字段说明是旧配置;Client 首次加载时会补齐内置快捷会话。
|
|
68
69
|
quickPhrasesSeeded: z.boolean().default(false),
|
|
69
70
|
}).default(DEFAULT_CODINGNS_SETTINGS.workspaceSessionEnhancement),
|
|
71
|
+
fileManagement: z.object({
|
|
72
|
+
menuEnhancement: z.boolean().default(DEFAULT_CODINGNS_SETTINGS.fileManagement.menuEnhancement),
|
|
73
|
+
fileEditor: z.boolean().default(DEFAULT_CODINGNS_SETTINGS.fileManagement.fileEditor),
|
|
74
|
+
sessionChangedFiles: z.boolean().default(DEFAULT_CODINGNS_SETTINGS.fileManagement.sessionChangedFiles),
|
|
75
|
+
}).default(DEFAULT_CODINGNS_SETTINGS.fileManagement),
|
|
70
76
|
});
|
|
71
77
|
/**
|
|
72
78
|
* DSH 0.1.7 只会把 `volatile` 配置投影成可编辑 ConfigForm。
|
|
@@ -20,7 +20,7 @@ export { createHttpDshH5ControlApi, startDshH5BrowserBootstrap } from './client/
|
|
|
20
20
|
export type { DshH5BrowserBootstrapOptions, DshH5BrowserBootstrapResult, DshH5BrowserControlApi } from './client/dsh-h5-bootstrap.js';
|
|
21
21
|
export { CODINGNS_RPC_CHANNEL } from './shared/contracts/transport.js';
|
|
22
22
|
export { CODINGNS4DSH_DEBUG_ENV, debugInfo, debugWarn, resolveCodingNsDebugEnabled, } from './shared/debug.js';
|
|
23
|
-
export { CODINGNS_CONTROL_BASE_URL_FIELD, CODINGNS_CONTROL_BASE_URLS_FIELD, CODINGNS_LAN_ACCESS_DSH_FIELD, CODINGNS_MODULES_FIELD, CODINGNS_SETTINGS_NAMESPACE, DEFAULT_CODINGNS_CONTROL_BASE_URL, DEFAULT_CODINGNS_CONTROL_BASE_URLS, DEFAULT_CODINGNS_SETTINGS, enabledFeatureNames, isFeatureEnabled, } from './shared/contracts/config.js';
|
|
23
|
+
export { CODINGNS_CONTROL_BASE_URL_FIELD, CODINGNS_CONTROL_BASE_URLS_FIELD, CODINGNS_LAN_ACCESS_DSH_FIELD, CODINGNS_FILE_MANAGEMENT_FIELD, CODINGNS_MODULES_FIELD, CODINGNS_SETTINGS_NAMESPACE, DEFAULT_CODINGNS_CONTROL_BASE_URL, DEFAULT_CODINGNS_CONTROL_BASE_URLS, DEFAULT_CODINGNS_SETTINGS, DEFAULT_FILE_MANAGEMENT_SETTINGS, enabledFeatureNames, isFeatureEnabled, } from './shared/contracts/config.js';
|
|
24
24
|
export type * from './shared/index.js';
|
|
25
25
|
export * from './dsh-capabilities/index.js';
|
|
26
26
|
export { dispatchCodingNsRpc, type CodingNsRpcContext, type CodingNsRpcDispatchResult } from './dsh-capabilities/host/connection-rpc-adapter.js';
|
package/data/build/dist/index.js
CHANGED
|
@@ -18,7 +18,7 @@ export { RemoteDshWebContext } from './client/remote-web-context.js';
|
|
|
18
18
|
export { createHttpDshH5ControlApi, startDshH5BrowserBootstrap } from './client/dsh-h5-bootstrap.js';
|
|
19
19
|
export { CODINGNS_RPC_CHANNEL } from './shared/contracts/transport.js';
|
|
20
20
|
export { CODINGNS4DSH_DEBUG_ENV, debugInfo, debugWarn, resolveCodingNsDebugEnabled, } from './shared/debug.js';
|
|
21
|
-
export { CODINGNS_CONTROL_BASE_URL_FIELD, CODINGNS_CONTROL_BASE_URLS_FIELD, CODINGNS_LAN_ACCESS_DSH_FIELD, CODINGNS_MODULES_FIELD, CODINGNS_SETTINGS_NAMESPACE, DEFAULT_CODINGNS_CONTROL_BASE_URL, DEFAULT_CODINGNS_CONTROL_BASE_URLS, DEFAULT_CODINGNS_SETTINGS, enabledFeatureNames, isFeatureEnabled, } from './shared/contracts/config.js';
|
|
21
|
+
export { CODINGNS_CONTROL_BASE_URL_FIELD, CODINGNS_CONTROL_BASE_URLS_FIELD, CODINGNS_LAN_ACCESS_DSH_FIELD, CODINGNS_FILE_MANAGEMENT_FIELD, CODINGNS_MODULES_FIELD, CODINGNS_SETTINGS_NAMESPACE, DEFAULT_CODINGNS_CONTROL_BASE_URL, DEFAULT_CODINGNS_CONTROL_BASE_URLS, DEFAULT_CODINGNS_SETTINGS, DEFAULT_FILE_MANAGEMENT_SETTINGS, enabledFeatureNames, isFeatureEnabled, } from './shared/contracts/config.js';
|
|
22
22
|
export * from './dsh-capabilities/index.js';
|
|
23
23
|
export { dispatchCodingNsRpc } from './dsh-capabilities/host/connection-rpc-adapter.js';
|
|
24
24
|
export { FeatureRegistry, FeatureRegistryError, FeatureResourceScopeImpl, } from './features/registry.js';
|