dsh-connect 0.7.2 → 0.9.0
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 +196 -43
- package/README.zh.md +171 -42
- package/client/client.js +817 -0
- package/client/client.js.map +7 -0
- package/client/locale.mjs +227 -0
- package/client/panel-state.mjs +54 -0
- package/client/settings-client.mjs +389 -0
- package/docs/images/settings-advanced-en.png +0 -0
- package/docs/images/settings-advanced-zh.png +0 -0
- package/docs/images/settings-defaults-en.png +0 -0
- package/docs/images/settings-defaults-zh.png +0 -0
- package/docs/images/settings-overview-en.png +0 -0
- package/docs/images/settings-overview-zh.png +0 -0
- package/examples/minimal.config.json +16 -0
- package/lib/binding.d.ts.map +1 -1
- package/lib/binding.js +2 -2
- package/lib/binding.js.map +1 -1
- package/lib/channels/dingtalk/adapter.d.ts +59 -0
- package/lib/channels/dingtalk/adapter.d.ts.map +1 -0
- package/lib/channels/dingtalk/adapter.js +123 -0
- package/lib/channels/dingtalk/adapter.js.map +1 -0
- package/lib/channels/dingtalk/i18n.d.ts +14 -0
- package/lib/channels/dingtalk/i18n.d.ts.map +1 -0
- package/lib/channels/dingtalk/i18n.js +16 -0
- package/lib/channels/dingtalk/i18n.js.map +1 -0
- package/lib/channels/dingtalk/index.d.ts +127 -0
- package/lib/channels/dingtalk/index.d.ts.map +1 -0
- package/lib/channels/dingtalk/index.js +144 -0
- package/lib/channels/dingtalk/index.js.map +1 -0
- package/lib/channels/dingtalk/message.d.ts +49 -0
- package/lib/channels/dingtalk/message.d.ts.map +1 -0
- package/lib/channels/dingtalk/message.js +50 -0
- package/lib/channels/dingtalk/message.js.map +1 -0
- package/lib/channels/dingtalk/stomp.d.ts +36 -0
- package/lib/channels/dingtalk/stomp.d.ts.map +1 -0
- package/lib/channels/dingtalk/stomp.js +107 -0
- package/lib/channels/dingtalk/stomp.js.map +1 -0
- package/lib/channels/dingtalk/stream.d.ts +53 -0
- package/lib/channels/dingtalk/stream.d.ts.map +1 -0
- package/lib/channels/dingtalk/stream.js +199 -0
- package/lib/channels/dingtalk/stream.js.map +1 -0
- package/lib/channels/dingtalk/webhook.d.ts +84 -0
- package/lib/channels/dingtalk/webhook.d.ts.map +1 -0
- package/lib/channels/dingtalk/webhook.js +143 -0
- package/lib/channels/dingtalk/webhook.js.map +1 -0
- package/lib/channels/feishu/adapter.d.ts +133 -0
- package/lib/channels/feishu/adapter.d.ts.map +1 -0
- package/lib/channels/feishu/adapter.js +662 -0
- package/lib/channels/feishu/adapter.js.map +1 -0
- package/lib/channels/feishu/i18n.d.ts +30 -0
- package/lib/channels/feishu/i18n.d.ts.map +1 -0
- package/lib/channels/feishu/i18n.js +42 -0
- package/lib/channels/feishu/i18n.js.map +1 -0
- package/lib/channels/feishu/index.d.ts +82 -0
- package/lib/channels/feishu/index.d.ts.map +1 -0
- package/lib/channels/feishu/index.js +103 -0
- package/lib/channels/feishu/index.js.map +1 -0
- package/lib/channels/feishu/onboard.d.ts +16 -0
- package/lib/channels/feishu/onboard.d.ts.map +1 -0
- package/lib/channels/feishu/onboard.js +86 -0
- package/lib/channels/feishu/onboard.js.map +1 -0
- package/lib/channels/telegram/adapter.d.ts +70 -0
- package/lib/channels/telegram/adapter.d.ts.map +1 -0
- package/lib/channels/telegram/adapter.js +460 -0
- package/lib/channels/telegram/adapter.js.map +1 -0
- package/lib/channels/telegram/client.d.ts +115 -0
- package/lib/channels/telegram/client.d.ts.map +1 -0
- package/lib/channels/telegram/client.js +198 -0
- package/lib/channels/telegram/client.js.map +1 -0
- package/lib/channels/telegram/i18n.d.ts +14 -0
- package/lib/channels/telegram/i18n.d.ts.map +1 -0
- package/lib/channels/telegram/i18n.js +18 -0
- package/lib/channels/telegram/i18n.js.map +1 -0
- package/lib/channels/telegram/index.d.ts +46 -0
- package/lib/channels/telegram/index.d.ts.map +1 -0
- package/lib/channels/telegram/index.js +54 -0
- package/lib/channels/telegram/index.js.map +1 -0
- package/lib/channels/web/adapter.d.ts +103 -0
- package/lib/channels/web/adapter.d.ts.map +1 -0
- package/lib/channels/web/adapter.js +161 -0
- package/lib/channels/web/adapter.js.map +1 -0
- package/lib/channels/web/index.d.ts +47 -0
- package/lib/channels/web/index.d.ts.map +1 -0
- package/lib/channels/web/index.js +59 -0
- package/lib/channels/web/index.js.map +1 -0
- package/lib/chat-key.d.ts +29 -0
- package/lib/chat-key.d.ts.map +1 -0
- package/lib/chat-key.js +38 -0
- package/lib/chat-key.js.map +1 -0
- package/lib/index.d.ts +78 -11
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +312 -9
- package/lib/index.js.map +1 -1
- package/lib/runner.d.ts +55 -2
- package/lib/runner.d.ts.map +1 -1
- package/lib/runner.js +158 -23
- package/lib/runner.js.map +1 -1
- package/lib/scheduler.d.ts.map +1 -1
- package/lib/scheduler.js +2 -2
- package/lib/scheduler.js.map +1 -1
- package/lib/service.d.ts +17 -1
- package/lib/service.d.ts.map +1 -1
- package/lib/service.js +47 -3
- package/lib/service.js.map +1 -1
- package/lib/settings/channel-runtime.d.ts +75 -0
- package/lib/settings/channel-runtime.d.ts.map +1 -0
- package/lib/settings/channel-runtime.js +165 -0
- package/lib/settings/channel-runtime.js.map +1 -0
- package/lib/settings/channels.d.ts +62 -0
- package/lib/settings/channels.d.ts.map +1 -0
- package/lib/settings/channels.js +132 -0
- package/lib/settings/channels.js.map +1 -0
- package/lib/settings/credential-store.d.ts +85 -0
- package/lib/settings/credential-store.d.ts.map +1 -0
- package/lib/settings/credential-store.js +142 -0
- package/lib/settings/credential-store.js.map +1 -0
- package/lib/settings/index.d.ts +14 -0
- package/lib/settings/index.d.ts.map +1 -0
- package/lib/settings/index.js +14 -0
- package/lib/settings/index.js.map +1 -0
- package/lib/settings/namespace.d.ts +175 -0
- package/lib/settings/namespace.d.ts.map +1 -0
- package/lib/settings/namespace.js +200 -0
- package/lib/settings/namespace.js.map +1 -0
- package/lib/settings/rpc-client.d.ts +36 -0
- package/lib/settings/rpc-client.d.ts.map +1 -0
- package/lib/settings/rpc-client.js +45 -0
- package/lib/settings/rpc-client.js.map +1 -0
- package/lib/settings/secret-disclosure.d.ts +50 -0
- package/lib/settings/secret-disclosure.d.ts.map +1 -0
- package/lib/settings/secret-disclosure.js +132 -0
- package/lib/settings/secret-disclosure.js.map +1 -0
- package/lib/settings/settings-model.d.ts +124 -0
- package/lib/settings/settings-model.d.ts.map +1 -0
- package/lib/settings/settings-model.js +118 -0
- package/lib/settings/settings-model.js.map +1 -0
- package/lib/settings/settings-rpc.d.ts +130 -0
- package/lib/settings/settings-rpc.d.ts.map +1 -0
- package/lib/settings/settings-rpc.js +233 -0
- package/lib/settings/settings-rpc.js.map +1 -0
- package/lib/settings/settings-service.d.ts +35 -0
- package/lib/settings/settings-service.d.ts.map +1 -0
- package/lib/settings/settings-service.js +171 -0
- package/lib/settings/settings-service.js.map +1 -0
- package/lib/state-dir.d.ts +28 -0
- package/lib/state-dir.d.ts.map +1 -0
- package/lib/state-dir.js +33 -0
- package/lib/state-dir.js.map +1 -0
- package/lib/stream.d.ts.map +1 -1
- package/lib/stream.js +3 -2
- package/lib/stream.js.map +1 -1
- package/package.json +56 -12
package/lib/index.js
CHANGED
|
@@ -1,5 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `dsh-connect` — the single all-in-one plugin that bridges DeepSeek Harness to
|
|
3
|
+
* chat platforms. It bundles the channel-agnostic `connect` service (adapter
|
|
4
|
+
* registry, inbound routing, authorization, proactive notify), every channel
|
|
5
|
+
* adapter (Feishu/Lark, Telegram, DingTalk, Web mirror), and the web-settings
|
|
6
|
+
* stack (host RPC + credential store + settings pane) into one package.
|
|
7
|
+
*
|
|
8
|
+
* Install one plugin, write one `dsh-connect` config block, and enable exactly
|
|
9
|
+
* the channels you use via `channels`.
|
|
10
|
+
*
|
|
11
|
+
* @module dsh-connect
|
|
12
|
+
*/
|
|
13
|
+
import { join } from "node:path";
|
|
1
14
|
import z from "@deepseek-ai/schemastery";
|
|
2
15
|
import { ConnectService } from "./service.js";
|
|
16
|
+
import { resolveStateDir } from "./state-dir.js";
|
|
17
|
+
import { CHANNELS, extractConfigSecrets, injectSecrets, } from "./settings/channels.js";
|
|
18
|
+
import { ChannelRuntime } from "./settings/channel-runtime.js";
|
|
19
|
+
import { installConnectSection } from "./settings/namespace.js";
|
|
20
|
+
import { installSettingsRpc } from "./settings/settings-rpc.js";
|
|
21
|
+
import { createSettingsService } from "./settings/settings-service.js";
|
|
22
|
+
import { CHANNEL_CONFIG_FIELDS } from "./settings/settings-model.js";
|
|
23
|
+
import { CHANNEL_SECRET_KEYS, createCredentialStore, } from "./settings/credential-store.js";
|
|
24
|
+
import { register as feishuRegister, loadCredentials } from "./channels/feishu/index.js";
|
|
25
|
+
import { register as telegramRegister } from "./channels/telegram/index.js";
|
|
26
|
+
import { register as dingtalkRegister } from "./channels/dingtalk/index.js";
|
|
27
|
+
import { register as webRegister } from "./channels/web/index.js";
|
|
3
28
|
export { ConnectService } from "./service.js";
|
|
4
29
|
export { AgentRunner, resolveConnectConfig } from "./runner.js";
|
|
5
30
|
export { MenuController } from "./menu-controller.js";
|
|
@@ -14,11 +39,112 @@ export { acquire as acquireLock, canWrite as lockCanWrite, isLockTimedOut, relea
|
|
|
14
39
|
export { ReminderStore, formatRemindAt, parseRemindTime } from "./scheduler.js";
|
|
15
40
|
export { parseCommand, helpText } from "./commands.js";
|
|
16
41
|
export { messages } from "./i18n.js";
|
|
42
|
+
// Channel adapters (exposed as namespaces so each channel's Config/apply/register
|
|
43
|
+
// never collide with the merged plugin's own top-level exports).
|
|
44
|
+
export * as feishu from "./channels/feishu/index.js";
|
|
45
|
+
export * as telegram from "./channels/telegram/index.js";
|
|
46
|
+
export * as dingtalk from "./channels/dingtalk/index.js";
|
|
47
|
+
export * as web from "./channels/web/index.js";
|
|
48
|
+
// Web-settings stack (host RPC + credential store + persistence + client model).
|
|
49
|
+
export * as settings from "./settings/index.js";
|
|
50
|
+
/**
|
|
51
|
+
* Backward-compat: on boot, seed the credential store from secrets a channel
|
|
52
|
+
* config already carries (e.g. `feishu.appId`/`appSecret` written into the
|
|
53
|
+
* profile before the web-settings pane existed). Keeps the pane's presence
|
|
54
|
+
* reporting honest — an upgraded user whose channels work via config-file
|
|
55
|
+
* secrets sees them as "已配置" instead of "未配置凭据".
|
|
56
|
+
*
|
|
57
|
+
* Non-destructive by design: a ref the store already holds is never re-written
|
|
58
|
+
* (pane-saved credentials always win), and only refs present in the config
|
|
59
|
+
* (non-empty string, at their real flat/nested location) are migrated. Secrets
|
|
60
|
+
* still never reach the settings state file — they only move into the store.
|
|
61
|
+
*/
|
|
62
|
+
async function seedCredentialRefs(provider, secretKeys, secrets) {
|
|
63
|
+
for (const [configKey, ref] of Object.entries(secretKeys)) {
|
|
64
|
+
const value = secrets[configKey];
|
|
65
|
+
if (value === undefined)
|
|
66
|
+
continue;
|
|
67
|
+
let alreadyConfigured = false;
|
|
68
|
+
try {
|
|
69
|
+
alreadyConfigured = (await provider.describe(ref)).configured === true;
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
alreadyConfigured = false;
|
|
73
|
+
}
|
|
74
|
+
if (alreadyConfigured)
|
|
75
|
+
continue;
|
|
76
|
+
try {
|
|
77
|
+
await provider.set(ref, value);
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
// Per-ref migration failure should never block activation.
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Fold credentials left behind by the legacy one-click onboarding file into the
|
|
86
|
+
* store. Feishu's onboarding predates the credential store and wrote its own
|
|
87
|
+
* JSON, which nothing but the adapter read — so a user who onboarded before the
|
|
88
|
+
* store existed had a working bot that the settings pane reported as
|
|
89
|
+
* 「未配置凭据」 forever. Migration is idempotent and never overwrites a value the
|
|
90
|
+
* store already holds.
|
|
91
|
+
*/
|
|
92
|
+
async function migrateOnboardedSecrets(provider, enabled) {
|
|
93
|
+
if (!enabled.includes("feishu"))
|
|
94
|
+
return;
|
|
95
|
+
let onboarded = null;
|
|
96
|
+
try {
|
|
97
|
+
onboarded = loadCredentials();
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
if (onboarded === null)
|
|
103
|
+
return;
|
|
104
|
+
await seedCredentialRefs(provider, CHANNEL_SECRET_KEYS.feishu, {
|
|
105
|
+
appId: onboarded.appId,
|
|
106
|
+
appSecret: onboarded.appSecret,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
async function migrateConfigSecrets(provider, cfg, enabled) {
|
|
110
|
+
for (const ch of enabled) {
|
|
111
|
+
const secretKeys = CHANNEL_SECRET_KEYS[ch] ?? {};
|
|
112
|
+
if (Object.keys(secretKeys).length === 0)
|
|
113
|
+
continue;
|
|
114
|
+
const raw = cfg[ch];
|
|
115
|
+
const secrets = extractConfigSecrets(raw, ch, secretKeys);
|
|
116
|
+
if (Object.keys(secrets).length === 0)
|
|
117
|
+
continue;
|
|
118
|
+
await seedCredentialRefs(provider, secretKeys, secrets);
|
|
119
|
+
}
|
|
120
|
+
await migrateOnboardedSecrets(provider, enabled);
|
|
121
|
+
}
|
|
17
122
|
/** Cordis plugin name used by loader diagnostics. */
|
|
18
123
|
export const name = "connect";
|
|
19
|
-
/**
|
|
20
|
-
|
|
21
|
-
|
|
124
|
+
/**
|
|
125
|
+
* Host-plane services this plugin must wait for before `apply` runs. All four
|
|
126
|
+
* are rows in the always-loaded `@deepseek-ai/dsh-base` bundle — the shared core
|
|
127
|
+
* of every base-backed profile — so requiring them cannot stall the plugin in
|
|
128
|
+
* any profile that can load `dsh-connect` at all.
|
|
129
|
+
*
|
|
130
|
+
* `credentials` must be listed here, not read lazily inside `apply`: a
|
|
131
|
+
* `ctx.get("credentials")` at apply time returns `undefined`, because this
|
|
132
|
+
* plugin activates before the credentials row does. That silently disabled the
|
|
133
|
+
* whole credential path — `migrateConfigSecrets` never seeded the store (so an
|
|
134
|
+
* upgraded user's working channels displayed "未配置凭据"), `injectSecrets`
|
|
135
|
+
* never merged store-backed secrets into a channel config, and
|
|
136
|
+
* `settings.saveCredentials` threw `not-configured` for every pane save. Note
|
|
137
|
+
* cordis v4 has no `?` optional-inject marker, so `"credentials?"` would be read
|
|
138
|
+
* as a required service literally named `"credentials?"` — that is a syntax
|
|
139
|
+
* hazard, not a reason the service itself is unavailable.
|
|
140
|
+
*/
|
|
141
|
+
export const inject = ["agents", "sessions", "agentDefaultModel", "credentials"];
|
|
142
|
+
/**
|
|
143
|
+
* Full plugin config: the channel-agnostic core fields plus the channel
|
|
144
|
+
* selector (`channels`), shared `channelDefaults`, per-channel config, and the
|
|
145
|
+
* web-settings state path. Each channel's own `Config` schema is also exported
|
|
146
|
+
* (as `feishu.Config`, etc.) for reference; the merged entry validates loosely.
|
|
147
|
+
*/
|
|
22
148
|
export const Config = z.object({
|
|
23
149
|
/** Agent preset id composed into each bound session; omit for the roster default. */
|
|
24
150
|
agentPreset: z.string(),
|
|
@@ -44,12 +170,189 @@ export const Config = z.object({
|
|
|
44
170
|
notifyLevel: z.union([z.const("full"), z.const("important"), z.const("result")]),
|
|
45
171
|
/** Proactive progress-notice interval ms when a turn stays silent (default: 300000 = 5 min; 0 disables). */
|
|
46
172
|
progressTimeoutMs: z.number(),
|
|
173
|
+
/** Channels to activate; default: all built-in channels. */
|
|
174
|
+
channels: z.array(z.union([z.const("feishu"), z.const("telegram"), z.const("dingtalk"), z.const("web")])),
|
|
175
|
+
/** Keys applied to every channel that doesn't set its own (e.g. a shared `language`). */
|
|
176
|
+
channelDefaults: z.any(),
|
|
177
|
+
feishu: z.any(),
|
|
178
|
+
telegram: z.any(),
|
|
179
|
+
dingtalk: z.any(),
|
|
180
|
+
web: z.any(),
|
|
181
|
+
/** Optional path to persist web-settings edits (non-secret). */
|
|
182
|
+
settingsStatePath: z.string(),
|
|
47
183
|
});
|
|
48
|
-
/**
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
184
|
+
/**
|
|
185
|
+
* Register the `connect` service and start the enabled channel adapters, then
|
|
186
|
+
* expose the web-settings RPC. `connect` is constructed first and passed *by
|
|
187
|
+
* instance* into each channel's `register` — never resolved via
|
|
188
|
+
* `ctx.get("connect")`, which returns undefined inside this plugin's own
|
|
189
|
+
* `apply` (the fiber is still LOADING until this function resolves).
|
|
190
|
+
*/
|
|
191
|
+
export async function apply(ctx, config = {}) {
|
|
192
|
+
// Shallow-clone so we never mutate the caller's config object. Only core
|
|
193
|
+
// fields are consumed by ConnectService; the rest are channel/settings.
|
|
194
|
+
const cfg = { ...(config ?? {}) };
|
|
195
|
+
const connect = new ConnectService(ctx, cfg);
|
|
196
|
+
// DSH credentials store: report presence + inject secrets into each channel
|
|
197
|
+
// config so store-backed secrets reach the adapter without the config file
|
|
198
|
+
// carrying them. `credentials` is a declared inject (see `inject` above), so
|
|
199
|
+
// it is guaranteed present by the time `apply` runs; the optional `ctx.get()`
|
|
200
|
+
// read is kept only so a bare context (unit tests) degrades to "no store"
|
|
201
|
+
// rather than throwing.
|
|
202
|
+
const credentialsProvider = ctx.get?.("credentials");
|
|
203
|
+
let credentialStore;
|
|
204
|
+
if (credentialsProvider) {
|
|
205
|
+
try {
|
|
206
|
+
credentialStore = createCredentialStore(credentialsProvider);
|
|
207
|
+
}
|
|
208
|
+
catch {
|
|
209
|
+
credentialStore = undefined;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
const wanted = cfg.channels ?? CHANNELS;
|
|
213
|
+
// Migrate config-file secrets into the store before activation, so an upgraded
|
|
214
|
+
// user's already-working channels report as configured (and the store becomes
|
|
215
|
+
// the single source of truth). Best-effort: never blocks the plugin load.
|
|
216
|
+
if (credentialStore && credentialsProvider) {
|
|
217
|
+
try {
|
|
218
|
+
await migrateConfigSecrets(credentialsProvider, cfg, wanted);
|
|
219
|
+
}
|
|
220
|
+
catch {
|
|
221
|
+
// Ignore a migration failure; activation continues with existing config.
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
const finalCfg = credentialStore
|
|
225
|
+
? await injectSecrets(cfg, wanted, (name) => credentialStore.get(name))
|
|
226
|
+
: cfg;
|
|
227
|
+
// Each channel's register receives the connect instance directly.
|
|
228
|
+
const channels = {
|
|
229
|
+
// Feishu additionally gets the credential store so a completed one-click
|
|
230
|
+
// onboarding lands in the DSH store (and not only in its own legacy file).
|
|
231
|
+
feishu: (_ctx, channelConfig) => feishuRegister(connect, channelConfig, _ctx, { credentialStore }),
|
|
232
|
+
telegram: (_ctx, channelConfig) => telegramRegister(connect, channelConfig, _ctx),
|
|
233
|
+
dingtalk: (_ctx, channelConfig) => dingtalkRegister(connect, channelConfig, _ctx),
|
|
234
|
+
web: (_ctx, channelConfig) => webRegister(connect, channelConfig, _ctx),
|
|
235
|
+
};
|
|
236
|
+
// Channel lifecycle is owned by a runtime, not a one-shot activation: once
|
|
237
|
+
// the channel list is user-editable, dropping a channel has to *stop* its
|
|
238
|
+
// adapter (a live Feishu long connection would otherwise outlive its config)
|
|
239
|
+
// and a reconfigured channel has to restart before the old transport is
|
|
240
|
+
// still delivering. See `settings/channel-runtime.ts`.
|
|
241
|
+
const runtime = new ChannelRuntime({
|
|
242
|
+
ctx,
|
|
243
|
+
channels,
|
|
244
|
+
teardown: (name) => connect.unregisterAdapter(name),
|
|
245
|
+
getSecrets: credentialStore ? (name) => credentialStore.get(name) : undefined,
|
|
246
|
+
});
|
|
247
|
+
await runtime.apply(finalCfg);
|
|
248
|
+
// Register the `dsh-connect` namespace so the channel selection and the
|
|
249
|
+
// per-channel non-secret options become user-editable and *effective*:
|
|
250
|
+
// `installSection` layers the plugin's own config (as `base`) under the
|
|
251
|
+
// user's `settings.yaml` section, and every change re-reconciles the running
|
|
252
|
+
// adapters through the runtime above. The panel's own RPC
|
|
253
|
+
// (`settings/settings-rpc.ts`) is a separate transport onto the same idea and
|
|
254
|
+
// is kept for the pane's compatibility path.
|
|
255
|
+
//
|
|
256
|
+
// Deferred through `inject` for the same reason as the RPC below: `settings`
|
|
257
|
+
// is a `dsh-base` row loaded after a user plugin's `apply` runs, so a plain
|
|
258
|
+
// optional read would see `undefined` and never register anything. If the
|
|
259
|
+
// host never provides it the callback never runs and the plugin config
|
|
260
|
+
// stands on its own — which is exactly what `installConnectSection` falls
|
|
261
|
+
// back to.
|
|
262
|
+
// Set once the namespace is live; read lazily by the settings service below,
|
|
263
|
+
// which is built before the deferred install runs.
|
|
264
|
+
let liveSection;
|
|
265
|
+
const installNamespace = (scopeCtx) => {
|
|
266
|
+
const installed = installConnectSection({
|
|
267
|
+
owner: scopeCtx,
|
|
268
|
+
settings: scopeCtx.get?.("settings"),
|
|
269
|
+
entry: finalCfg,
|
|
270
|
+
onChange: (section) => {
|
|
271
|
+
void runtime.apply(section);
|
|
272
|
+
},
|
|
273
|
+
});
|
|
274
|
+
liveSection = installed.handle;
|
|
275
|
+
};
|
|
276
|
+
if (typeof ctx.inject === "function") {
|
|
277
|
+
ctx.inject(["settings"], installNamespace);
|
|
278
|
+
}
|
|
279
|
+
else {
|
|
280
|
+
// Bare context (unit tests): no inject-scope API, install directly.
|
|
281
|
+
installNamespace(ctx);
|
|
282
|
+
}
|
|
283
|
+
// Expose the web-settings RPC. The host `connection`/`webServer` services are
|
|
284
|
+
// loaded as base plugins AFTER this user plugin's apply runs, so a plain
|
|
285
|
+
// optional inject would see `ctx.connection === undefined` and mount nothing
|
|
286
|
+
// (the settings pane then hangs on "加载中"). Instead defer the registration
|
|
287
|
+
// into a nested injection scope that waits for both to be ready — the same
|
|
288
|
+
// pattern dsh-api-gateway uses for its `/api` route. If the host never
|
|
289
|
+
// provides them (non-web runtime), the callback never runs and the RPC is
|
|
290
|
+
// simply absent.
|
|
291
|
+
//
|
|
292
|
+
// Both services are required in the injected set: `installSettingsRpc` mounts
|
|
293
|
+
// the channel as a `prefix` route on `webServer` itself (see its doc for why
|
|
294
|
+
// `connection.rpc.handle` cannot be used for a third-party channel), and it
|
|
295
|
+
// reads `connection.requestRejection` for the Host/Origin + browser-auth
|
|
296
|
+
// fence.
|
|
297
|
+
//
|
|
298
|
+
// Web settings pane state. When the namespace above is live, that registration
|
|
299
|
+
// *is* the store: the pane reads and writes `$DSH_HOME/settings.yaml` through
|
|
300
|
+
// `liveSection`, a save reconciles the adapters immediately (via the same
|
|
301
|
+
// `onChange`) and survives a restart. The JSON file below is then only a
|
|
302
|
+
// fallback for a host with no settings service, which is why the service takes
|
|
303
|
+
// the handle as a getter rather than a value.
|
|
304
|
+
//
|
|
305
|
+
// Seeded from the live plugin config so the pane reflects the channels actually
|
|
306
|
+
// enabled; only NON-SECRET editable fields per channel (secrets live in the
|
|
307
|
+
// credential store, never in either store this file touches). The fallback path
|
|
308
|
+
// is defaulted under the state dir so a save persists out of the box.
|
|
309
|
+
const settingsSeed = {
|
|
310
|
+
channels: finalCfg.channels ?? CHANNELS,
|
|
311
|
+
...(finalCfg.channelDefaults ? { channelDefaults: finalCfg.channelDefaults } : {}),
|
|
312
|
+
};
|
|
313
|
+
for (const ch of CHANNELS) {
|
|
314
|
+
const raw = finalCfg[ch] ?? {};
|
|
315
|
+
const nonSecret = {};
|
|
316
|
+
for (const field of CHANNEL_CONFIG_FIELDS[ch] ?? []) {
|
|
317
|
+
if (raw[field.key] !== undefined)
|
|
318
|
+
nonSecret[field.key] = raw[field.key];
|
|
319
|
+
}
|
|
320
|
+
if (Object.keys(nonSecret).length)
|
|
321
|
+
settingsSeed[ch] = nonSecret;
|
|
322
|
+
}
|
|
323
|
+
// Resolve through the shared helper and off the *merged* config, so the state
|
|
324
|
+
// file lands beside `bindings.json` and can't disagree with the stores. This
|
|
325
|
+
// used to read the raw `cfg.stateDir`, which made the path `undefined` for
|
|
326
|
+
// every profile that never set `stateDir` — and an undefined path made the
|
|
327
|
+
// settings service degrade to in-memory, so a pane save silently vanished.
|
|
328
|
+
const settingsStatePath = finalCfg.settingsStatePath
|
|
329
|
+
?? join(resolveStateDir(finalCfg), "dsh-connect-settings.json");
|
|
330
|
+
const settingsService = createSettingsService({
|
|
331
|
+
statePath: settingsStatePath,
|
|
332
|
+
credentialStore,
|
|
333
|
+
initialConfig: settingsSeed,
|
|
334
|
+
live: () => liveSection,
|
|
335
|
+
});
|
|
336
|
+
if (typeof ctx.inject === "function") {
|
|
337
|
+
ctx.inject(["connection", "webServer"], (scopeCtx) => {
|
|
338
|
+
installSettingsRpc(scopeCtx, { service: settingsService });
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
else {
|
|
342
|
+
// Fallback for a bare context without the inject-scope API: try directly.
|
|
343
|
+
installSettingsRpc(ctx, { service: settingsService });
|
|
344
|
+
}
|
|
53
345
|
}
|
|
54
|
-
|
|
346
|
+
// The DSH loader (cordis-plugin-loader) resolves a plugin entry to the module's
|
|
347
|
+
// DEFAULT export via `unwrapExports()` (`exports.default ?? exports`), then
|
|
348
|
+
// hands it to `ctx.registry.plugin()`. An object `{ apply, name, inject }` makes
|
|
349
|
+
// the loader route through `apply` — the function that activates the channel
|
|
350
|
+
// adapters and installs the web-settings RPC.
|
|
351
|
+
//
|
|
352
|
+
// Previously the default export was the `ConnectService` class. That "worked"
|
|
353
|
+
// on the surface (the class was constructed, no error) but `apply` was never
|
|
354
|
+
// called, so `activateChannels` and `installSettingsRpc` were silently skipped:
|
|
355
|
+
// no channel was bound and no `/dsh-connect` RPC route was mounted (the web
|
|
356
|
+
// settings pane hung on "加载中"). Routing through `apply` fixes it.
|
|
357
|
+
export default { apply, name, inject };
|
|
55
358
|
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/lib/runner.d.ts
CHANGED
|
@@ -29,8 +29,7 @@ export interface ConnectConfig {
|
|
|
29
29
|
autoMirror?: boolean;
|
|
30
30
|
/** Liveness heartbeat interval ms for the streaming card; 0 disables it (default: 60000). */
|
|
31
31
|
streamHeartbeatMs?: number;
|
|
32
|
-
/**
|
|
33
|
-
/** Streaming reply detail. Default 'result' (final answer only) to keep chat cards short. */
|
|
32
|
+
/** Streaming reply detail. Default 'result' (final answer only) keeps chat cards short. */
|
|
34
33
|
notifyLevel?: NotifyLevel;
|
|
35
34
|
/** Proactive progress-notice interval ms: when a turn goes silent for this long, a standalone status card is sent (default: 300000 = 5 min; 0 disables). */
|
|
36
35
|
progressTimeoutMs?: number;
|
|
@@ -72,6 +71,8 @@ export declare class AgentRunner implements MenuHost {
|
|
|
72
71
|
private readonly reminders?;
|
|
73
72
|
private readonly queue;
|
|
74
73
|
private running;
|
|
74
|
+
/** Set by `dispose()`; makes the runner permanently inert. */
|
|
75
|
+
private disposed;
|
|
75
76
|
private agent?;
|
|
76
77
|
private handle?;
|
|
77
78
|
private turn?;
|
|
@@ -99,6 +100,20 @@ export declare class AgentRunner implements MenuHost {
|
|
|
99
100
|
private reasonLabel;
|
|
100
101
|
/** Prefer the user's first DSH workspace over the process cwd as default. */
|
|
101
102
|
private resolveDefaultWorkDir;
|
|
103
|
+
/**
|
|
104
|
+
* Tear the runner down for good — the counterpoint to `enqueue`.
|
|
105
|
+
*
|
|
106
|
+
* Called when the runner's channel adapter is deactivated (a settings change
|
|
107
|
+
* removed that channel from `channels[]`) or the service shuts down. The
|
|
108
|
+
* runner is inert afterwards: `enqueue` drops work and the drain loop stops
|
|
109
|
+
* before its next turn. `ConnectService` deletes its map entry, so a later
|
|
110
|
+
* message builds a fresh runner instead of reviving this one.
|
|
111
|
+
*
|
|
112
|
+
* `queuedMessages` is cleared rather than replayed: those messages belong to
|
|
113
|
+
* a channel that no longer has an adapter to answer on, so replaying them
|
|
114
|
+
* would run agent turns whose output has nowhere to go.
|
|
115
|
+
*/
|
|
116
|
+
dispose(): Promise<void>;
|
|
102
117
|
enqueue(msg: InboundMessage): void;
|
|
103
118
|
/** Route one live session event to the active turn's chunk queue. */
|
|
104
119
|
onSessionEvent(session: Session, event: SessionEvent): void;
|
|
@@ -161,8 +176,46 @@ export declare class AgentRunner implements MenuHost {
|
|
|
161
176
|
* report it) while the actual LLM requests keep using the old default.
|
|
162
177
|
* The default model still seeds the agent through `agentOptions` in
|
|
163
178
|
* `ensureAgent`, which `buildRequest` uses as its fallback route.
|
|
179
|
+
*
|
|
180
|
+
* Preset resolution is best-effort — see {@link resolvePresetId}. This method
|
|
181
|
+
* never throws for a preset reason, so no configuration id can stop a turn
|
|
182
|
+
* from composing an agent at all.
|
|
164
183
|
*/
|
|
165
184
|
private composeSetup;
|
|
185
|
+
/**
|
|
186
|
+
* Resolve the preset to compose, degrading instead of aborting the turn.
|
|
187
|
+
*
|
|
188
|
+
* The host looks a preset up by id, so one stale id — `agentPresets.default`
|
|
189
|
+
* naming a preset this install does not ship, or a preset directory edited
|
|
190
|
+
* into an unreadable state — used to throw straight out of `composeSetup`.
|
|
191
|
+
* That happens before an agent exists, so *every* turn of every bound chat
|
|
192
|
+
* died with the raw host error and nothing in the session log to explain it.
|
|
193
|
+
* Resolution is therefore best-effort: the configured id is tried, then
|
|
194
|
+
* {@link FALLBACK_PRESET_ID}, and when neither composes the agent is built
|
|
195
|
+
* without a preset — the same shape a host with no `agentPresets` service
|
|
196
|
+
* already produced — so the turn still runs.
|
|
197
|
+
*/
|
|
198
|
+
private resolvePresetId;
|
|
199
|
+
/**
|
|
200
|
+
* Resolve `id`, reporting why it is unusable instead of throwing.
|
|
201
|
+
*
|
|
202
|
+
* A preset that resolves but reports `broken` counts as unusable: the host's
|
|
203
|
+
* mounting paths refuse those, so composing one would only move this failure
|
|
204
|
+
* to `mount`, after the log line that would have explained it.
|
|
205
|
+
*
|
|
206
|
+
* `undefined` id means "the roster default", which is what `resolve` does
|
|
207
|
+
* with it — the default is as fallible as an explicit id, so it is routed
|
|
208
|
+
* through the same recovery.
|
|
209
|
+
*/
|
|
210
|
+
private tryPreset;
|
|
211
|
+
/**
|
|
212
|
+
* The id to retry with: {@link FALLBACK_PRESET_ID} while the roster still
|
|
213
|
+
* offers it, otherwise the roster's first mountable row.
|
|
214
|
+
*
|
|
215
|
+
* Never throws — the caller is already handling a failure, and a roster that
|
|
216
|
+
* cannot be listed should still leave the hardcoded id to be tried.
|
|
217
|
+
*/
|
|
218
|
+
private fallbackPresetId;
|
|
166
219
|
/** Agents this runner has already attached a `session/event` listener to. */
|
|
167
220
|
private readonly watchedAgents;
|
|
168
221
|
private watchAgent;
|
package/lib/runner.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"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"}
|