@jingyi0605/codingns4dsh 0.1.0 → 0.1.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.en.md +306 -0
- package/README.md +190 -993
- package/data/build/dist/client/account-bar.d.ts +2 -2
- package/data/build/dist/client/account-bar.js +96 -39
- package/data/build/dist/client/bundle.js +13722 -3611
- package/data/build/dist/client/cli-catalog.js +20 -3
- package/data/build/dist/client/cli-slots.d.ts +5 -0
- package/data/build/dist/client/cli-slots.js +57 -7
- package/data/build/dist/client/debug/ui.d.ts +1 -1
- package/data/build/dist/client/debug/ui.js +62 -32
- package/data/build/dist/client/dsh-runtime-version.d.ts +9 -2
- package/data/build/dist/client/dsh-runtime-version.js +24 -2
- package/data/build/dist/client/features/cli-adapters.d.ts +1 -1
- package/data/build/dist/client/features/cli-adapters.js +19 -16
- package/data/build/dist/client/features/debug.js +2 -2
- package/data/build/dist/client/features/index.d.ts +2 -1
- package/data/build/dist/client/features/index.js +3 -1
- package/data/build/dist/client/features/lan-access-panel.d.ts +1 -1
- package/data/build/dist/client/features/lan-access-panel.js +8 -10
- package/data/build/dist/client/features/lan-access.js +1 -1
- package/data/build/dist/client/features/login-protection-panel.d.ts +1 -1
- package/data/build/dist/client/features/login-protection-panel.js +7 -9
- package/data/build/dist/client/features/reverse-proxy-panel.d.ts +1 -1
- package/data/build/dist/client/features/reverse-proxy-panel.js +99 -11
- package/data/build/dist/client/features/reverse-proxy.d.ts +1 -1
- package/data/build/dist/client/features/reverse-proxy.js +19 -18
- package/data/build/dist/client/features/terminal-enhancement-panel.d.ts +1 -1
- package/data/build/dist/client/features/terminal-enhancement-panel.js +62 -55
- package/data/build/dist/client/features/terminal-enhancement.d.ts +1 -1
- package/data/build/dist/client/features/terminal-enhancement.js +3 -3
- package/data/build/dist/client/features/types.d.ts +14 -3
- package/data/build/dist/client/features/workspace-session-enhancement-panel.d.ts +1 -1
- package/data/build/dist/client/features/workspace-session-enhancement-panel.js +31 -9
- package/data/build/dist/client/features/workspace-session-enhancement.js +72 -11
- package/data/build/dist/client/git-management.d.ts +16 -0
- package/data/build/dist/client/git-management.js +757 -0
- package/data/build/dist/client/index.d.ts +3 -2
- package/data/build/dist/client/index.js +152 -27
- package/data/build/dist/client/locale.js +91 -29
- package/data/build/dist/client/quick-phrase-layout.d.ts +49 -0
- package/data/build/dist/client/quick-phrase-layout.js +95 -0
- package/data/build/dist/client/quick-phrase-slot.d.ts +7 -0
- package/data/build/dist/client/quick-phrase-slot.js +370 -0
- package/data/build/dist/client/remote-web-context.js +1 -1
- package/data/build/dist/client/settings-bridge.d.ts +9 -6
- package/data/build/dist/client/settings-bridge.js +51 -27
- package/data/build/dist/client/settings-section.d.ts +3 -2
- package/data/build/dist/client/settings-section.js +33 -19
- package/data/build/dist/client/subscription-slot.d.ts +3 -0
- package/data/build/dist/client/subscription-slot.js +108 -16
- package/data/build/dist/client/terminal/model.d.ts +14 -2
- package/data/build/dist/client/terminal/model.js +109 -21
- package/data/build/dist/client/terminal/recovery.d.ts +50 -0
- package/data/build/dist/client/terminal/recovery.js +101 -0
- package/data/build/dist/client/terminal/ui.d.ts +2 -2
- package/data/build/dist/client/terminal/ui.js +49 -11
- package/data/build/dist/client/terminal/xterm-view.d.ts +2 -2
- package/data/build/dist/client/terminal/xterm-view.js +2 -1
- package/data/build/dist/client/theme.d.ts +6 -1
- package/data/build/dist/client/theme.js +32 -1
- package/data/build/dist/client/workspace-session-archive-dom.d.ts +12 -0
- package/data/build/dist/client/workspace-session-archive-dom.js +27 -5
- package/data/build/dist/client/workspace-session-visibility-dom.d.ts +30 -0
- package/data/build/dist/client/workspace-session-visibility-dom.js +604 -0
- package/data/build/dist/dsh-capabilities/client/config-forms-adapter.d.ts +50 -0
- package/data/build/dist/dsh-capabilities/client/config-forms-adapter.js +139 -0
- package/data/build/dist/dsh-capabilities/client/conversation-adapter.d.ts +7 -0
- package/data/build/dist/dsh-capabilities/client/conversation-adapter.js +6 -0
- package/data/build/dist/dsh-capabilities/client/locale-adapter.d.ts +9 -0
- package/data/build/dist/dsh-capabilities/client/locale-adapter.js +4 -0
- package/data/build/dist/dsh-capabilities/client/primitives-adapter.d.ts +10 -0
- package/data/build/dist/dsh-capabilities/client/primitives-adapter.js +14 -0
- package/data/build/dist/dsh-capabilities/client/settings-scope-adapter.d.ts +8 -0
- package/data/build/dist/dsh-capabilities/client/settings-scope-adapter.js +16 -0
- package/data/build/dist/dsh-capabilities/client/sidebar-adapter.d.ts +7 -0
- package/data/build/dist/dsh-capabilities/client/sidebar-adapter.js +5 -0
- package/data/build/dist/dsh-capabilities/client/theme-adapter.d.ts +6 -0
- package/data/build/dist/dsh-capabilities/client/theme-adapter.js +4 -0
- package/data/build/dist/dsh-capabilities/client/typert-adapter.d.ts +5 -0
- package/data/build/dist/dsh-capabilities/client/typert-adapter.js +4 -0
- package/data/build/dist/dsh-capabilities/host/config-forms-adapter.d.ts +19 -0
- package/data/build/dist/dsh-capabilities/host/config-forms-adapter.js +45 -0
- package/data/build/dist/dsh-capabilities/host/connection-rpc-adapter.d.ts +19 -0
- package/data/build/dist/dsh-capabilities/host/connection-rpc-adapter.js +13 -0
- package/data/build/dist/dsh-capabilities/host/settings-scope-adapter.d.ts +8 -0
- package/data/build/dist/dsh-capabilities/host/settings-scope-adapter.js +47 -0
- package/data/build/dist/dsh-capabilities/host/typert-adapter.d.ts +6 -0
- package/data/build/dist/dsh-capabilities/host/typert-adapter.js +4 -0
- package/data/build/dist/dsh-capabilities/index.d.ts +6 -0
- package/data/build/dist/dsh-capabilities/index.js +6 -0
- package/data/build/dist/dsh-capabilities/matrix.d.ts +15 -0
- package/data/build/dist/dsh-capabilities/matrix.js +32 -0
- package/data/build/dist/dsh-capabilities/registry.d.ts +22 -0
- package/data/build/dist/dsh-capabilities/registry.js +196 -0
- package/data/build/dist/dsh-capabilities/routes.d.ts +10 -0
- package/data/build/dist/dsh-capabilities/routes.js +34 -0
- package/data/build/dist/dsh-capabilities/settings-store.d.ts +29 -0
- package/data/build/dist/dsh-capabilities/settings-store.js +5 -0
- package/data/build/dist/dsh-capabilities/types.d.ts +50 -0
- package/data/build/dist/dsh-capabilities/types.js +23 -0
- package/data/build/dist/features/registry.d.ts +8 -2
- package/data/build/dist/features/registry.js +104 -1
- package/data/build/dist/host/auth-session.d.ts +8 -1
- package/data/build/dist/host/auth-session.js +28 -6
- package/data/build/dist/host/cli-adapters/claude-driver.d.ts +2 -0
- package/data/build/dist/host/cli-adapters/claude-driver.js +19 -4
- package/data/build/dist/host/cli-adapters/claude-model-options.d.ts +14 -0
- package/data/build/dist/host/cli-adapters/claude-model-options.js +157 -0
- package/data/build/dist/host/cli-adapters/codex-driver.d.ts +11 -0
- package/data/build/dist/host/cli-adapters/codex-driver.js +166 -14
- package/data/build/dist/host/cli-adapters/driver.d.ts +2 -0
- package/data/build/dist/host/cli-adapters/dsh-message-projector.d.ts +15 -0
- package/data/build/dist/host/cli-adapters/dsh-message-projector.js +120 -29
- package/data/build/dist/host/cli-adapters/dsh-tool-history.d.ts +4 -1
- package/data/build/dist/host/cli-adapters/dsh-tool-history.js +25 -7
- package/data/build/dist/host/cli-adapters/feature.js +74 -8
- package/data/build/dist/host/cli-adapters/gemini-driver.js +2 -2
- package/data/build/dist/host/cli-adapters/grok-driver.js +2 -2
- package/data/build/dist/host/cli-adapters/json-rpc-process.d.ts +4 -2
- package/data/build/dist/host/cli-adapters/json-rpc-process.js +8 -9
- package/data/build/dist/host/cli-adapters/kimi-driver.js +1 -1
- package/data/build/dist/host/cli-adapters/legacy-session-adapter.d.ts +17 -0
- package/data/build/dist/host/cli-adapters/legacy-session-adapter.js +88 -0
- package/data/build/dist/host/cli-adapters/legacy-session-settings.d.ts +24 -0
- package/data/build/dist/host/cli-adapters/legacy-session-settings.js +162 -0
- package/data/build/dist/host/cli-adapters/official-provider-subscription.d.ts +29 -0
- package/data/build/dist/host/cli-adapters/official-provider-subscription.js +361 -0
- package/data/build/dist/host/cli-adapters/opencode-driver.d.ts +2 -0
- package/data/build/dist/host/cli-adapters/opencode-driver.js +97 -12
- package/data/build/dist/host/cli-adapters/pi-driver.js +69 -23
- package/data/build/dist/host/cli-adapters/provider-registry.d.ts +33 -0
- package/data/build/dist/host/cli-adapters/provider-registry.js +83 -0
- package/data/build/dist/host/cli-adapters/provider-subscription.d.ts +25 -3
- package/data/build/dist/host/cli-adapters/provider-subscription.js +346 -30
- package/data/build/dist/host/cli-adapters/registry.d.ts +6 -0
- package/data/build/dist/host/cli-adapters/registry.js +170 -13
- package/data/build/dist/host/cli-adapters/rpc-driver-utils.js +10 -0
- package/data/build/dist/host/cli-adapters/session-store.d.ts +7 -0
- package/data/build/dist/host/cli-adapters/session-store.js +39 -1
- package/data/build/dist/host/cli-adapters/standard-stream-driver.d.ts +3 -0
- package/data/build/dist/host/cli-adapters/stream-normalizer.d.ts +3 -0
- package/data/build/dist/host/cli-adapters/stream-normalizer.js +22 -2
- package/data/build/dist/host/control-api-client.d.ts +3 -3
- package/data/build/dist/host/control-api-client.js +2 -1
- package/data/build/dist/host/credential-store.js +11 -1
- package/data/build/dist/host/dsh-device-runtime.d.ts +4 -0
- package/data/build/dist/host/dsh-device-runtime.js +20 -9
- package/data/build/dist/host/features/auth.js +8 -5
- package/data/build/dist/host/features/debug.js +1 -1
- package/data/build/dist/host/features/git-management.d.ts +5 -0
- package/data/build/dist/host/features/git-management.js +290 -0
- package/data/build/dist/host/features/host-status.js +1 -1
- package/data/build/dist/host/features/index.d.ts +1 -0
- package/data/build/dist/host/features/index.js +3 -0
- package/data/build/dist/host/features/terminal-process.js +1 -1
- package/data/build/dist/host/features/terminal-status.d.ts +3 -1
- package/data/build/dist/host/features/terminal-status.js +3 -1
- package/data/build/dist/host/index.d.ts +7 -3
- package/data/build/dist/host/index.js +76 -11
- package/data/build/dist/host/lan-access-dsh.js +18 -5
- package/data/build/dist/host/native-session-bridge.d.ts +23 -1
- package/data/build/dist/host/native-session-bridge.js +157 -10
- package/data/build/dist/host/rpc-table.d.ts +1 -1
- package/data/build/dist/host/rpc.js +60 -10
- package/data/build/dist/host/session-migration-repair.d.ts +19 -0
- package/data/build/dist/host/session-migration-repair.js +395 -0
- package/data/build/dist/host/settings.d.ts +8 -1
- package/data/build/dist/host/settings.js +94 -3
- package/data/build/dist/host/terminal/backends/tmux-backend.d.ts +1 -0
- package/data/build/dist/host/terminal/backends/tmux-backend.js +4 -2
- package/data/build/dist/host/terminal/controller-factory.d.ts +4 -0
- package/data/build/dist/host/terminal/controller-factory.js +26 -7
- package/data/build/dist/host/terminal/runtime-manager.d.ts +2 -1
- package/data/build/dist/host/terminal/runtime-manager.js +3 -0
- package/data/build/dist/host/terminal/startup.d.ts +2 -0
- package/data/build/dist/host/terminal/startup.js +2 -1
- package/data/build/dist/host/terminal/terminal-controller.d.ts +10 -3
- package/data/build/dist/host/terminal/terminal-controller.js +101 -15
- package/data/build/dist/host/terminal/terminal-process-service.js +3 -1
- package/data/build/dist/host/terminal/terminal-service.d.ts +2 -0
- package/data/build/dist/host/terminal/terminal-service.js +10 -0
- package/data/build/dist/index.d.ts +6 -2
- package/data/build/dist/index.js +8 -2
- package/data/build/dist/shared/contracts/cli-adapter.d.ts +14 -0
- package/data/build/dist/shared/contracts/config.d.ts +31 -1
- package/data/build/dist/shared/contracts/config.js +25 -0
- package/data/build/dist/shared/contracts/dsh-device.d.ts +13 -1
- package/data/build/dist/shared/contracts/errors.d.ts +1 -1
- package/data/build/dist/shared/contracts/feature.d.ts +6 -0
- package/data/build/dist/shared/contracts/git.d.ts +82 -0
- package/data/build/dist/shared/contracts/git.js +3 -0
- package/data/build/dist/shared/contracts/subscription.d.ts +46 -0
- package/data/build/dist/shared/contracts/terminal.d.ts +4 -1
- package/data/build/dist/shared/contracts/version.d.ts +2 -2
- package/data/build/dist/shared/contracts/version.js +4 -6
- package/data/build/dist/shared/debug.d.ts +14 -0
- package/data/build/dist/shared/debug.js +53 -0
- package/data/build/dist/shared/index.d.ts +7 -4
- package/data/build/dist/shared/index.js +2 -1
- package/data/build/dist/transport/debug.d.ts +1 -1
- package/data/build/dist/transport/debug.js +3 -30
- package/data/build/dist/transport/dsh-session.js +3 -3
- package/data/build/dist/typert.host.js +4 -2
- package/data/build/dist/typert.remote-client.d.ts +11 -0
- package/data/build/dist/typert.remote-client.js +7 -0
- package/dsh.bundle.patch +1 -1
- package/package.json +17 -5
- package/profile/README.md +4 -4
- package/profile/package.json +6 -4
- package/profile/scripts/check-dsh-install.mjs +2 -2
- package/profile/version.json +2 -2
- package/scripts/check-dsh-install.mjs +2 -2
- package/version.json +2 -2
|
@@ -10,10 +10,15 @@ export class CodingNsDshMessageProjector {
|
|
|
10
10
|
options;
|
|
11
11
|
normalizer = new CodingNsAgentEventNormalizer();
|
|
12
12
|
toolHistory;
|
|
13
|
+
reasoningIndex = 0;
|
|
14
|
+
textIndex = 1;
|
|
15
|
+
nextBlockIndex = 2;
|
|
16
|
+
reasoningText = '';
|
|
17
|
+
textText = '';
|
|
13
18
|
finished = false;
|
|
14
19
|
constructor(options) {
|
|
15
20
|
this.options = options;
|
|
16
|
-
this.toolHistory = new CodingNsDshToolHistoryProjector(options.nativeSessions, options.sessionId);
|
|
21
|
+
this.toolHistory = new CodingNsDshToolHistoryProjector(options.nativeSessions, options.sessionId, options.adapterId);
|
|
17
22
|
}
|
|
18
23
|
get isFinished() {
|
|
19
24
|
return this.finished;
|
|
@@ -21,6 +26,8 @@ export class CodingNsDshMessageProjector {
|
|
|
21
26
|
async push(event) {
|
|
22
27
|
if (this.finished)
|
|
23
28
|
return [];
|
|
29
|
+
if (event.type === 'usage')
|
|
30
|
+
this.recordUsageSample(event);
|
|
24
31
|
const projected = [];
|
|
25
32
|
for (const normalized of this.normalizer.push(event)) {
|
|
26
33
|
projected.push(...await this.project(normalized));
|
|
@@ -44,7 +51,7 @@ export class CodingNsDshMessageProjector {
|
|
|
44
51
|
const projected = await this.flushUsage();
|
|
45
52
|
const reason = cancelled ? 'cancel' : 'error';
|
|
46
53
|
if (!cancelled) {
|
|
47
|
-
projected.push({ type: 'text-delta',
|
|
54
|
+
projected.push(...await this.project({ type: 'text-delta', text: formatExecutionFailure(this.options.adapterId, message) }));
|
|
48
55
|
}
|
|
49
56
|
projected.push(...await this.project({ type: 'finish', reason }, message));
|
|
50
57
|
return projected;
|
|
@@ -55,14 +62,55 @@ export class CodingNsDshMessageProjector {
|
|
|
55
62
|
projected.push(...await this.project(event));
|
|
56
63
|
return projected;
|
|
57
64
|
}
|
|
65
|
+
/** Provider 的 usage 到达时立即给 token-meter 一个非 surface 采样点。
|
|
66
|
+
*
|
|
67
|
+
* DSH 规范要求正式 usage 仍随 assistant/message 在 finish 前结算,因此这里不
|
|
68
|
+
* 提前向 LLM 流发送第二个 usage,只写入 assistant/attempt 供上下文计量投影使用。
|
|
69
|
+
*/
|
|
70
|
+
recordUsageSample(event) {
|
|
71
|
+
const usage = {
|
|
72
|
+
inputTokens: event.inputTokens,
|
|
73
|
+
outputTokens: event.outputTokens,
|
|
74
|
+
...(event.cacheReadTokens === undefined ? {} : { cacheReadTokens: event.cacheReadTokens }),
|
|
75
|
+
...(event.cacheWriteTokens === undefined ? {} : { cacheWriteTokens: event.cacheWriteTokens }),
|
|
76
|
+
...(event.uncachedInputTokens === undefined ? {} : { uncachedInputTokens: event.uncachedInputTokens }),
|
|
77
|
+
...(event.totalTokens === undefined ? {} : { totalTokens: event.totalTokens }),
|
|
78
|
+
...(event.cacheHitRate === undefined ? {} : { cacheHitRate: event.cacheHitRate }),
|
|
79
|
+
...(event.contextWindow === undefined ? {} : { contextWindow: event.contextWindow }),
|
|
80
|
+
...(event.contextTokens === undefined ? {} : { contextTokens: event.contextTokens }),
|
|
81
|
+
...(event.contextUsageRatio === undefined ? {} : { contextUsageRatio: event.contextUsageRatio }),
|
|
82
|
+
};
|
|
83
|
+
if (event.contextWindow !== undefined) {
|
|
84
|
+
this.options.nativeSessions?.appendRequestContext?.(this.options.sessionId, {
|
|
85
|
+
provider: this.options.adapterId,
|
|
86
|
+
model: this.options.modelId ?? this.options.adapterId,
|
|
87
|
+
contextWindow: event.contextWindow,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
this.options.nativeSessions?.appendUsageSample?.(this.options.sessionId, usage);
|
|
91
|
+
}
|
|
58
92
|
async project(event, failureMessage) {
|
|
59
93
|
switch (event.type) {
|
|
60
94
|
case 'reasoning-delta':
|
|
61
|
-
|
|
95
|
+
if (event.text === '')
|
|
96
|
+
return [];
|
|
97
|
+
return this.appendDelta('reasoning', event.text);
|
|
62
98
|
case 'text-delta':
|
|
63
|
-
|
|
99
|
+
if (event.text === '')
|
|
100
|
+
return [];
|
|
101
|
+
return this.appendDelta('text', event.text);
|
|
102
|
+
case 'message-boundary':
|
|
103
|
+
return this.closeMessageBlock(event.channel);
|
|
104
|
+
case 'step-boundary':
|
|
105
|
+
// DSH 0.1.7 的 Chat 分组器会把同一 Turn 中没有可见 assistant
|
|
106
|
+
// 回复的连续工具节点合并到一个 process group。Codex 的工具已经
|
|
107
|
+
// 在外部进程完成,分段之间没有 DSH 原生 assistant 文本可供分组器
|
|
108
|
+
// 识别,因此写入一个 Markdown 引用定义作为不可见的回复边界。
|
|
109
|
+
// 必须从新行开始;DSH UI 会忽略 definition 节点,而不是把 HTML 当注释解析。
|
|
110
|
+
// 该内容不会显示给用户,也不会改变工具的原生 step 坐标。
|
|
111
|
+
return this.appendDelta('text', '\n\n[//]: # (codingns-step-boundary)');
|
|
64
112
|
case 'tool-event':
|
|
65
|
-
return externalToolChunk(this.toolHistory.observe(event));
|
|
113
|
+
return this.externalToolChunk(this.toolHistory.observe(event));
|
|
66
114
|
case 'permission-request':
|
|
67
115
|
await this.requestPermission(event);
|
|
68
116
|
return [];
|
|
@@ -70,13 +118,6 @@ export class CodingNsDshMessageProjector {
|
|
|
70
118
|
await this.requestQuestions(event);
|
|
71
119
|
return [];
|
|
72
120
|
case 'usage':
|
|
73
|
-
if (event.contextWindow !== undefined) {
|
|
74
|
-
this.options.nativeSessions?.appendRequestContext?.(this.options.sessionId, {
|
|
75
|
-
provider: this.options.adapterId,
|
|
76
|
-
model: this.options.modelId ?? this.options.adapterId,
|
|
77
|
-
contextWindow: event.contextWindow,
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
121
|
return [{
|
|
81
122
|
type: 'usage',
|
|
82
123
|
usage: {
|
|
@@ -95,11 +136,77 @@ export class CodingNsDshMessageProjector {
|
|
|
95
136
|
case 'session-binding':
|
|
96
137
|
return [];
|
|
97
138
|
case 'finish':
|
|
139
|
+
const closed = [
|
|
140
|
+
...this.closeMessageBlock('reasoning'),
|
|
141
|
+
...this.closeMessageBlock('text'),
|
|
142
|
+
];
|
|
98
143
|
this.finished = true;
|
|
99
144
|
this.toolHistory.finalize(event.reason, failureMessage);
|
|
100
|
-
|
|
145
|
+
closed.push({ type: 'finish', reason: toDshFinishReason(event.reason, failureMessage) });
|
|
146
|
+
return closed;
|
|
101
147
|
}
|
|
102
148
|
}
|
|
149
|
+
appendDelta(channel, text) {
|
|
150
|
+
const opened = channel === 'reasoning' ? this.reasoningText === '' : this.textText === '';
|
|
151
|
+
const index = this.openBlock(channel);
|
|
152
|
+
if (channel === 'reasoning')
|
|
153
|
+
this.reasoningText += text;
|
|
154
|
+
else
|
|
155
|
+
this.textText += text;
|
|
156
|
+
const delta = { type: `${channel}-delta`, index, text };
|
|
157
|
+
return opened ? [{ type: 'block-start', index, blockType: channel }, delta] : [delta];
|
|
158
|
+
}
|
|
159
|
+
openBlock(channel) {
|
|
160
|
+
const current = channel === 'reasoning' ? this.reasoningIndex : this.textIndex;
|
|
161
|
+
if (current !== undefined)
|
|
162
|
+
return current;
|
|
163
|
+
const index = this.nextBlockIndex;
|
|
164
|
+
this.nextBlockIndex += 1;
|
|
165
|
+
if (channel === 'reasoning')
|
|
166
|
+
this.reasoningIndex = index;
|
|
167
|
+
else
|
|
168
|
+
this.textIndex = index;
|
|
169
|
+
return index;
|
|
170
|
+
}
|
|
171
|
+
closeMessageBlock(channel) {
|
|
172
|
+
if (channel === 'reasoning') {
|
|
173
|
+
if (this.reasoningText === '')
|
|
174
|
+
return [];
|
|
175
|
+
const index = this.reasoningIndex;
|
|
176
|
+
if (index === undefined)
|
|
177
|
+
return [];
|
|
178
|
+
const chunk = { type: 'block-end', index, block: { type: 'reasoning', text: this.reasoningText } };
|
|
179
|
+
this.reasoningText = '';
|
|
180
|
+
this.reasoningIndex = undefined;
|
|
181
|
+
return [chunk];
|
|
182
|
+
}
|
|
183
|
+
if (this.textText === '')
|
|
184
|
+
return [];
|
|
185
|
+
const index = this.textIndex;
|
|
186
|
+
if (index === undefined)
|
|
187
|
+
return [];
|
|
188
|
+
const chunk = { type: 'block-end', index, block: { type: 'text', text: this.textText } };
|
|
189
|
+
this.textText = '';
|
|
190
|
+
this.textIndex = undefined;
|
|
191
|
+
return [chunk];
|
|
192
|
+
}
|
|
193
|
+
externalToolChunk(marker) {
|
|
194
|
+
if (marker === null)
|
|
195
|
+
return [];
|
|
196
|
+
const index = this.nextBlockIndex;
|
|
197
|
+
this.nextBlockIndex += 1;
|
|
198
|
+
return [
|
|
199
|
+
{ type: 'block-start', index, blockType: 'reasoning' },
|
|
200
|
+
{
|
|
201
|
+
type: 'reasoning-delta',
|
|
202
|
+
index,
|
|
203
|
+
// 空 delta 会被 DSH 的流式聚合器丢弃,空格能保留 live-chunk 但不会显示思考正文。
|
|
204
|
+
text: ' ',
|
|
205
|
+
codingnsExternalTool: marker,
|
|
206
|
+
},
|
|
207
|
+
{ type: 'block-end', index, block: { type: 'reasoning', text: ' ' } },
|
|
208
|
+
];
|
|
209
|
+
}
|
|
103
210
|
async requestPermission(event) {
|
|
104
211
|
const responder = this.options.respondPermission;
|
|
105
212
|
if (responder === undefined)
|
|
@@ -129,22 +236,6 @@ export class CodingNsDshMessageProjector {
|
|
|
129
236
|
await responder(response);
|
|
130
237
|
}
|
|
131
238
|
}
|
|
132
|
-
/**
|
|
133
|
-
* 没有 DSH 原生 Session 时的工具展示回退:使用空白 reasoning chunk 携带私有标记,
|
|
134
|
-
* 只让 Client 的实时 Conversation 投影读取,不会再次执行工具。完整 Host 直接使用
|
|
135
|
-
* 原生 tool/call 与 tool/result,不经过这里。
|
|
136
|
-
*/
|
|
137
|
-
function externalToolChunk(marker) {
|
|
138
|
-
if (marker === null)
|
|
139
|
-
return [];
|
|
140
|
-
return [{
|
|
141
|
-
type: 'reasoning-delta',
|
|
142
|
-
index: 0,
|
|
143
|
-
// 空 delta 会被 DSH 的流式聚合器丢弃,空格能保留 live-chunk 但不会显示思考正文。
|
|
144
|
-
text: ' ',
|
|
145
|
-
codingnsExternalTool: marker,
|
|
146
|
-
}];
|
|
147
|
-
}
|
|
148
239
|
function toDshFinishReason(reason, failureMessage) {
|
|
149
240
|
if (reason === 'cancel') {
|
|
150
241
|
return { kind: 'aborted', failure: { message: failureMessage ?? '外部 Agent 执行已取消', code: 'ABORTED' } };
|
|
@@ -10,6 +10,7 @@ export interface CodingNsDshExternalToolMarker {
|
|
|
10
10
|
readonly status: 'running' | 'completed' | 'failed';
|
|
11
11
|
readonly output?: string;
|
|
12
12
|
readonly error?: string;
|
|
13
|
+
readonly adapterId?: string;
|
|
13
14
|
}
|
|
14
15
|
/**
|
|
15
16
|
* 所有外部 Agent 共用的 DSH 工具历史投影器。
|
|
@@ -20,6 +21,7 @@ export interface CodingNsDshExternalToolMarker {
|
|
|
20
21
|
export declare class CodingNsDshToolHistoryProjector {
|
|
21
22
|
private readonly nativeSessions;
|
|
22
23
|
private readonly sessionId;
|
|
24
|
+
private readonly adapterId?;
|
|
23
25
|
private readonly records;
|
|
24
26
|
private readonly deferNativeAppend;
|
|
25
27
|
private readonly removeNativeEventListener;
|
|
@@ -28,7 +30,7 @@ export declare class CodingNsDshToolHistoryProjector {
|
|
|
28
30
|
private observedCalls;
|
|
29
31
|
private finalized;
|
|
30
32
|
private flushScheduled;
|
|
31
|
-
constructor(nativeSessions: CodingNsNativeSessionBridge | undefined, sessionId: string);
|
|
33
|
+
constructor(nativeSessions: CodingNsNativeSessionBridge | undefined, sessionId: string, adapterId?: string | undefined);
|
|
32
34
|
observe(event: CodingNsAgentToolEvent): CodingNsDshExternalToolMarker | null;
|
|
33
35
|
/** 流结束时补齐 Provider 遗漏的终态,避免原生组件永久停留在运行中。 */
|
|
34
36
|
finalize(reason: 'stop' | 'cancel' | 'error', failure?: string): void;
|
|
@@ -36,6 +38,7 @@ export declare class CodingNsDshToolHistoryProjector {
|
|
|
36
38
|
private settle;
|
|
37
39
|
/** 按 Provider 到达顺序把工具调用和结果写入当前 DSH step。 */
|
|
38
40
|
private flushNativeRecords;
|
|
41
|
+
private hasPendingNativeRecords;
|
|
39
42
|
private persistNativeRecord;
|
|
40
43
|
private scheduleFlush;
|
|
41
44
|
/** 活动 step 晚于首个工具通知时,补写尚未进入 Session 的工具标记。 */
|
|
@@ -12,6 +12,7 @@ const TRUNCATION_MARKER = '\n...[内容因长度限制已截断]';
|
|
|
12
12
|
export class CodingNsDshToolHistoryProjector {
|
|
13
13
|
nativeSessions;
|
|
14
14
|
sessionId;
|
|
15
|
+
adapterId;
|
|
15
16
|
records = new Map();
|
|
16
17
|
deferNativeAppend;
|
|
17
18
|
removeNativeEventListener;
|
|
@@ -20,12 +21,13 @@ export class CodingNsDshToolHistoryProjector {
|
|
|
20
21
|
observedCalls = 0;
|
|
21
22
|
finalized = false;
|
|
22
23
|
flushScheduled = false;
|
|
23
|
-
constructor(nativeSessions, sessionId) {
|
|
24
|
+
constructor(nativeSessions, sessionId, adapterId) {
|
|
24
25
|
this.nativeSessions = nativeSessions;
|
|
25
26
|
this.sessionId = sessionId;
|
|
26
|
-
|
|
27
|
-
//
|
|
28
|
-
// assistant/
|
|
27
|
+
this.adapterId = adapterId;
|
|
28
|
+
// 工具通知必须在当前 llm/stream 结束前写入原生时间线。若把它延迟到
|
|
29
|
+
// assistant/message 结算之后,最后一条事件会变成带 tool-call 的合成 assistant,
|
|
30
|
+
// DSH 会把整步判定为 process,最终正文也会被收进折叠按钮。
|
|
29
31
|
const subscribe = nativeSessions?.supportsEvents === true ? nativeSessions.subscribe : undefined;
|
|
30
32
|
this.deferNativeAppend = nativeSessions?.appendToolCall === undefined && nativeSessions?.appendExternalToolEvent === undefined && subscribe !== undefined;
|
|
31
33
|
this.removeNativeEventListener = subscribe?.call(nativeSessions, {
|
|
@@ -93,6 +95,7 @@ export class CodingNsDshToolHistoryProjector {
|
|
|
93
95
|
name: normalized.name,
|
|
94
96
|
arguments: normalized.arguments,
|
|
95
97
|
status,
|
|
98
|
+
...(this.adapterId === undefined ? {} : { adapterId: this.adapterId }),
|
|
96
99
|
...(record.output === undefined ? {} : { output: record.output }),
|
|
97
100
|
...(record.error === undefined ? {} : { error: record.error }),
|
|
98
101
|
};
|
|
@@ -125,7 +128,6 @@ export class CodingNsDshToolHistoryProjector {
|
|
|
125
128
|
}
|
|
126
129
|
if (this.nativeSessions?.appendToolCall !== undefined) {
|
|
127
130
|
this.flushNativeRecords();
|
|
128
|
-
this.removeNativeEventListener?.();
|
|
129
131
|
}
|
|
130
132
|
else if (this.nativeSessions?.appendExternalToolEvent !== undefined) {
|
|
131
133
|
this.flushExternalMarkers();
|
|
@@ -160,9 +162,16 @@ export class CodingNsDshToolHistoryProjector {
|
|
|
160
162
|
return;
|
|
161
163
|
for (const record of this.records.values())
|
|
162
164
|
this.persistNativeRecord(record);
|
|
163
|
-
if (this.finalized)
|
|
165
|
+
if (this.finalized && !this.hasPendingNativeRecords())
|
|
164
166
|
this.removeNativeEventListener?.();
|
|
165
167
|
}
|
|
168
|
+
hasPendingNativeRecords() {
|
|
169
|
+
for (const record of this.records.values()) {
|
|
170
|
+
if (record.handle === null || record.settled && !record.resultAppended)
|
|
171
|
+
return true;
|
|
172
|
+
}
|
|
173
|
+
return false;
|
|
174
|
+
}
|
|
166
175
|
persistNativeRecord(record) {
|
|
167
176
|
const append = this.nativeSessions?.appendToolCall;
|
|
168
177
|
if (append === undefined || this.sessionId.trim() === '')
|
|
@@ -221,7 +230,15 @@ export class CodingNsDshToolHistoryProjector {
|
|
|
221
230
|
if (!record.externalPersisted) {
|
|
222
231
|
const start = marker.phase === 'start'
|
|
223
232
|
? marker
|
|
224
|
-
: {
|
|
233
|
+
: {
|
|
234
|
+
source: marker.source,
|
|
235
|
+
phase: 'start',
|
|
236
|
+
callId: marker.callId,
|
|
237
|
+
name: marker.name,
|
|
238
|
+
arguments: marker.arguments,
|
|
239
|
+
status: 'running',
|
|
240
|
+
...(this.adapterId === undefined ? {} : { adapterId: this.adapterId }),
|
|
241
|
+
};
|
|
225
242
|
try {
|
|
226
243
|
if (!append.call(this.nativeSessions, this.sessionId, start))
|
|
227
244
|
return false;
|
|
@@ -250,6 +267,7 @@ export class CodingNsDshToolHistoryProjector {
|
|
|
250
267
|
callId: record.callId,
|
|
251
268
|
name: normalized.name,
|
|
252
269
|
arguments: normalized.arguments,
|
|
270
|
+
...(this.adapterId === undefined ? {} : { adapterId: this.adapterId }),
|
|
253
271
|
});
|
|
254
272
|
}
|
|
255
273
|
catch {
|
|
@@ -15,7 +15,7 @@ export function createCliAdaptersFeature(options = {}) {
|
|
|
15
15
|
return {
|
|
16
16
|
descriptor: {
|
|
17
17
|
name: 'cliAdapters',
|
|
18
|
-
version: '0.1.
|
|
18
|
+
version: '0.1.1',
|
|
19
19
|
enabledByDefault: true,
|
|
20
20
|
dependencies: [],
|
|
21
21
|
runtime: 'host',
|
|
@@ -24,6 +24,13 @@ export function createCliAdaptersFeature(options = {}) {
|
|
|
24
24
|
const commandCodeSubscription = new CommandCodeSubscriptionService();
|
|
25
25
|
const subscriptions = new ProviderSubscriptionService({ commandCode: commandCodeSubscription });
|
|
26
26
|
const sessionStore = new CodingNsCliSessionStore(context.services.settings === undefined ? {} : { settings: context.services.settings });
|
|
27
|
+
const nativeSessions = context.services.nativeSessions;
|
|
28
|
+
if (nativeSessions !== undefined) {
|
|
29
|
+
const migration = sessionStore.migrateLegacySessions(nativeSessions.list());
|
|
30
|
+
if (migration.migrated > 0 || migration.unresolved > 0) {
|
|
31
|
+
console.info('codingns4dsh: 旧外部会话适配器迁移完成', migration);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
27
34
|
const registry = options.registry ?? new CodingNsCliAdapterRegistry([
|
|
28
35
|
new CommandCodeDriver(),
|
|
29
36
|
new ClaudeCodeDriver(),
|
|
@@ -40,7 +47,6 @@ export function createCliAdaptersFeature(options = {}) {
|
|
|
40
47
|
});
|
|
41
48
|
registry.applyEnabledSettings(context.services.settings?.get().agentAdapters);
|
|
42
49
|
registry.warmCatalog();
|
|
43
|
-
const nativeSessions = context.services.nativeSessions;
|
|
44
50
|
if (nativeSessions !== undefined) {
|
|
45
51
|
const disposeNativeEvents = nativeSessions.subscribe({
|
|
46
52
|
onEvent: (session, event) => {
|
|
@@ -48,6 +54,10 @@ export function createCliAdaptersFeature(options = {}) {
|
|
|
48
54
|
const eventType = nativeEventType(event);
|
|
49
55
|
if (sessionId === undefined || eventType === undefined)
|
|
50
56
|
return;
|
|
57
|
+
// 旧会话可能不在启动时的 SessionStore.list() 中,直到用户点击
|
|
58
|
+
// 侧栏才加载。加载事件本身携带完整快照,此时补做一次迁移。
|
|
59
|
+
if (sessionStore.get(sessionId) === undefined)
|
|
60
|
+
sessionStore.migrateLegacySessions([session]);
|
|
51
61
|
const current = sessionStore.get(sessionId);
|
|
52
62
|
if (current === undefined || current.status === 'archived')
|
|
53
63
|
return;
|
|
@@ -69,12 +79,20 @@ export function createCliAdaptersFeature(options = {}) {
|
|
|
69
79
|
case 'session/get': return registry.getSession(readSessionId(payload));
|
|
70
80
|
case 'session/set': return registry.setSession(readSessionId(payload), readSessionConfig(payload));
|
|
71
81
|
case 'session/list': return registry.listSessions(readSessionListOptions(payload));
|
|
72
|
-
case 'session/adapter-map':
|
|
82
|
+
case 'session/adapter-map':
|
|
83
|
+
// DSH 历史会话的 seed 事件不会发布 session/event;每次读取映射时
|
|
84
|
+
// 重新检查当前已加载对象,覆盖“用户刚点击打开旧会话”的路径。
|
|
85
|
+
if (nativeSessions !== undefined)
|
|
86
|
+
sessionStore.migrateLegacySessions(nativeSessions.list());
|
|
87
|
+
return sessionStore.adapterBindings();
|
|
73
88
|
case 'session/archive': return registry.archiveSession(readSessionId(payload));
|
|
74
89
|
case 'session/steer': return registry.steer(readSessionId(payload), readPrompt(payload), false);
|
|
75
90
|
case 'session/follow-up': return registry.steer(readSessionId(payload), readPrompt(payload), true);
|
|
76
91
|
case 'session/interrupt': return registry.interrupt(readSessionId(payload));
|
|
77
|
-
case 'subscription':
|
|
92
|
+
case 'subscription': {
|
|
93
|
+
const subscription = readSubscriptionRequest(payload);
|
|
94
|
+
return subscriptions.read(subscription.adapterId, subscription.providerId);
|
|
95
|
+
}
|
|
78
96
|
default: throw new Error(`未知 CLI RPC: cli/${action}`);
|
|
79
97
|
}
|
|
80
98
|
}));
|
|
@@ -106,6 +124,9 @@ export function createCliAdaptersFeature(options = {}) {
|
|
|
106
124
|
}
|
|
107
125
|
const messages = Array.isArray(value?.messages) ? value.messages.filter(isMessage) : [];
|
|
108
126
|
const cwd = resolveSessionCwd(context.services.nativeSessions, sessionId, value);
|
|
127
|
+
// 只有 Provider 驱动明确维护了稳定的 turn 分段,才把工具边界映射为 DSH step。
|
|
128
|
+
// OpenCode、Command Code 会在同一轮连续产出工具和 usage,强行切 step 会让
|
|
129
|
+
// token-meter 在下一条 usage 到达前失去投影,表现为上下文组件反复卸载。
|
|
109
130
|
const input = {
|
|
110
131
|
sessionId,
|
|
111
132
|
messages,
|
|
@@ -116,6 +137,13 @@ export function createCliAdaptersFeature(options = {}) {
|
|
|
116
137
|
...(config.rawStoreRef ? { rawStoreRef: config.rawStoreRef } : {}),
|
|
117
138
|
...(cwd === undefined ? {} : { cwd }),
|
|
118
139
|
...(isAbortSignal(value?.signal) ? { signal: value.signal } : {}),
|
|
140
|
+
...(registry.supportsSegmentedTurns(config.adapterId)
|
|
141
|
+
&& nativeSessions?.available === true
|
|
142
|
+
&& nativeSessions.injectNextStep !== undefined
|
|
143
|
+
&& (nativeSessions.canInjectNextStep === undefined
|
|
144
|
+
|| nativeSessions.canInjectNextStep(sessionId))
|
|
145
|
+
? { splitToolSteps: true }
|
|
146
|
+
: {}),
|
|
119
147
|
};
|
|
120
148
|
const projector = new CodingNsDshMessageProjector({
|
|
121
149
|
adapterId: config.adapterId,
|
|
@@ -126,8 +154,25 @@ export function createCliAdaptersFeature(options = {}) {
|
|
|
126
154
|
respondPermission: (response) => registry.respondPermission(sessionId, response),
|
|
127
155
|
respondQuestion: (response) => registry.respondQuestion(sessionId, response),
|
|
128
156
|
});
|
|
157
|
+
const discardSuspendedTurn = () => registry.discardSegmentedTurn(sessionId);
|
|
158
|
+
input.signal?.addEventListener('abort', discardSuspendedTurn, { once: true });
|
|
159
|
+
if (input.signal?.aborted)
|
|
160
|
+
discardSuspendedTurn();
|
|
129
161
|
try {
|
|
130
162
|
for await (const chunk of registry.execute({ ...input, adapterId: config.adapterId })) {
|
|
163
|
+
if (chunk.type === 'step-boundary') {
|
|
164
|
+
// Agent Loop 会在本次 llm/stream 返回后关闭当前 step,并在返回前
|
|
165
|
+
// 检查 next-step inbox。必须先注入,再发送 finish,不能等 complete()
|
|
166
|
+
// 之后再写入,否则 DSH 已经把整个 turn 结算完了。
|
|
167
|
+
const injected = nativeSessions?.available === true
|
|
168
|
+
? nativeSessions.injectNextStep?.(sessionId) ?? false
|
|
169
|
+
: false;
|
|
170
|
+
if (!injected)
|
|
171
|
+
discardSuspendedTurn();
|
|
172
|
+
for (const dshChunk of await projector.push(chunk))
|
|
173
|
+
yield dshChunk;
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
131
176
|
for (const dshChunk of await projector.push(chunk))
|
|
132
177
|
yield dshChunk;
|
|
133
178
|
// DSH 要求 finish 是唯一且最后一个 chunk。这里 return 也会关闭上游迭代器。
|
|
@@ -143,6 +188,9 @@ export function createCliAdaptersFeature(options = {}) {
|
|
|
143
188
|
for (const dshChunk of await projector.fail(message, input.signal?.aborted ?? false))
|
|
144
189
|
yield dshChunk;
|
|
145
190
|
}
|
|
191
|
+
finally {
|
|
192
|
+
input.signal?.removeEventListener('abort', discardSuspendedTurn);
|
|
193
|
+
}
|
|
146
194
|
});
|
|
147
195
|
if (typeof dispose === 'function')
|
|
148
196
|
context.resources.add(() => { dispose(); });
|
|
@@ -157,11 +205,15 @@ function readAdapterId(value) {
|
|
|
157
205
|
throw new Error('adapterId 不能为空');
|
|
158
206
|
return record.adapterId.trim();
|
|
159
207
|
}
|
|
160
|
-
function
|
|
208
|
+
function readSubscriptionRequest(value) {
|
|
161
209
|
const record = asRecord(value);
|
|
162
210
|
if (record === null || record.adapterId === undefined)
|
|
163
|
-
return 'command-code';
|
|
164
|
-
|
|
211
|
+
return { adapterId: 'command-code' };
|
|
212
|
+
const adapterId = readAdapterId(value);
|
|
213
|
+
return {
|
|
214
|
+
adapterId,
|
|
215
|
+
...(typeof record.providerId === 'string' && record.providerId.trim() !== '' ? { providerId: record.providerId.trim() } : {}),
|
|
216
|
+
};
|
|
165
217
|
}
|
|
166
218
|
function readSessionId(value) {
|
|
167
219
|
const record = asRecord(value);
|
|
@@ -176,6 +228,7 @@ function readSessionConfig(value) {
|
|
|
176
228
|
adapterId,
|
|
177
229
|
...(typeof record?.modelId === 'string' && record.modelId.trim() ? { modelId: record.modelId.trim() } : {}),
|
|
178
230
|
...(typeof record?.effortId === 'string' && record.effortId.trim() ? { effortId: record.effortId.trim() } : {}),
|
|
231
|
+
...(typeof record?.providerId === 'string' && record.providerId.trim() ? { providerId: record.providerId.trim() } : {}),
|
|
179
232
|
...(typeof record?.providerSessionId === 'string' && record.providerSessionId.trim() ? { providerSessionId: record.providerSessionId.trim() } : {}),
|
|
180
233
|
};
|
|
181
234
|
}
|
|
@@ -215,15 +268,17 @@ function readDshSelection(value) {
|
|
|
215
268
|
};
|
|
216
269
|
const modelId = read(['model', 'modelId']);
|
|
217
270
|
const effortId = read(['reasoningEffort', 'effortId', 'thinking']);
|
|
271
|
+
const providerId = read(['provider', 'providerId', 'providerName']);
|
|
218
272
|
return {
|
|
219
273
|
...(modelId === undefined ? {} : { modelId }),
|
|
220
274
|
...(effortId === undefined ? {} : { effortId }),
|
|
275
|
+
...(providerId === undefined ? {} : { providerId }),
|
|
221
276
|
};
|
|
222
277
|
}
|
|
223
278
|
/** DSH Session 快照把最近选择放在 modelSelection.lastUsed/next。 */
|
|
224
279
|
function readModelSelectionCandidates(value) {
|
|
225
280
|
const result = [];
|
|
226
|
-
for (const candidate of [value, asRecord(value?.request), asRecord(value?.config), asRecord(value?.header)]) {
|
|
281
|
+
for (const candidate of [value, asRecord(value?.request), asRecord(value?.config), asRecord(value?.header), asRecord(asRecord(value?.record)?.rows)]) {
|
|
227
282
|
const selection = asRecord(candidate?.modelSelection);
|
|
228
283
|
const lastUsed = asRecord(selection?.lastUsed);
|
|
229
284
|
const next = asRecord(selection?.next);
|
|
@@ -247,11 +302,22 @@ async function setAdapterEnabled(settings, registry, value) {
|
|
|
247
302
|
function extractPrompt(messages) {
|
|
248
303
|
for (let index = messages.length - 1; index >= 0; index -= 1) {
|
|
249
304
|
const message = messages[index];
|
|
305
|
+
if (message !== undefined && isInjectedStepNotice(message))
|
|
306
|
+
return extractText(message.content);
|
|
250
307
|
if (message !== undefined && isHumanUserMessage(message))
|
|
251
308
|
return extractText(message.content);
|
|
252
309
|
}
|
|
253
310
|
return '';
|
|
254
311
|
}
|
|
312
|
+
/** DSH 为工具分段注入的继续提示必须成为下一次 Provider 请求的 prompt。 */
|
|
313
|
+
function isInjectedStepNotice(message) {
|
|
314
|
+
if (message.role !== 'user' || !isRecord(message.source))
|
|
315
|
+
return false;
|
|
316
|
+
if (message.source.form !== 'notice')
|
|
317
|
+
return false;
|
|
318
|
+
return message.source.kind === 'model-selection'
|
|
319
|
+
|| message.source.kind === 'plugin' && message.source.plugin === 'codingns4dsh';
|
|
320
|
+
}
|
|
255
321
|
function isHumanUserMessage(message) {
|
|
256
322
|
if (message.role !== 'user')
|
|
257
323
|
return false;
|
|
@@ -25,7 +25,7 @@ export class GeminiCliDriver extends StandardStreamDriver {
|
|
|
25
25
|
try {
|
|
26
26
|
await rpc.request('initialize', {
|
|
27
27
|
protocolVersion: 1,
|
|
28
|
-
clientInfo: { name: 'codingns4dsh', version: '0.1.
|
|
28
|
+
clientInfo: { name: 'codingns4dsh', version: '0.1.1' },
|
|
29
29
|
clientCapabilities: {},
|
|
30
30
|
}, { signal: controller.signal });
|
|
31
31
|
const session = await rpc.request('session/new', {
|
|
@@ -128,7 +128,7 @@ export class GeminiCliDriver extends StandardStreamDriver {
|
|
|
128
128
|
try {
|
|
129
129
|
await rpc.request('initialize', {
|
|
130
130
|
protocolVersion: 1,
|
|
131
|
-
clientInfo: { name: 'codingns4dsh', version: '0.1.
|
|
131
|
+
clientInfo: { name: 'codingns4dsh', version: '0.1.1' },
|
|
132
132
|
clientCapabilities: {},
|
|
133
133
|
}, { signal: input.signal });
|
|
134
134
|
rpc.notify('initialized', {});
|
|
@@ -34,7 +34,7 @@ export class GrokBuildDriver {
|
|
|
34
34
|
return emptyCatalog();
|
|
35
35
|
const rpc = new JsonRpcProcess({ command, args: ['agent', '--no-leader', 'stdio'], spawn: this.runSpawn });
|
|
36
36
|
try {
|
|
37
|
-
await rpc.request('initialize', { protocolVersion: 1, clientInfo: { name: 'codingns4dsh', version: '0.1.
|
|
37
|
+
await rpc.request('initialize', { protocolVersion: 1, clientInfo: { name: 'codingns4dsh', version: '0.1.1' }, capabilities: {} });
|
|
38
38
|
rpc.notify('initialized', {});
|
|
39
39
|
const session = await rpc.request('session/new', { cwd: process.cwd(), mcpServers: [] });
|
|
40
40
|
const parsed = parseGrokCatalog(session);
|
|
@@ -126,7 +126,7 @@ export class GrokBuildDriver {
|
|
|
126
126
|
const state = { rpc, cwd: input.cwd, providerSessionId: '', requests: new Map() };
|
|
127
127
|
await rpc.request('initialize', {
|
|
128
128
|
protocolVersion: 1,
|
|
129
|
-
clientInfo: { name: 'codingns4dsh', version: '0.1.
|
|
129
|
+
clientInfo: { name: 'codingns4dsh', version: '0.1.1' },
|
|
130
130
|
capabilities: {},
|
|
131
131
|
});
|
|
132
132
|
rpc.notify('initialized', {});
|
|
@@ -25,6 +25,8 @@ export interface JsonRpcRequestOptions {
|
|
|
25
25
|
readonly onNotification?: (message: JsonRpcMessage) => void;
|
|
26
26
|
/** 取消本次请求时是否同时终止整个 Agent 进程;长期会话应关闭此项。 */
|
|
27
27
|
readonly killOnAbort?: boolean;
|
|
28
|
+
/** Pi 使用 type/data 顶层命令,不是 JSON-RPC method/params。 */
|
|
29
|
+
readonly wireFormat?: 'jsonrpc' | 'pi';
|
|
28
30
|
}
|
|
29
31
|
/**
|
|
30
32
|
* 统一管理 stdio JSON-RPC 子进程:请求编号、逐行解码、取消和退出清理都在这里完成。
|
|
@@ -43,8 +45,8 @@ export declare class JsonRpcProcess {
|
|
|
43
45
|
private serverRequestHandler;
|
|
44
46
|
constructor(options: JsonRpcProcessOptions);
|
|
45
47
|
request(method: string, params?: unknown, options?: JsonRpcRequestOptions): Promise<unknown>;
|
|
46
|
-
/**
|
|
47
|
-
notify(method: string, params?: unknown): void;
|
|
48
|
+
/** 发送无需响应的协议通知,例如 initialized 或 cancel。 */
|
|
49
|
+
notify(method: string, params?: unknown, wireFormat?: 'jsonrpc' | 'pi'): void;
|
|
48
50
|
/** 注册 Agent 发起的 JSON-RPC 服务端请求处理器,例如 Codex 权限审批。 */
|
|
49
51
|
setServerRequestHandler(handler: ((message: JsonRpcMessage) => unknown | Promise<unknown>) | undefined): void;
|
|
50
52
|
/** 为一段流式请求注册独立监听器,响应先到时也不会提前移除。 */
|
|
@@ -40,14 +40,10 @@ export class JsonRpcProcess {
|
|
|
40
40
|
else
|
|
41
41
|
options.signal?.addEventListener('abort', onAbort, { once: true });
|
|
42
42
|
try {
|
|
43
|
-
|
|
44
|
-
// method,否则 Pi 会回报 “Unknown command: undefined”。其余适配器仍走标准 JSON-RPC。
|
|
45
|
-
if (method === 'get_available_models') {
|
|
43
|
+
if (options.wireFormat === 'pi')
|
|
46
44
|
this.write({ id, type: method, ...(isRecord(params) ? params : {}) });
|
|
47
|
-
|
|
48
|
-
else {
|
|
45
|
+
else
|
|
49
46
|
this.write({ jsonrpc: '2.0', id, method, params });
|
|
50
|
-
}
|
|
51
47
|
const result = await promise;
|
|
52
48
|
if (options.signal?.aborted)
|
|
53
49
|
throw new Error('请求已取消');
|
|
@@ -60,10 +56,13 @@ export class JsonRpcProcess {
|
|
|
60
56
|
this.pending.delete(id);
|
|
61
57
|
}
|
|
62
58
|
}
|
|
63
|
-
/**
|
|
64
|
-
notify(method, params = {}) {
|
|
59
|
+
/** 发送无需响应的协议通知,例如 initialized 或 cancel。 */
|
|
60
|
+
notify(method, params = {}, wireFormat = 'jsonrpc') {
|
|
65
61
|
this.ensureStarted();
|
|
66
|
-
|
|
62
|
+
if (wireFormat === 'pi')
|
|
63
|
+
this.write({ type: method, ...(isRecord(params) ? params : {}) });
|
|
64
|
+
else
|
|
65
|
+
this.write({ jsonrpc: '2.0', method, params });
|
|
67
66
|
}
|
|
68
67
|
/** 注册 Agent 发起的 JSON-RPC 服务端请求处理器,例如 Codex 权限审批。 */
|
|
69
68
|
setServerRequestHandler(handler) {
|
|
@@ -137,7 +137,7 @@ export class KimiCliDriver extends StandardStreamDriver {
|
|
|
137
137
|
method: 'initialize',
|
|
138
138
|
params: {
|
|
139
139
|
protocol_version: '1.10',
|
|
140
|
-
client: { name: 'codingns4dsh', version: '0.1.
|
|
140
|
+
client: { name: 'codingns4dsh', version: '0.1.1' },
|
|
141
141
|
capabilities: { supports_question: true },
|
|
142
142
|
},
|
|
143
143
|
})}\n`);
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { CodingNsCliAdapterId } from '../../shared/contracts/cli-adapter.js';
|
|
2
|
+
/** 当前插件注册的适配器;旧日志只能从这些稳定 ID 中选择,不能猜测任意品牌。 */
|
|
3
|
+
export declare const KNOWN_CLI_ADAPTER_IDS: Set<string>;
|
|
4
|
+
export interface LegacySessionAdapterEvidence {
|
|
5
|
+
readonly sessionId: string;
|
|
6
|
+
readonly adapterId?: CodingNsCliAdapterId;
|
|
7
|
+
readonly cwd?: string;
|
|
8
|
+
readonly createdAt?: string;
|
|
9
|
+
readonly external: boolean;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* 从 DSH 原生会话快照读取旧版外部 Agent 的适配器证据。
|
|
13
|
+
* `codingns-external` 只能证明消息来自外部 Agent;只有 source/provider 或
|
|
14
|
+
* request/context 中出现当前已知适配器 ID 时才回填,避免把 DSH 模型提供方误认成 CLI。
|
|
15
|
+
*/
|
|
16
|
+
export declare function inspectLegacySessionAdapter(value: unknown): LegacySessionAdapterEvidence | undefined;
|
|
17
|
+
//# sourceMappingURL=legacy-session-adapter.d.ts.map
|