@morlay/dsh-session-mode 0.0.13 → 0.0.14-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{catalog-K5cESbqA.cjs → catalog-C_6kb1aC.cjs} +2 -3
- package/dist/{catalog-DWxIg3qw.mjs → catalog-D-n_RctY.mjs} +2 -3
- package/dist/{catalog-remote-KXJjDaN6.mjs → catalog-remote-Cz8L_Zrl.mjs} +1 -2
- package/dist/{catalog-remote-B7ZgYqun.cjs → catalog-remote-DWV4E4Vo.cjs} +1 -2
- package/dist/client.cjs +1228 -520
- package/dist/client.d.cts +0 -14
- package/dist/client.d.mts +0 -14
- package/dist/client.mjs +11 -22
- package/dist/index.cjs +62 -42
- package/dist/index.d.mts +9 -7
- package/dist/index.mjs +62 -42
- package/dist/rows.cjs +8 -6
- package/dist/rows.d.mts +1 -3
- package/dist/rows.mjs +8 -6
- package/dist/{shared-BusmswG5.cjs → shared-DO1nZbJ0.cjs} +2 -4
- package/dist/{shared-DX2Giyh3.mjs → shared-vjlwxiMt.mjs} +1 -2
- package/dist/testing.cjs +2 -2
- package/dist/testing.d.mts +0 -4
- package/dist/testing.mjs +2 -2
- package/package.json +56 -56
- package/src/index.ts +62 -21
- package/src/mode-sources.ts +6 -3
- package/src/scope.ts +53 -36
package/dist/client.d.cts
CHANGED
|
@@ -3,7 +3,6 @@ import { SnapshotStore } from "@deepseek-ai/dsh-client-store";
|
|
|
3
3
|
import { SchemaFormState } from "@morlay/dsh-client-ui-primitives";
|
|
4
4
|
import { InjectFace, PropsLocale, PropsRuntime } from "@deepseek-ai/dsh-client-ui-slots";
|
|
5
5
|
import "react";
|
|
6
|
-
//#region src/client/bundle-locales.d.ts
|
|
7
6
|
declare const bundleZh: {
|
|
8
7
|
"default.label": string;
|
|
9
8
|
"default.hint": string;
|
|
@@ -100,8 +99,6 @@ declare const bundleZh: {
|
|
|
100
99
|
"summary.globalModel": string;
|
|
101
100
|
};
|
|
102
101
|
type BundleLocaleKey = keyof typeof bundleZh;
|
|
103
|
-
//#endregion
|
|
104
|
-
//#region src/client/llm-directory.d.ts
|
|
105
102
|
interface ModelRoute {
|
|
106
103
|
readonly key: string;
|
|
107
104
|
readonly provider: string;
|
|
@@ -109,8 +106,6 @@ interface ModelRoute {
|
|
|
109
106
|
readonly model: string;
|
|
110
107
|
readonly modelName: string;
|
|
111
108
|
}
|
|
112
|
-
//#endregion
|
|
113
|
-
//#region src/client/bundle-config.d.ts
|
|
114
109
|
export declare const SESSION_MODE_NS = "session-mode";
|
|
115
110
|
interface BundleConfigDiagnosis {
|
|
116
111
|
readonly namespaces: readonly string[];
|
|
@@ -142,8 +137,6 @@ interface BundleConfigFace extends BundleConfigActions {
|
|
|
142
137
|
resync: () => void;
|
|
143
138
|
}
|
|
144
139
|
type ConfigStatus = "loading" | "ready" | "unavailable";
|
|
145
|
-
//#endregion
|
|
146
|
-
//#region src/client/locales.d.ts
|
|
147
140
|
declare const zh: {
|
|
148
141
|
seatHint: string;
|
|
149
142
|
lockedHint: string;
|
|
@@ -156,14 +149,8 @@ declare const zh: {
|
|
|
156
149
|
reasoningEffortHint: string;
|
|
157
150
|
};
|
|
158
151
|
type SessionModeLocaleKey = keyof typeof zh;
|
|
159
|
-
//#endregion
|
|
160
|
-
//#region src/client/SessionModeSeat.d.ts
|
|
161
152
|
type SessionModeSeatProps = PropsRuntime<"conversation.input.left"> & PropsLocale<"session-mode">;
|
|
162
|
-
//#endregion
|
|
163
|
-
//#region src/client/BundleConfigPage.d.ts
|
|
164
153
|
type BundleConfigPageProps = PropsRuntime<"plugins.bundle.config"> & PropsLocale<"session-mode-bundle"> & InjectFace<BundleConfigFace>;
|
|
165
|
-
//#endregion
|
|
166
|
-
//#region src/client/index.d.ts
|
|
167
154
|
declare module "@deepseek-ai/dsh-client-ui-slots" {
|
|
168
155
|
interface LocaleNamespaceMap {
|
|
169
156
|
"session-mode": SessionModeLocaleKey;
|
|
@@ -172,5 +159,4 @@ declare module "@deepseek-ai/dsh-client-ui-slots" {
|
|
|
172
159
|
}
|
|
173
160
|
export declare const inject: string[];
|
|
174
161
|
export declare function apply(ctx: Context): void;
|
|
175
|
-
//#endregion
|
|
176
162
|
export type { BundleConfigPageProps, SessionModeLocaleKey, SessionModeSeatProps };
|
package/dist/client.d.mts
CHANGED
|
@@ -3,7 +3,6 @@ import { SnapshotStore } from "@deepseek-ai/dsh-client-store";
|
|
|
3
3
|
import { SchemaFormState } from "@morlay/dsh-client-ui-primitives";
|
|
4
4
|
import { InjectFace, PropsLocale, PropsRuntime } from "@deepseek-ai/dsh-client-ui-slots";
|
|
5
5
|
import "react";
|
|
6
|
-
//#region src/client/bundle-locales.d.ts
|
|
7
6
|
declare const bundleZh: {
|
|
8
7
|
"default.label": string;
|
|
9
8
|
"default.hint": string;
|
|
@@ -100,8 +99,6 @@ declare const bundleZh: {
|
|
|
100
99
|
"summary.globalModel": string;
|
|
101
100
|
};
|
|
102
101
|
type BundleLocaleKey = keyof typeof bundleZh;
|
|
103
|
-
//#endregion
|
|
104
|
-
//#region src/client/llm-directory.d.ts
|
|
105
102
|
interface ModelRoute {
|
|
106
103
|
readonly key: string;
|
|
107
104
|
readonly provider: string;
|
|
@@ -109,8 +106,6 @@ interface ModelRoute {
|
|
|
109
106
|
readonly model: string;
|
|
110
107
|
readonly modelName: string;
|
|
111
108
|
}
|
|
112
|
-
//#endregion
|
|
113
|
-
//#region src/client/bundle-config.d.ts
|
|
114
109
|
export declare const SESSION_MODE_NS = "session-mode";
|
|
115
110
|
interface BundleConfigDiagnosis {
|
|
116
111
|
readonly namespaces: readonly string[];
|
|
@@ -142,8 +137,6 @@ interface BundleConfigFace extends BundleConfigActions {
|
|
|
142
137
|
resync: () => void;
|
|
143
138
|
}
|
|
144
139
|
type ConfigStatus = "loading" | "ready" | "unavailable";
|
|
145
|
-
//#endregion
|
|
146
|
-
//#region src/client/locales.d.ts
|
|
147
140
|
declare const zh: {
|
|
148
141
|
seatHint: string;
|
|
149
142
|
lockedHint: string;
|
|
@@ -156,14 +149,8 @@ declare const zh: {
|
|
|
156
149
|
reasoningEffortHint: string;
|
|
157
150
|
};
|
|
158
151
|
type SessionModeLocaleKey = keyof typeof zh;
|
|
159
|
-
//#endregion
|
|
160
|
-
//#region src/client/SessionModeSeat.d.ts
|
|
161
152
|
type SessionModeSeatProps = PropsRuntime<"conversation.input.left"> & PropsLocale<"session-mode">;
|
|
162
|
-
//#endregion
|
|
163
|
-
//#region src/client/BundleConfigPage.d.ts
|
|
164
153
|
type BundleConfigPageProps = PropsRuntime<"plugins.bundle.config"> & PropsLocale<"session-mode-bundle"> & InjectFace<BundleConfigFace>;
|
|
165
|
-
//#endregion
|
|
166
|
-
//#region src/client/index.d.ts
|
|
167
154
|
declare module "@deepseek-ai/dsh-client-ui-slots" {
|
|
168
155
|
interface LocaleNamespaceMap {
|
|
169
156
|
"session-mode": SessionModeLocaleKey;
|
|
@@ -172,5 +159,4 @@ declare module "@deepseek-ai/dsh-client-ui-slots" {
|
|
|
172
159
|
}
|
|
173
160
|
export declare const inject: string[];
|
|
174
161
|
export declare function apply(ctx: Context): void;
|
|
175
|
-
//#endregion
|
|
176
162
|
export type { BundleConfigPageProps, SessionModeLocaleKey, SessionModeSeatProps };
|
package/dist/client.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import { createSnapshotStore } from "@deepseek-ai/dsh-client-store";
|
|
|
2
2
|
import { Button, DisclosureRow, IconAgentPresetOutlineRegular, IconButton, IconChevronDownOutlineRegular, IconPlusOutlineRegular, IconTrashOutlineRegular, Input, Menu, Modal, ModelRouteList, MultilineField, Row, SchemaFormController, SearchSelect, SeatButton, SegmentedControl, SettingsFieldRow, SettingsForm, Stack, Switch, TagInput, Text, failureOf, projectRoot } from "@morlay/dsh-client-ui-primitives";
|
|
3
3
|
import { useEffect, useId, useMemo, useState } from "react";
|
|
4
4
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
-
|
|
5
|
+
// src/catalog-remote.ts
|
|
6
6
|
const CATALOG_NS = "sessionModeCatalog";
|
|
7
7
|
const SESSION_MODE_CATALOG_REMOTE = {
|
|
8
8
|
package: "@morlay/dsh-session-mode",
|
|
@@ -17,12 +17,10 @@ const SESSION_MODE_CATALOG_REMOTE = {
|
|
|
17
17
|
result: { mode: "src-json" }
|
|
18
18
|
}]
|
|
19
19
|
};
|
|
20
|
-
|
|
21
|
-
//#region src/shared.ts
|
|
20
|
+
// src/shared.ts
|
|
22
21
|
const SESSION_MODE_PATH = "/session-mode";
|
|
23
22
|
const POLICY_NAMES = ["fs/write-intent", "fs/edit-intent"];
|
|
24
|
-
|
|
25
|
-
//#region src/client/llm-directory.ts
|
|
23
|
+
// src/client/llm-directory.ts
|
|
26
24
|
function routeKey(provider, model) {
|
|
27
25
|
return `${provider}\u0000${model}`;
|
|
28
26
|
}
|
|
@@ -90,8 +88,7 @@ function routesOf(providers) {
|
|
|
90
88
|
modelName: model.label
|
|
91
89
|
})));
|
|
92
90
|
}
|
|
93
|
-
|
|
94
|
-
//#region src/client/bundle-config.ts
|
|
91
|
+
// src/client/bundle-config.ts
|
|
95
92
|
const SESSION_MODE_NS = "session-mode";
|
|
96
93
|
const BUNDLE_CONFIG_KEY = "@morlay/session-mode-profile";
|
|
97
94
|
const PROTECTED_MODE_IDS = ["noop"];
|
|
@@ -598,8 +595,7 @@ function arrayOf(field) {
|
|
|
598
595
|
return Array.isArray(value) ? value.map((item) => String(item)) : [];
|
|
599
596
|
}
|
|
600
597
|
const ROLES = ROLE_VALUES;
|
|
601
|
-
|
|
602
|
-
//#region src/client/BundleConfigPage.tsx
|
|
598
|
+
// src/client/BundleConfigPage.tsx
|
|
603
599
|
function BundleConfigPage(props) {
|
|
604
600
|
const { t, view } = props;
|
|
605
601
|
const face = {
|
|
@@ -1089,8 +1085,7 @@ function FieldControl({ field, writable, t, face }) {
|
|
|
1089
1085
|
function triValue(field) {
|
|
1090
1086
|
return field.value === "unset" || field.value === "on" || field.value === "off" ? field.value : "unset";
|
|
1091
1087
|
}
|
|
1092
|
-
|
|
1093
|
-
//#region src/client/bundle-locales.ts
|
|
1088
|
+
// src/client/bundle-locales.ts
|
|
1094
1089
|
const BUNDLE_NS = "session-mode-bundle";
|
|
1095
1090
|
const bundleZh = {
|
|
1096
1091
|
"default.label": "新会话的默认模式",
|
|
@@ -1282,8 +1277,7 @@ const bundleEn = {
|
|
|
1282
1277
|
"summary.denyTools": "{n} denied",
|
|
1283
1278
|
"summary.globalModel": "global model"
|
|
1284
1279
|
};
|
|
1285
|
-
|
|
1286
|
-
//#region src/client/api.ts
|
|
1280
|
+
// src/client/api.ts
|
|
1287
1281
|
async function fetchRoster() {
|
|
1288
1282
|
const response = await fetch(SESSION_MODE_PATH, {
|
|
1289
1283
|
method: "GET",
|
|
@@ -1311,8 +1305,7 @@ async function selectMode(sessionId, mode) {
|
|
|
1311
1305
|
}
|
|
1312
1306
|
return value?.mode ?? mode;
|
|
1313
1307
|
}
|
|
1314
|
-
|
|
1315
|
-
//#region src/client/use-roster.ts
|
|
1308
|
+
// src/client/use-roster.ts
|
|
1316
1309
|
let pending;
|
|
1317
1310
|
function useRoster() {
|
|
1318
1311
|
const [roster, setRoster] = useState(void 0);
|
|
@@ -1330,8 +1323,7 @@ function useRoster() {
|
|
|
1330
1323
|
}, []);
|
|
1331
1324
|
return roster;
|
|
1332
1325
|
}
|
|
1333
|
-
|
|
1334
|
-
//#region src/client/SessionModeSeat.tsx
|
|
1326
|
+
// src/client/SessionModeSeat.tsx
|
|
1335
1327
|
function SessionModeSeat({ sessionId, useSessions, t }) {
|
|
1336
1328
|
const roster = useRoster();
|
|
1337
1329
|
const selected = useSessions((state) => {
|
|
@@ -1401,8 +1393,7 @@ function SessionModeSeat({ sessionId, useSessions, t }) {
|
|
|
1401
1393
|
})
|
|
1402
1394
|
});
|
|
1403
1395
|
}
|
|
1404
|
-
|
|
1405
|
-
//#region src/client/locales.ts
|
|
1396
|
+
// src/client/locales.ts
|
|
1406
1397
|
const zh = {
|
|
1407
1398
|
seatHint: "选择这个会话的模式",
|
|
1408
1399
|
lockedHint: "这个会话已经开始:换模式请新开一个会话",
|
|
@@ -1425,8 +1416,7 @@ const en = {
|
|
|
1425
1416
|
reasoningEffort: "Reasoning effort",
|
|
1426
1417
|
reasoningEffortHint: "Default keeps the provider's own default."
|
|
1427
1418
|
};
|
|
1428
|
-
|
|
1429
|
-
//#region src/client/index.ts
|
|
1419
|
+
// src/client/index.ts
|
|
1430
1420
|
const NS = "session-mode";
|
|
1431
1421
|
const FIELDS = [
|
|
1432
1422
|
"provider",
|
|
@@ -1608,5 +1598,4 @@ function apply(ctx) {
|
|
|
1608
1598
|
}, "session-mode: bundle configuration page");
|
|
1609
1599
|
});
|
|
1610
1600
|
}
|
|
1611
|
-
//#endregion
|
|
1612
1601
|
export { SESSION_MODE_NS, apply, inject };
|
package/dist/index.cjs
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_shared = require("./shared-
|
|
3
|
-
const require_catalog = require("./catalog-
|
|
2
|
+
const require_shared = require("./shared-DO1nZbJ0.cjs");
|
|
3
|
+
const require_catalog = require("./catalog-C_6kb1aC.cjs");
|
|
4
4
|
let _deepseek_ai_cordis = require("@deepseek-ai/cordis");
|
|
5
|
+
let _deepseek_ai_dsh_agent = require("@deepseek-ai/dsh-agent");
|
|
5
6
|
let _deepseek_ai_dsh_llm = require("@deepseek-ai/dsh-llm");
|
|
7
|
+
let _deepseek_ai_dsh_agent_preset_registry = require("@deepseek-ai/dsh-agent-preset-registry");
|
|
6
8
|
let zod = require("zod");
|
|
7
9
|
let _deepseek_ai_schemastery = require("@deepseek-ai/schemastery");
|
|
8
10
|
_deepseek_ai_schemastery = require_shared.__toESM(_deepseek_ai_schemastery, 1);
|
|
9
11
|
let _deepseek_ai_dsh_system_prompt = require("@deepseek-ai/dsh-system-prompt");
|
|
10
|
-
|
|
12
|
+
// src/modes.ts
|
|
11
13
|
function derivedSkills(mode) {
|
|
12
14
|
return (mode.allowTools.length === 0 || mode.allowTools.includes("skill")) && !mode.denyTools.includes("skill");
|
|
13
15
|
}
|
|
@@ -123,8 +125,7 @@ function configProblem(config) {
|
|
|
123
125
|
}).map(([id]) => id);
|
|
124
126
|
if (partial.length > 0) return `session-mode: mode(s) ${partial.join(", ")} declare \`defaultModel\` without both \`provider\` and \`model\``;
|
|
125
127
|
}
|
|
126
|
-
|
|
127
|
-
//#region src/persona.ts
|
|
128
|
+
// src/persona.ts
|
|
128
129
|
const PREFIX_ORDER = "DEPLOYMENT_PERSONA_PREFIX";
|
|
129
130
|
const SUFFIX_ORDER = "DEPLOYMENT_PERSONA_SUFFIX";
|
|
130
131
|
function installPersona(agent, persona) {
|
|
@@ -142,13 +143,7 @@ function installPersona(agent, persona) {
|
|
|
142
143
|
for (const dispose of disposers) dispose();
|
|
143
144
|
};
|
|
144
145
|
}
|
|
145
|
-
|
|
146
|
-
//#region src/scope.ts
|
|
147
|
-
const OUT_OF_SCOPE = (toolName, modeName) => `${toolName} 不在「${modeName}」的工具白名单里,用它不会有结果;按当前模式提供的工具完成任务,或让用户切到别的模式。`;
|
|
148
|
-
const DENYLISTED = (toolName, modeName) => `${toolName} 被「${modeName}」的工具黑名单排除,用它不会有结果;按当前模式提供的工具完成任务,或让用户切到别的模式。`;
|
|
149
|
-
function refusalOf(toolName, modeName, denial) {
|
|
150
|
-
return denial === "denylisted" ? DENYLISTED(toolName, modeName) : OUT_OF_SCOPE(toolName, modeName);
|
|
151
|
-
}
|
|
146
|
+
// src/scope.ts
|
|
152
147
|
const SKILL_OUT_OF_SCOPE = (skillName, modeName) => `${skillName} 不在「${modeName}」的技能白名单里,加载它不会有结果;按当前模式可用的技能完成任务,或让用户切到别的模式。`;
|
|
153
148
|
const SKILL_DENYLISTED = (skillName, modeName) => `${skillName} 被「${modeName}」的技能黑名单排除,加载它不会有结果;按当前模式可用的技能完成任务,或让用户切到别的模式。`;
|
|
154
149
|
function skillRefusalOf(skillName, modeName, denial) {
|
|
@@ -225,8 +220,7 @@ var SessionScope = class {
|
|
|
225
220
|
const result = await next();
|
|
226
221
|
return {
|
|
227
222
|
...result,
|
|
228
|
-
sections: result.sections.filter((section) => section.name.startsWith(TOOL_SECTION_PREFIX) ? denialOf(gate, section.name.slice(5)) === void 0 : true)
|
|
229
|
-
tools: result.tools.filter((tool) => denialOf(gate, tool.name) === void 0)
|
|
223
|
+
sections: result.sections.filter((section) => section.name.startsWith(TOOL_SECTION_PREFIX) ? denialOf(gate, section.name.slice(5)) === void 0 : true)
|
|
230
224
|
};
|
|
231
225
|
});
|
|
232
226
|
}
|
|
@@ -247,19 +241,32 @@ var SessionScope = class {
|
|
|
247
241
|
};
|
|
248
242
|
}, { prepend: true }));
|
|
249
243
|
if (definition.runtimeContext === false) stoppers.push(agent.ctx.systemPrompt.suppressRuntimeContext());
|
|
250
|
-
const
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
const
|
|
254
|
-
|
|
255
|
-
|
|
244
|
+
const install = (scope) => {
|
|
245
|
+
const disposers = [];
|
|
246
|
+
if (gate !== void 0) {
|
|
247
|
+
const known = new Set(scope.tools.definitions(agent).map((tool) => tool.name));
|
|
248
|
+
disposers.push(scope.tools.restrict({
|
|
249
|
+
...gate.allow === void 0 ? {} : { allow: [...gate.allow].filter((name) => known.has(name)) },
|
|
250
|
+
...gate.deny.size === 0 ? {} : { deny: [...gate.deny].filter((name) => known.has(name)) }
|
|
251
|
+
}));
|
|
252
|
+
}
|
|
253
|
+
if (skillGate === void 0) return disposers;
|
|
254
|
+
disposers.push(scope.tools.guard((exec) => {
|
|
255
|
+
if (exec.name !== SKILL_TOOL_NAME) return void 0;
|
|
256
256
|
const skillName = skillNameOf(exec.arguments);
|
|
257
257
|
if (skillName === void 0) return void 0;
|
|
258
258
|
const skillDenial = denialOf(skillGate, skillName);
|
|
259
259
|
return skillDenial === void 0 ? void 0 : skillRefusalOf(skillName, definition.name, skillDenial);
|
|
260
|
+
}));
|
|
261
|
+
return disposers;
|
|
262
|
+
};
|
|
263
|
+
if (agent.ctx.get("tools") === void 0) {
|
|
264
|
+
const fiber = agent.ctx.inject(["tools"], (scope) => {
|
|
265
|
+
stoppers.push(...install(scope));
|
|
260
266
|
});
|
|
261
|
-
|
|
262
|
-
|
|
267
|
+
stoppers.push(() => fiber.dispose());
|
|
268
|
+
} else stoppers.push(...install(agent.ctx));
|
|
269
|
+
return stoppers;
|
|
263
270
|
}, "session-mode: per-session gate");
|
|
264
271
|
this.channel()?.setInstructions(agent, definition.instructions);
|
|
265
272
|
this.applied.set(agent, {
|
|
@@ -307,8 +314,7 @@ var SessionScope = class {
|
|
|
307
314
|
}
|
|
308
315
|
}
|
|
309
316
|
};
|
|
310
|
-
|
|
311
|
-
//#region src/index.ts
|
|
317
|
+
// src/index.ts
|
|
312
318
|
const name = "session-mode";
|
|
313
319
|
const inject = [
|
|
314
320
|
"agents",
|
|
@@ -340,9 +346,13 @@ const sessionModeEditableProjection = {
|
|
|
340
346
|
},
|
|
341
347
|
stateVersion: 1
|
|
342
348
|
};
|
|
343
|
-
var SessionModes = class extends _deepseek_ai_cordis.Service {
|
|
349
|
+
var SessionModes = class SessionModes extends _deepseek_ai_cordis.Service {
|
|
344
350
|
installs = /* @__PURE__ */ new WeakMap();
|
|
345
351
|
scope;
|
|
352
|
+
projectionHandle;
|
|
353
|
+
editableHandle;
|
|
354
|
+
modelSelectionHandle;
|
|
355
|
+
agentPresetHandle;
|
|
346
356
|
config;
|
|
347
357
|
constructor(ctx, config) {
|
|
348
358
|
super(ctx, "sessionModes");
|
|
@@ -356,8 +366,6 @@ var SessionModes = class extends _deepseek_ai_cordis.Service {
|
|
|
356
366
|
});
|
|
357
367
|
if (problem !== void 0) throw new Error(problem);
|
|
358
368
|
this.scope = new SessionScope(ctx);
|
|
359
|
-
ctx.sessionProjections.register(sessionModeProjection);
|
|
360
|
-
ctx.sessionProjections.register(sessionModeEditableProjection);
|
|
361
369
|
ctx.on("fs/write-intent", (_target, actor, next) => this.decidePolicy("fs/write-intent", actor, next), { prepend: true });
|
|
362
370
|
ctx.on("fs/edit-intent", (_target, actor, next) => this.decidePolicy("fs/edit-intent", actor, next), { prepend: true });
|
|
363
371
|
ctx.on("agent/created", ({ agent }) => {
|
|
@@ -367,10 +375,21 @@ var SessionModes = class extends _deepseek_ai_cordis.Service {
|
|
|
367
375
|
const mapped = this.modeForPreset(preset);
|
|
368
376
|
const agent = ctx.agents.get(sessionId);
|
|
369
377
|
if (mapped === void 0 || agent === void 0) return;
|
|
370
|
-
if (this.
|
|
378
|
+
if (this.projectionHandle.stateOf(agent.session) !== mapped) agent.session.append("session-mode/selected", { sessionMode: mapped });
|
|
371
379
|
this.installFor(agent, mapped);
|
|
372
380
|
});
|
|
373
381
|
}
|
|
382
|
+
static async create(ctx, config) {
|
|
383
|
+
const modes = new SessionModes(ctx, config);
|
|
384
|
+
await modes.init();
|
|
385
|
+
return modes;
|
|
386
|
+
}
|
|
387
|
+
async init() {
|
|
388
|
+
this.projectionHandle = await this.ctx.sessionProjections.register(sessionModeProjection);
|
|
389
|
+
this.editableHandle = await this.ctx.sessionProjections.register(sessionModeEditableProjection);
|
|
390
|
+
this.modelSelectionHandle = await this.ctx.sessionProjections.register(_deepseek_ai_dsh_agent.modelSelectionProjectionDefinition);
|
|
391
|
+
this.agentPresetHandle = await this.ctx.sessionProjections.register(_deepseek_ai_dsh_agent_preset_registry.agentPresetProjectionDefinition);
|
|
392
|
+
}
|
|
374
393
|
get defaultId() {
|
|
375
394
|
return this.config.default;
|
|
376
395
|
}
|
|
@@ -405,8 +424,14 @@ var SessionModes = class extends _deepseek_ai_cordis.Service {
|
|
|
405
424
|
if (mode === void 0) throw new Error(`未知的模式 ${JSON.stringify(wanted)};可用的是 ${Object.keys(this.config.modes).join(", ")}`);
|
|
406
425
|
return mode;
|
|
407
426
|
}
|
|
427
|
+
selectedOf(session) {
|
|
428
|
+
return this.projectionHandle.stateOf(session);
|
|
429
|
+
}
|
|
408
430
|
modeOf(session) {
|
|
409
|
-
return this.
|
|
431
|
+
return this.projectionHandle.stateOf(session) ?? this.defaultId;
|
|
432
|
+
}
|
|
433
|
+
editableOf(session) {
|
|
434
|
+
return this.editableHandle.stateOf(session);
|
|
410
435
|
}
|
|
411
436
|
modeOfSession(session) {
|
|
412
437
|
return this.definition(this.modeOf(session));
|
|
@@ -430,14 +455,14 @@ var SessionModes = class extends _deepseek_ai_cordis.Service {
|
|
|
430
455
|
if (!definition.role.includes("main")) throw new Error(`模式 ${JSON.stringify(mode)} 不是用户可选的(它的 role 里没有 main)。`);
|
|
431
456
|
const session = this.ctx.sessions.get(sessionId);
|
|
432
457
|
if (session === void 0) throw new Error(`未知的会话 ${sessionId}`);
|
|
433
|
-
if (this.
|
|
458
|
+
if (this.editableHandle.stateOf(session) === false) throw new Error("这个会话已经开始,模式不能再改;要换模式请新开一个会话。");
|
|
434
459
|
const agent = this.ctx.agents.get(sessionId);
|
|
435
460
|
const registry = this.presetRegistry();
|
|
436
461
|
if (agent !== void 0 && registry !== void 0) {
|
|
437
462
|
const target = this.presetTarget(definition.presetsOnly, this.presetOfAgent(registry, agent));
|
|
438
463
|
if (target !== void 0) await registry.select(agent, target);
|
|
439
464
|
}
|
|
440
|
-
if (this.
|
|
465
|
+
if (this.projectionHandle.stateOf(session) !== mode) session.append("session-mode/selected", { sessionMode: mode });
|
|
441
466
|
if (agent !== void 0) this.installFor(agent);
|
|
442
467
|
return mode;
|
|
443
468
|
}
|
|
@@ -469,7 +494,7 @@ var SessionModes = class extends _deepseek_ai_cordis.Service {
|
|
|
469
494
|
this.installFor(agent, mode);
|
|
470
495
|
}
|
|
471
496
|
resolveModeId(agent) {
|
|
472
|
-
const selected = this.
|
|
497
|
+
const selected = this.projectionHandle.stateOf(agent.session);
|
|
473
498
|
if (typeof selected === "string") return selected;
|
|
474
499
|
const mapped = this.modeForPreset(this.presetOf(agent.session));
|
|
475
500
|
if (mapped !== void 0) {
|
|
@@ -482,12 +507,8 @@ var SessionModes = class extends _deepseek_ai_cordis.Service {
|
|
|
482
507
|
return inherited;
|
|
483
508
|
}
|
|
484
509
|
presetOf(session) {
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
return typeof state === "string" ? state : void 0;
|
|
488
|
-
} catch {
|
|
489
|
-
return;
|
|
490
|
-
}
|
|
510
|
+
const state = this.agentPresetHandle.stateOf(session);
|
|
511
|
+
return typeof state === "string" ? state : void 0;
|
|
491
512
|
}
|
|
492
513
|
modeForPreset(preset) {
|
|
493
514
|
if (preset === void 0) return void 0;
|
|
@@ -528,7 +549,7 @@ var SessionModes = class extends _deepseek_ai_cordis.Service {
|
|
|
528
549
|
const resolved = await next();
|
|
529
550
|
const model = this.config.modes[modeId]?.defaultModel;
|
|
530
551
|
if (model === void 0) return resolved;
|
|
531
|
-
const pending = this.
|
|
552
|
+
const pending = this.modelSelectionHandle.stateOf(agent.session).pending;
|
|
532
553
|
if (pending !== void 0 && pending !== null) return resolved;
|
|
533
554
|
if (agent.session.requestHeader() !== void 0) return resolved;
|
|
534
555
|
return {
|
|
@@ -540,8 +561,8 @@ var SessionModes = class extends _deepseek_ai_cordis.Service {
|
|
|
540
561
|
});
|
|
541
562
|
}
|
|
542
563
|
};
|
|
543
|
-
function apply(ctx, config) {
|
|
544
|
-
registerHttpRoutes(ctx,
|
|
564
|
+
async function apply(ctx, config) {
|
|
565
|
+
registerHttpRoutes(ctx, await SessionModes.create(ctx, config));
|
|
545
566
|
ctx.plugin(require_catalog.SessionModeCatalog);
|
|
546
567
|
}
|
|
547
568
|
function respondJson(response, status, body) {
|
|
@@ -601,7 +622,6 @@ function registerHttpRoutes(ctx, modes) {
|
|
|
601
622
|
}), "session-mode: HTTP route");
|
|
602
623
|
});
|
|
603
624
|
}
|
|
604
|
-
//#endregion
|
|
605
625
|
exports.Config = Config;
|
|
606
626
|
exports.POLICY_NAMES = require_shared.POLICY_NAMES;
|
|
607
627
|
exports.SESSION_MODE_PATH = require_shared.SESSION_MODE_PATH;
|
package/dist/index.d.mts
CHANGED
|
@@ -3,7 +3,6 @@ import { Agent } from "@deepseek-ai/dsh-agent";
|
|
|
3
3
|
import { Session, SessionEvent, SessionId } from "@deepseek-ai/dsh-session";
|
|
4
4
|
import { z } from "zod";
|
|
5
5
|
import z$1 from "@deepseek-ai/schemastery";
|
|
6
|
-
//#region src/modes.d.ts
|
|
7
6
|
interface SessionModePersona {
|
|
8
7
|
readonly prefix: string;
|
|
9
8
|
readonly suffix: string;
|
|
@@ -44,8 +43,6 @@ interface ResolvedConfig {
|
|
|
44
43
|
readonly models: SessionModeModels;
|
|
45
44
|
}
|
|
46
45
|
export declare const Config: z$1<Config, ResolvedConfig>;
|
|
47
|
-
//#endregion
|
|
48
|
-
//#region src/shared.d.ts
|
|
49
46
|
export declare const SESSION_MODE_PATH = "/session-mode";
|
|
50
47
|
export declare const POLICY_NAMES: readonly ["fs/write-intent", "fs/edit-intent"];
|
|
51
48
|
type PolicyName = (typeof POLICY_NAMES)[number];
|
|
@@ -58,8 +55,6 @@ interface SessionModeRoster {
|
|
|
58
55
|
readonly default: string;
|
|
59
56
|
readonly modes: readonly SessionModeRow[];
|
|
60
57
|
}
|
|
61
|
-
//#endregion
|
|
62
|
-
//#region src/index.d.ts
|
|
63
58
|
export declare const name = "session-mode";
|
|
64
59
|
export declare const inject: string[];
|
|
65
60
|
declare module "@deepseek-ai/cordis" {
|
|
@@ -109,11 +104,17 @@ export declare const sessionModeEditableProjection: {
|
|
|
109
104
|
export declare class SessionModes extends Service {
|
|
110
105
|
private readonly installs;
|
|
111
106
|
private readonly scope;
|
|
107
|
+
private projectionHandle;
|
|
108
|
+
private editableHandle;
|
|
109
|
+
private modelSelectionHandle;
|
|
110
|
+
private agentPresetHandle;
|
|
112
111
|
readonly config: {
|
|
113
112
|
default: string;
|
|
114
113
|
modes: Record<string, SessionMode>;
|
|
115
114
|
};
|
|
116
115
|
constructor(ctx: Context, config: ResolvedConfig);
|
|
116
|
+
static create(ctx: Context, config: ResolvedConfig): Promise<SessionModes>;
|
|
117
|
+
private init;
|
|
117
118
|
get defaultId(): string;
|
|
118
119
|
list(): SessionModeRow[];
|
|
119
120
|
idsFor(role: SessionModeRole): string[];
|
|
@@ -123,7 +124,9 @@ export declare class SessionModes extends Service {
|
|
|
123
124
|
}[];
|
|
124
125
|
roster(): SessionModeRoster;
|
|
125
126
|
definition(id?: string): SessionMode;
|
|
127
|
+
selectedOf(session: Session): string | null;
|
|
126
128
|
modeOf(session: Session): string;
|
|
129
|
+
editableOf(session: Session): boolean;
|
|
127
130
|
modeOfSession(session: Session): SessionMode;
|
|
128
131
|
private policyInForce;
|
|
129
132
|
private decidePolicy;
|
|
@@ -141,6 +144,5 @@ export declare class SessionModes extends Service {
|
|
|
141
144
|
private installFor;
|
|
142
145
|
private installDefaultModel;
|
|
143
146
|
}
|
|
144
|
-
export declare function apply(ctx: Context, config: ResolvedConfig): void
|
|
145
|
-
//#endregion
|
|
147
|
+
export declare function apply(ctx: Context, config: ResolvedConfig): Promise<void>;
|
|
146
148
|
export type { PolicyName, ResolvedConfig, SessionMode, SessionModeModel, SessionModePersona, SessionModeRole, SessionModeRoster, SessionModeRow };
|