dsh-edge 0.1.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/LICENSE +21 -0
- package/README.i18n.yaml +6 -0
- package/README.md +183 -0
- package/README.zh.md +183 -0
- package/THIRD_PARTY_NOTICES.md +199 -0
- package/dist/_headers +3 -0
- package/dist/assets/fonts/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
- package/dist/assets/fonts/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
- package/dist/assets/fonts/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
- package/dist/assets/fonts/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
- package/dist/assets/fonts/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
- package/dist/assets/fonts/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
- package/dist/assets/fonts/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
- package/dist/assets/fonts/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
- package/dist/assets/fonts/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
- package/dist/assets/fonts/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
- package/dist/assets/fonts/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
- package/dist/assets/fonts/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
- package/dist/assets/fonts/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
- package/dist/assets/fonts/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
- package/dist/assets/fonts/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
- package/dist/assets/fonts/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
- package/dist/assets/fonts/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
- package/dist/assets/fonts/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
- package/dist/assets/fonts/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
- package/dist/assets/fonts/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
- package/dist/assets/fonts/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
- package/dist/assets/fonts/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
- package/dist/assets/fonts/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
- package/dist/assets/fonts/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
- package/dist/assets/fonts/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
- package/dist/assets/fonts/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
- package/dist/assets/fonts/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
- package/dist/assets/fonts/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
- package/dist/assets/fonts/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
- package/dist/assets/fonts/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
- package/dist/assets/fonts/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
- package/dist/assets/fonts/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
- package/dist/assets/fonts/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
- package/dist/assets/fonts/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
- package/dist/assets/fonts/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
- package/dist/assets/fonts/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
- package/dist/assets/fonts/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
- package/dist/assets/fonts/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
- package/dist/assets/fonts/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
- package/dist/assets/fonts/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
- package/dist/assets/fonts/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
- package/dist/assets/fonts/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
- package/dist/assets/fonts/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
- package/dist/assets/fonts/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
- package/dist/assets/fonts/KaTeX_Script-Regular-D5yQViql.woff +0 -0
- package/dist/assets/fonts/KaTeX_Size1-Regular-C195tn64.woff +0 -0
- package/dist/assets/fonts/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
- package/dist/assets/fonts/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
- package/dist/assets/fonts/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
- package/dist/assets/fonts/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
- package/dist/assets/fonts/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
- package/dist/assets/fonts/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
- package/dist/assets/fonts/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
- package/dist/assets/fonts/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
- package/dist/assets/fonts/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
- package/dist/assets/fonts/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
- package/dist/assets/fonts/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
- package/dist/assets/fonts/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
- package/dist/assets/fonts/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
- package/dist/assets/index-C-1AiF3k.js +112 -0
- package/dist/assets/index-CSGf6Qzd.css +1 -0
- package/dist/assets/langs/c-BIGW1oBm.js +2 -0
- package/dist/assets/langs/cpp-DIPi6g--.js +2 -0
- package/dist/assets/langs/csharp-DSvCPggb.js +2 -0
- package/dist/assets/langs/css-CLj8gQPS.js +2 -0
- package/dist/assets/langs/go-C27-OAKa.js +2 -0
- package/dist/assets/langs/html-CfGypltT.js +2 -0
- package/dist/assets/langs/ini-BEwlwnbL.js +2 -0
- package/dist/assets/langs/java-CylS5w8V.js +2 -0
- package/dist/assets/langs/kotlin-BdnUsdx6.js +2 -0
- package/dist/assets/langs/less-B1dDrJ26.js +2 -0
- package/dist/assets/langs/lua-BaeVxFsk.js +2 -0
- package/dist/assets/langs/markdown-Cvjx9yec.js +2 -0
- package/dist/assets/langs/mdx-Cmh6b_Ma.js +2 -0
- package/dist/assets/langs/php-D-uCvoST.js +2 -0
- package/dist/assets/langs/python-B6aJPvgy.js +2 -0
- package/dist/assets/langs/ruby-DEItuUFs.js +2 -0
- package/dist/assets/langs/rust-B1yitclQ.js +2 -0
- package/dist/assets/langs/scss-D5BDwBP9.js +2 -0
- package/dist/assets/langs/sql-CRqJ_cUM.js +2 -0
- package/dist/assets/langs/swift-D82vCrfD.js +2 -0
- package/dist/assets/langs/toml-vGWfd6FD.js +2 -0
- package/dist/assets/langs/xml-sdJ4AIDG.js +2 -0
- package/dist/assets/langs/yaml-Buea-lGh.js +2 -0
- package/dist/assets/vendor-Cjbwl5VI.js +411 -0
- package/dist/assets/vendor-CjyC-hUb.css +1 -0
- package/dist/favicon.svg +8 -0
- package/dist/index.html +35 -0
- package/dist/manifest.webmanifest +16 -0
- package/dist/plugins/@deepseek-ai/dsh-api-gateway/client.js +420 -0
- package/dist/plugins/@deepseek-ai/dsh-api-remotes/client.js +5937 -0
- package/dist/plugins/@deepseek-ai/dsh-client-connection/client.js +10207 -0
- package/dist/plugins/@deepseek-ai/dsh-client-locale/client.js +1231 -0
- package/dist/plugins/@deepseek-ai/dsh-client-modules/client.js +259 -0
- package/dist/plugins/@deepseek-ai/dsh-client-runtime/client.js +10539 -0
- package/dist/plugins/@deepseek-ai/dsh-client-ui-agent-preset/client.js +1725 -0
- package/dist/plugins/@deepseek-ai/dsh-client-ui-commands/client.js +1116 -0
- package/dist/plugins/@deepseek-ai/dsh-client-ui-conversation/client.js +9832 -0
- package/dist/plugins/@deepseek-ai/dsh-client-ui-deliverables/client.js +373 -0
- package/dist/plugins/@deepseek-ai/dsh-client-ui-edge/client.js +549 -0
- package/dist/plugins/@deepseek-ai/dsh-client-ui-input-trigger/client.js +859 -0
- package/dist/plugins/@deepseek-ai/dsh-client-ui-jobs/client.js +280 -0
- package/dist/plugins/@deepseek-ai/dsh-client-ui-layout/client.js +456 -0
- package/dist/plugins/@deepseek-ai/dsh-client-ui-model-selection/client.js +804 -0
- package/dist/plugins/@deepseek-ai/dsh-client-ui-permission-presets/client.js +461 -0
- package/dist/plugins/@deepseek-ai/dsh-client-ui-settings/client.js +254 -0
- package/dist/plugins/@deepseek-ai/dsh-client-ui-settings-general/client.js +609 -0
- package/dist/plugins/@deepseek-ai/dsh-client-ui-sidebar/client.js +292 -0
- package/dist/plugins/@deepseek-ai/dsh-client-ui-skill/client.js +327 -0
- package/dist/plugins/@deepseek-ai/dsh-client-ui-subagent/client.js +710 -0
- package/dist/plugins/@deepseek-ai/dsh-client-ui-theme/client.js +1312 -0
- package/dist/plugins/@deepseek-ai/dsh-client-ui-tool/client.js +1630 -0
- package/dist/plugins/@deepseek-ai/dsh-client-ui-trajectory/client.js +7370 -0
- package/dist/plugins/@deepseek-ai/dsh-client-ui-user-questions/client.js +700 -0
- package/dist/plugins/@deepseek-ai/dsh-client-ui-workflow-run/client.js +474 -0
- package/dist/plugins/@deepseek-ai/dsh-client-ui-workspace/client.js +2426 -0
- package/dist/plugins/@deepseek-ai/dsh-typert-registry/client.js +1372 -0
- package/package.json +97 -0
- package/scripts/assemble-web.mjs +230 -0
- package/scripts/bundle-size.d.mts +2 -0
- package/scripts/bundle-size.mjs +26 -0
- package/scripts/bundle.mjs +53 -0
- package/scripts/cli.d.mts +39 -0
- package/scripts/cli.mjs +496 -0
- package/scripts/install.d.mts +149 -0
- package/scripts/install.mjs +989 -0
- package/scripts/legal-files.mjs +24 -0
- package/scripts/verify-packed.mjs +32 -0
- package/scripts/wrangler-config.d.mts +18 -0
- package/scripts/wrangler-config.mjs +84 -0
- package/src/agent.ts +119 -0
- package/src/auth.ts +352 -0
- package/src/deepseek.ts +231 -0
- package/src/deployment.ts +147 -0
- package/src/direct-shell-core-empty.ts +10 -0
- package/src/direct-shell-protocol.ts +5 -0
- package/src/direct-shell.ts +341 -0
- package/src/do-session-persistence.ts +1064 -0
- package/src/edge-api.ts +796 -0
- package/src/edge-credentials.ts +56 -0
- package/src/edge-remotes.ts +41 -0
- package/src/edge-workspace-store.ts +339 -0
- package/src/http.ts +212 -0
- package/src/index.ts +196 -0
- package/src/instance.ts +1007 -0
- package/src/isolated-direct-shell-unavailable.ts +11 -0
- package/src/protocol.ts +39 -0
- package/src/release.ts +9 -0
- package/src/session-store.ts +1110 -0
- package/src/sse.ts +86 -0
- package/src/web-search.ts +38 -0
- package/src/workspace.ts +270 -0
- package/wrangler.jsonc +56 -0
|
@@ -0,0 +1,1725 @@
|
|
|
1
|
+
window.__ModuleLoader__.load({
|
|
2
|
+
id: "@deepseek-ai/dsh-client-ui-agent-preset",
|
|
3
|
+
factory: (require) => {
|
|
4
|
+
var module = { exports: {} };
|
|
5
|
+
var exports = module.exports;
|
|
6
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
7
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
8
|
+
let react = require("react");
|
|
9
|
+
let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
10
|
+
let _deepseek_ai_dsh_client_runtime_client = require("@deepseek-ai/dsh-client-runtime/client");
|
|
11
|
+
//#region lib/types/client/locales.js
|
|
12
|
+
/** Locale bundles for the agent-preset settings row, hero chip, header label, and management section. */
|
|
13
|
+
/** English copy. */
|
|
14
|
+
const en = {
|
|
15
|
+
title: "Agent preset",
|
|
16
|
+
description: "Applies to sessions you start from now on. Running sessions keep the preset they began with.",
|
|
17
|
+
loading: "Loading presets…",
|
|
18
|
+
error: "Could not load agent presets.",
|
|
19
|
+
userTrust: "Custom",
|
|
20
|
+
seatHint: "Agent preset for the session you are about to start",
|
|
21
|
+
headerHint: "The agent preset this session runs, fixed when it started",
|
|
22
|
+
nav: "Agent presets",
|
|
23
|
+
sectionIntro: "A preset is the plugin composition one session's agent runs — its tools, prompt, and capabilities. Duplicate an existing one and make it yours, or let the agent draft one for you in Creator mode.",
|
|
24
|
+
builtIn: "Built-in",
|
|
25
|
+
setDefault: "Set as default",
|
|
26
|
+
view: "View",
|
|
27
|
+
presetStandardName: "Standard mode",
|
|
28
|
+
presetStandardDescription: "Full coding agent with file editing, shell, file and web search, skills, planning, goals, subagents, and workflows.",
|
|
29
|
+
presetCodeName: "PTC mode",
|
|
30
|
+
presetCodeDescription: "All Standard mode capabilities, with tools exposed through the Code Mode SDK so the model can combine multi-step operations in one TypeScript program.",
|
|
31
|
+
presetMinimalName: "Minimal mode",
|
|
32
|
+
presetMinimalDescription: "Two-tool coding agent with persistent bash and str_replace_editor.",
|
|
33
|
+
presetCordisName: "Creator mode",
|
|
34
|
+
presetCordisDescription: "Built for creating custom agent presets, with all Standard mode capabilities plus runtime inspection, plugin experiments, and preset-authoring guidance.",
|
|
35
|
+
duplicate: "Duplicate",
|
|
36
|
+
duplicateUnavailable: "This deployment has no writable preset directory",
|
|
37
|
+
delete: "Delete",
|
|
38
|
+
presetId: "Identifier",
|
|
39
|
+
presetIdPlaceholder: "my-agent",
|
|
40
|
+
displayName: "Name",
|
|
41
|
+
displayNamePlaceholder: "Shown in the picker; defaults to the identifier",
|
|
42
|
+
inUse: "In use",
|
|
43
|
+
builtInGroup: "Built-in",
|
|
44
|
+
customGroup: "Custom",
|
|
45
|
+
noDescription: "No description.",
|
|
46
|
+
brokenBadge: "Failed to load",
|
|
47
|
+
brokenNoCopy: "A preset that failed to load cannot be duplicated",
|
|
48
|
+
copyOf: "Copied from",
|
|
49
|
+
composition: "Composition (agent.cordis.yml)",
|
|
50
|
+
cancel: "Cancel",
|
|
51
|
+
close: "Close",
|
|
52
|
+
retry: "Retry",
|
|
53
|
+
copyTitle: "Duplicate preset",
|
|
54
|
+
copyIntro: "The whole preset is copied on this machine. The identifier becomes its directory name and cannot be changed later; everything else is edited in the preset's own files.",
|
|
55
|
+
create: "Create",
|
|
56
|
+
creating: "Creating…",
|
|
57
|
+
creatorDraft: "Draft a custom preset with Creator mode",
|
|
58
|
+
openLocation: "Open folder",
|
|
59
|
+
showLocation: "Show location",
|
|
60
|
+
revealedPathLabel: "Preset files:",
|
|
61
|
+
idRequired: "Give the preset an identifier.",
|
|
62
|
+
idInvalid: "Use lowercase letters, digits, and hyphens, starting with a letter or digit.",
|
|
63
|
+
idTaken: "A preset with this identifier already exists.",
|
|
64
|
+
deleteTitle: "Delete this preset?",
|
|
65
|
+
deleteDescription: "The preset directory is deleted. Sessions already running on it keep working; new sessions cannot select it.",
|
|
66
|
+
deleteConfirm: "Delete",
|
|
67
|
+
deleting: "Deleting…"
|
|
68
|
+
};
|
|
69
|
+
/** Simplified Chinese copy. */
|
|
70
|
+
const zh = {
|
|
71
|
+
title: "Agent 预设",
|
|
72
|
+
description: "对此后新建的会话生效。运行中的会话保持它开始时的预设。",
|
|
73
|
+
loading: "正在加载预设…",
|
|
74
|
+
error: "无法加载 Agent 预设。",
|
|
75
|
+
userTrust: "自定义",
|
|
76
|
+
seatHint: "即将开始的这个会话所用的 Agent 预设",
|
|
77
|
+
headerHint: "本会话运行的 Agent 预设,开始时即固定",
|
|
78
|
+
nav: "Agent 预设",
|
|
79
|
+
sectionIntro: "预设即一个会话的 Agent 所运行的插件组装 —— 它的工具、提示词与能力。复制一份既有预设改成自己的,或用「创造模式」让 Agent 帮你创建。",
|
|
80
|
+
builtIn: "内置",
|
|
81
|
+
setDefault: "设为默认",
|
|
82
|
+
view: "查看",
|
|
83
|
+
presetStandardName: "标准模式",
|
|
84
|
+
presetStandardDescription: "功能完整的编码 Agent,支持文件编辑、Shell、文件与网页检索、Skills、计划、目标、子代理和工作流。",
|
|
85
|
+
presetCodeName: "PTC 模式",
|
|
86
|
+
presetCodeDescription: "具备标准模式的全部能力,并通过 Code Mode SDK 呈现工具,让模型用一个 TypeScript 程序组合多步操作。",
|
|
87
|
+
presetMinimalName: "极简模式",
|
|
88
|
+
presetMinimalDescription: "仅提供持久 bash 与 str_replace_editor 的双工具编码 Agent。",
|
|
89
|
+
presetCordisName: "创造模式",
|
|
90
|
+
presetCordisDescription: "用于创建自定义 Agent preset:具备标准模式的全部能力,并提供运行时检查、插件实验和 preset 创作指导。",
|
|
91
|
+
duplicate: "复制",
|
|
92
|
+
duplicateUnavailable: "此部署未配置可写的预设目录",
|
|
93
|
+
delete: "删除",
|
|
94
|
+
presetId: "标识符",
|
|
95
|
+
presetIdPlaceholder: "my-agent",
|
|
96
|
+
displayName: "名称",
|
|
97
|
+
displayNamePlaceholder: "选择器中显示的名字,缺省用标识符",
|
|
98
|
+
inUse: "当前使用",
|
|
99
|
+
builtInGroup: "内置",
|
|
100
|
+
customGroup: "自定义",
|
|
101
|
+
noDescription: "暂无描述。",
|
|
102
|
+
brokenBadge: "加载失败",
|
|
103
|
+
brokenNoCopy: "预设加载失败,不能复制",
|
|
104
|
+
copyOf: "复制自",
|
|
105
|
+
composition: "组装(agent.cordis.yml)",
|
|
106
|
+
cancel: "取消",
|
|
107
|
+
close: "关闭",
|
|
108
|
+
retry: "重试",
|
|
109
|
+
copyTitle: "复制预设",
|
|
110
|
+
copyIntro: "整个预设会在本机复制一份。标识符将成为目录名,事后无法更改;其余内容之后直接在预设自己的文件里编辑。",
|
|
111
|
+
create: "创建",
|
|
112
|
+
creating: "正在创建…",
|
|
113
|
+
creatorDraft: "用「创造模式」创作自定义预设",
|
|
114
|
+
openLocation: "打开目录",
|
|
115
|
+
showLocation: "查看路径",
|
|
116
|
+
revealedPathLabel: "预设文件:",
|
|
117
|
+
idRequired: "请填写标识符。",
|
|
118
|
+
idInvalid: "只能使用小写字母、数字与连字符,且以字母或数字开头。",
|
|
119
|
+
idTaken: "该标识符已被占用。",
|
|
120
|
+
deleteTitle: "删除该预设?",
|
|
121
|
+
deleteDescription: "预设目录将被删除。已在其上运行的会话不受影响;新会话将无法再选择它。",
|
|
122
|
+
deleteConfirm: "删除",
|
|
123
|
+
deleting: "正在删除…"
|
|
124
|
+
};
|
|
125
|
+
const BUILT_IN_PRESET_KEYS = {
|
|
126
|
+
standard: {
|
|
127
|
+
name: "presetStandardName",
|
|
128
|
+
description: "presetStandardDescription"
|
|
129
|
+
},
|
|
130
|
+
code: {
|
|
131
|
+
name: "presetCodeName",
|
|
132
|
+
description: "presetCodeDescription"
|
|
133
|
+
},
|
|
134
|
+
minimal: {
|
|
135
|
+
name: "presetMinimalName",
|
|
136
|
+
description: "presetMinimalDescription"
|
|
137
|
+
},
|
|
138
|
+
cordis: {
|
|
139
|
+
name: "presetCordisName",
|
|
140
|
+
description: "presetCordisDescription"
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
/**
|
|
144
|
+
* Resolve preset display copy without making user-authored metadata translatable.
|
|
145
|
+
* @param preset - roster row whose copy is being rendered.
|
|
146
|
+
* @param t - active Web locale lookup.
|
|
147
|
+
* @returns localized copy for a known shipped preset, otherwise file metadata.
|
|
148
|
+
*/
|
|
149
|
+
function presetDisplayText(preset, t) {
|
|
150
|
+
const keys = preset.trust === "system" ? BUILT_IN_PRESET_KEYS[preset.id] : void 0;
|
|
151
|
+
if (keys !== void 0) return {
|
|
152
|
+
name: t(keys.name),
|
|
153
|
+
description: t(keys.description)
|
|
154
|
+
};
|
|
155
|
+
return {
|
|
156
|
+
name: preset.name ?? preset.id,
|
|
157
|
+
...preset.description === void 0 ? {} : { description: preset.description }
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
//#endregion
|
|
161
|
+
//#region \0dsh-css:/private/var/folders/nm/n5smty9962gf5rhjc5855kt80000gn/T/dsh-edge-release-worktree.XXXXXX.RcJjogaGt4/repo/packages/client/ui-agent-preset/src/client/AgentPresetLabel.module.css.mjs
|
|
162
|
+
const css$3 = ".pS66sW_label{background:var(--dsw-alias-fill-tsp-secondary);max-width:180px;height:22px;color:var(--dsw-alias-label-secondary);white-space:nowrap;text-overflow:ellipsis;border-radius:6px;align-items:center;gap:4px;padding:0 2px 0 0;font-size:12px;line-height:22px;display:inline-flex;overflow:hidden}.pS66sW_icon{opacity:.7;flex:none}";
|
|
163
|
+
const tagId$3 = "@deepseek-ai/dsh-client-ui-agent-preset/AgentPresetLabel.module.css";
|
|
164
|
+
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$3) + "]") === null) {
|
|
165
|
+
const tag = document.createElement("style");
|
|
166
|
+
tag.dataset.plugin = "@deepseek-ai/dsh-client-ui-agent-preset";
|
|
167
|
+
tag.dataset.pluginCss = tagId$3;
|
|
168
|
+
tag.textContent = css$3;
|
|
169
|
+
document.head.appendChild(tag);
|
|
170
|
+
}
|
|
171
|
+
var AgentPresetLabel_module_css_default = {
|
|
172
|
+
"label": "pS66sW_label",
|
|
173
|
+
"icon": "pS66sW_icon"
|
|
174
|
+
};
|
|
175
|
+
//#endregion
|
|
176
|
+
//#region lib/types/client/AgentPresetLabel.js
|
|
177
|
+
/**
|
|
178
|
+
* The session header's agent-preset label.
|
|
179
|
+
*
|
|
180
|
+
* Read-only by construction: a session's composition is fixed once its
|
|
181
|
+
* conversation starts, and a header is only worth reading after that. Offering
|
|
182
|
+
* a control here would promise a switch the host refuses; naming what the
|
|
183
|
+
* session runs is the honest affordance, and the choice itself lives on the
|
|
184
|
+
* new-session screen ({@link AgentPresetSeat}).
|
|
185
|
+
*/
|
|
186
|
+
/**
|
|
187
|
+
* Render this session's agent-preset name beside its title.
|
|
188
|
+
* @param props - composed slot props.
|
|
189
|
+
* @returns the label, or null when the session records no preset.
|
|
190
|
+
*/
|
|
191
|
+
function AgentPresetLabel({ sessionId, useSessions, useAgentPresets, load, t }) {
|
|
192
|
+
const preset = useSessions((state) => state.byId[sessionId]?.agentPreset);
|
|
193
|
+
const options = useAgentPresets((state) => state.options);
|
|
194
|
+
(0, react.useEffect)(() => {
|
|
195
|
+
if (preset !== void 0) load();
|
|
196
|
+
}, [preset, load]);
|
|
197
|
+
if (preset === void 0) return null;
|
|
198
|
+
const option = options.find((entry) => entry.id === preset);
|
|
199
|
+
const text = option === void 0 ? void 0 : presetDisplayText(option, t);
|
|
200
|
+
return (0, react_jsx_runtime.jsxs)("span", {
|
|
201
|
+
className: AgentPresetLabel_module_css_default.label,
|
|
202
|
+
title: text?.description ?? t("headerHint"),
|
|
203
|
+
children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconAgentPresetOutline16, {
|
|
204
|
+
size: 14,
|
|
205
|
+
className: AgentPresetLabel_module_css_default.icon
|
|
206
|
+
}), text?.name ?? preset]
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
//#endregion
|
|
210
|
+
//#region lib/types/client/PresetMenu.js
|
|
211
|
+
/**
|
|
212
|
+
* The preset picker both surfaces render: a menu of presets over a button
|
|
213
|
+
* naming the current one.
|
|
214
|
+
*
|
|
215
|
+
* The settings row and the composer seat differ in where they sit, what they
|
|
216
|
+
* call the current value, and when they refuse a pick — not in how the picker
|
|
217
|
+
* itself behaves. Trust is the one thing the list always says: a locally
|
|
218
|
+
* authored preset is exactly as privileged as the plugins it names, so the
|
|
219
|
+
* label marks it rather than presenting every preset as shipped and vetted.
|
|
220
|
+
*/
|
|
221
|
+
/**
|
|
222
|
+
* Render the preset picker.
|
|
223
|
+
* @param props - the calling surface's copy, styling, and handlers.
|
|
224
|
+
* @returns the menu and its trigger.
|
|
225
|
+
*/
|
|
226
|
+
function PresetMenu({ options, selectedId, label, t, buttonClassName, chevronClassName, disabled, open, onOpenChange, onSelect }) {
|
|
227
|
+
return (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Menu, {
|
|
228
|
+
open,
|
|
229
|
+
onClose: () => {
|
|
230
|
+
onOpenChange(false);
|
|
231
|
+
},
|
|
232
|
+
items: options.map((option) => {
|
|
233
|
+
const name = presetDisplayText(option, t).name;
|
|
234
|
+
return {
|
|
235
|
+
id: option.id,
|
|
236
|
+
label: option.trust === "user" ? `${name} · ${t("userTrust")}` : name
|
|
237
|
+
};
|
|
238
|
+
}),
|
|
239
|
+
selectedId,
|
|
240
|
+
onSelect: (id) => {
|
|
241
|
+
onOpenChange(false);
|
|
242
|
+
onSelect(id);
|
|
243
|
+
},
|
|
244
|
+
align: "end",
|
|
245
|
+
portal: true,
|
|
246
|
+
anchor: (0, react_jsx_runtime.jsxs)("button", {
|
|
247
|
+
type: "button",
|
|
248
|
+
className: buttonClassName,
|
|
249
|
+
"aria-haspopup": "menu",
|
|
250
|
+
"aria-expanded": open,
|
|
251
|
+
disabled,
|
|
252
|
+
onClick: () => {
|
|
253
|
+
onOpenChange(!open);
|
|
254
|
+
},
|
|
255
|
+
children: [label, (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutline14, { className: chevronClassName })]
|
|
256
|
+
})
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
//#endregion
|
|
260
|
+
//#region \0dsh-css:/private/var/folders/nm/n5smty9962gf5rhjc5855kt80000gn/T/dsh-edge-release-worktree.XXXXXX.RcJjogaGt4/repo/packages/client/ui-agent-preset/src/client/AgentPresetRow.module.css.mjs
|
|
261
|
+
const css$2 = ".nJy-kq_row{border-bottom:1px solid var(--dsw-alias-border-l2);align-items:center;gap:8px;padding:16px 0;display:flex}.nJy-kq_rowText{flex-direction:column;flex:1;gap:4px;min-width:0;padding-right:48px;display:flex}.nJy-kq_title{color:var(--dsw-alias-label-primary);font-size:14px;font-weight:400;line-height:22px}.nJy-kq_desc{color:var(--dsw-alias-label-tertiary);font-size:12px;font-weight:400;line-height:18px}.nJy-kq_selector{background:var(--dsw-alias-bg-module-platform);height:36px;font:inherit;color:var(--dsw-alias-label-primary);cursor:pointer;border:none;border-radius:18px;align-items:center;gap:12px;padding:0 14px;font-size:14px;line-height:22px;display:inline-flex}.nJy-kq_selector:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.nJy-kq_selector:disabled{cursor:default}.nJy-kq_chevron{flex:none}";
|
|
262
|
+
const tagId$2 = "@deepseek-ai/dsh-client-ui-agent-preset/AgentPresetRow.module.css";
|
|
263
|
+
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$2) + "]") === null) {
|
|
264
|
+
const tag = document.createElement("style");
|
|
265
|
+
tag.dataset.plugin = "@deepseek-ai/dsh-client-ui-agent-preset";
|
|
266
|
+
tag.dataset.pluginCss = tagId$2;
|
|
267
|
+
tag.textContent = css$2;
|
|
268
|
+
document.head.appendChild(tag);
|
|
269
|
+
}
|
|
270
|
+
var AgentPresetRow_module_css_default = {
|
|
271
|
+
"desc": "nJy-kq_desc",
|
|
272
|
+
"rowText": "nJy-kq_rowText",
|
|
273
|
+
"selector": "nJy-kq_selector",
|
|
274
|
+
"title": "nJy-kq_title",
|
|
275
|
+
"row": "nJy-kq_row",
|
|
276
|
+
"chevron": "nJy-kq_chevron"
|
|
277
|
+
};
|
|
278
|
+
//#endregion
|
|
279
|
+
//#region lib/types/client/AgentPresetRow.js
|
|
280
|
+
/**
|
|
281
|
+
* Agent-preset preference row: the preset new sessions are composed from.
|
|
282
|
+
* A running session keeps the composition it began with, so this row never
|
|
283
|
+
* disturbs work in progress.
|
|
284
|
+
*/
|
|
285
|
+
/**
|
|
286
|
+
* Render the new-session agent-preset selector.
|
|
287
|
+
* @param props - composed slot props.
|
|
288
|
+
* @returns the row, or null when the deployment composes no presets.
|
|
289
|
+
*/
|
|
290
|
+
function AgentPresetRow({ load, select, useAgentPreset, t }) {
|
|
291
|
+
const state = useAgentPreset((snapshot) => snapshot);
|
|
292
|
+
const [open, setOpen] = (0, react.useState)(false);
|
|
293
|
+
(0, react.useEffect)(() => {
|
|
294
|
+
load();
|
|
295
|
+
}, [load]);
|
|
296
|
+
(0, react.useEffect)(() => {
|
|
297
|
+
if (state.writable && state.status !== "unavailable") return;
|
|
298
|
+
setOpen(false);
|
|
299
|
+
}, [state.status, state.writable]);
|
|
300
|
+
if (state.status === "unavailable") return null;
|
|
301
|
+
const busy = state.status === "loading" || state.status === "saving";
|
|
302
|
+
const chosen = state.options.find((option) => option.id === state.currentValue);
|
|
303
|
+
const chosenText = chosen === void 0 ? void 0 : presetDisplayText(chosen, t);
|
|
304
|
+
const label = state.currentValue === "" ? t("loading") : chosenText?.name ?? state.currentValue;
|
|
305
|
+
const description = state.error ?? t("description");
|
|
306
|
+
return (0, react_jsx_runtime.jsxs)("div", {
|
|
307
|
+
className: AgentPresetRow_module_css_default.row,
|
|
308
|
+
children: [(0, react_jsx_runtime.jsxs)("div", {
|
|
309
|
+
className: AgentPresetRow_module_css_default.rowText,
|
|
310
|
+
children: [(0, react_jsx_runtime.jsx)("div", {
|
|
311
|
+
className: AgentPresetRow_module_css_default.title,
|
|
312
|
+
children: t("title")
|
|
313
|
+
}), (0, react_jsx_runtime.jsx)("div", {
|
|
314
|
+
className: AgentPresetRow_module_css_default.desc,
|
|
315
|
+
role: state.error === null ? void 0 : "alert",
|
|
316
|
+
children: description
|
|
317
|
+
})]
|
|
318
|
+
}), (0, react_jsx_runtime.jsx)(PresetMenu, {
|
|
319
|
+
options: state.options,
|
|
320
|
+
selectedId: state.currentValue,
|
|
321
|
+
label,
|
|
322
|
+
t,
|
|
323
|
+
buttonClassName: AgentPresetRow_module_css_default.selector,
|
|
324
|
+
chevronClassName: AgentPresetRow_module_css_default.chevron,
|
|
325
|
+
disabled: busy || !state.writable || state.options.length === 0,
|
|
326
|
+
open,
|
|
327
|
+
onOpenChange: setOpen,
|
|
328
|
+
onSelect: (id) => {
|
|
329
|
+
select(id);
|
|
330
|
+
}
|
|
331
|
+
})]
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
//#endregion
|
|
335
|
+
//#region \0dsh-css:/private/var/folders/nm/n5smty9962gf5rhjc5855kt80000gn/T/dsh-edge-release-worktree.XXXXXX.RcJjogaGt4/repo/packages/client/ui-agent-preset/src/client/AgentPresetSeat.module.css.mjs
|
|
336
|
+
const css$1 = ".rjnHCa_seat{max-width:min(100%,240px);min-height:28px;color:var(--dsw-alias-label-primary);white-space:nowrap;text-overflow:ellipsis;cursor:pointer;background:0 0;border:none;border-radius:16px;align-items:center;gap:4px;padding:0 8px;font-size:13px;font-weight:500;line-height:20px;display:inline-flex;overflow:hidden}.rjnHCa_seat:not(:disabled):hover,.rjnHCa_seat[aria-expanded=true]{background:var(--dsw-alias-interactive-bg-hover)}.rjnHCa_seat:disabled{cursor:default;color:var(--dsw-alias-label-quaternary)}.rjnHCa_seatIcon{color:var(--dsw-alias-label-primary);flex:none}.rjnHCa_introIcon{animation:.15s cubic-bezier(.16,1,.3,1) both rjnHCa_seat-icon-in}@keyframes rjnHCa_seat-icon-in{0%{opacity:0;transform:scale(.5)}to{opacity:1;transform:scale(1)}}.rjnHCa_introText{white-space:pre;display:inline-block}.rjnHCa_introChar{white-space:pre;opacity:0;animation:.4s ease-out forwards rjnHCa_seat-char-in;display:inline-block}@keyframes rjnHCa_seat-char-in{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}@media (prefers-reduced-motion:reduce){.rjnHCa_introIcon,.rjnHCa_introChar{opacity:1;animation:none}}.rjnHCa_chevron{color:var(--dsw-alias-label-caption);flex:none}.rjnHCa_item{flex-direction:column;gap:2px;max-width:280px;display:flex}.rjnHCa_itemName{color:var(--dsw-alias-label-primary);font-size:13px;line-height:20px}.rjnHCa_itemDesc{color:var(--dsw-alias-label-caption);white-space:normal;font-size:12px;line-height:16px}";
|
|
337
|
+
const tagId$1 = "@deepseek-ai/dsh-client-ui-agent-preset/AgentPresetSeat.module.css";
|
|
338
|
+
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
|
|
339
|
+
const tag = document.createElement("style");
|
|
340
|
+
tag.dataset.plugin = "@deepseek-ai/dsh-client-ui-agent-preset";
|
|
341
|
+
tag.dataset.pluginCss = tagId$1;
|
|
342
|
+
tag.textContent = css$1;
|
|
343
|
+
document.head.appendChild(tag);
|
|
344
|
+
}
|
|
345
|
+
var AgentPresetSeat_module_css_default = {
|
|
346
|
+
"introText": "rjnHCa_introText",
|
|
347
|
+
"item": "rjnHCa_item",
|
|
348
|
+
"seat-icon-in": "rjnHCa_seat-icon-in",
|
|
349
|
+
"seat-char-in": "rjnHCa_seat-char-in",
|
|
350
|
+
"chevron": "rjnHCa_chevron",
|
|
351
|
+
"itemName": "rjnHCa_itemName",
|
|
352
|
+
"seat": "rjnHCa_seat",
|
|
353
|
+
"seatIcon": "rjnHCa_seatIcon",
|
|
354
|
+
"introChar": "rjnHCa_introChar",
|
|
355
|
+
"introIcon": "rjnHCa_introIcon",
|
|
356
|
+
"itemDesc": "rjnHCa_itemDesc"
|
|
357
|
+
};
|
|
358
|
+
//#endregion
|
|
359
|
+
//#region lib/types/client/AgentPresetSeat.js
|
|
360
|
+
/**
|
|
361
|
+
* The agent-preset chip on the new-session screen, beside the workspace
|
|
362
|
+
* picker.
|
|
363
|
+
*
|
|
364
|
+
* It lives here rather than in the composer because the choice is only
|
|
365
|
+
* available before a conversation starts: once a turn has run, the session's
|
|
366
|
+
* history was produced under that preset's tools and the host refuses to swap
|
|
367
|
+
* them. A control that spends most of its life disabled belongs on the screen
|
|
368
|
+
* where it still works.
|
|
369
|
+
*
|
|
370
|
+
* The menu opens on the staged choice, which starts as the deployment default.
|
|
371
|
+
* Picking stages; the choice reaches a session when one becomes current.
|
|
372
|
+
*/
|
|
373
|
+
const INTRO_TEXT_DELAY_MS = 150;
|
|
374
|
+
const INTRO_CHAR_STAGGER_MS = 40;
|
|
375
|
+
const INTRO_TEXT_REVEAL_MS = 200;
|
|
376
|
+
const INTRO_CHAR_FADE_MS = 400;
|
|
377
|
+
/**
|
|
378
|
+
* Per-character start offset for the introduce reveal.
|
|
379
|
+
* @param count - character count of the shown preset name.
|
|
380
|
+
* @returns milliseconds between successive character starts.
|
|
381
|
+
*/
|
|
382
|
+
function introStaggerMs(count) {
|
|
383
|
+
if (count <= 1) return 0;
|
|
384
|
+
return Math.min(INTRO_CHAR_STAGGER_MS, INTRO_TEXT_REVEAL_MS / (count - 1));
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* Render the new-session agent-preset chip.
|
|
388
|
+
* @param props - composed slot props.
|
|
389
|
+
* @returns the chip, or null when the deployment composes no presets.
|
|
390
|
+
*/
|
|
391
|
+
function AgentPresetSeat({ load, select, introduced, useAgentPresetSeat, t }) {
|
|
392
|
+
const state = useAgentPresetSeat((snapshot) => snapshot);
|
|
393
|
+
const [open, setOpen] = (0, react.useState)(false);
|
|
394
|
+
(0, react.useEffect)(() => {
|
|
395
|
+
load();
|
|
396
|
+
}, [load]);
|
|
397
|
+
const chosen = state.options.find((option) => option.id === state.current);
|
|
398
|
+
const label = (chosen === void 0 ? void 0 : presetDisplayText(chosen, t))?.name ?? state.current;
|
|
399
|
+
const ready = state.options.length > 0 && state.current !== "";
|
|
400
|
+
const [introducing, setIntroducing] = (0, react.useState)(false);
|
|
401
|
+
(0, react.useEffect)(() => {
|
|
402
|
+
if (!state.introduce || !ready) return;
|
|
403
|
+
const characters = Array.from(label);
|
|
404
|
+
if (characters.length === 0 || window.matchMedia("(prefers-reduced-motion: reduce)").matches) {
|
|
405
|
+
introduced();
|
|
406
|
+
return;
|
|
407
|
+
}
|
|
408
|
+
setIntroducing(true);
|
|
409
|
+
const done = window.setTimeout(() => {
|
|
410
|
+
setIntroducing(false);
|
|
411
|
+
introduced();
|
|
412
|
+
}, INTRO_TEXT_DELAY_MS + (characters.length - 1) * introStaggerMs(characters.length) + INTRO_CHAR_FADE_MS);
|
|
413
|
+
return () => {
|
|
414
|
+
window.clearTimeout(done);
|
|
415
|
+
};
|
|
416
|
+
}, [
|
|
417
|
+
state.introduce,
|
|
418
|
+
ready,
|
|
419
|
+
label,
|
|
420
|
+
introduced
|
|
421
|
+
]);
|
|
422
|
+
if (!ready) return null;
|
|
423
|
+
const characters = Array.from(label);
|
|
424
|
+
const stagger = introStaggerMs(characters.length);
|
|
425
|
+
const shownLabel = introducing ? (0, react_jsx_runtime.jsx)("span", {
|
|
426
|
+
className: AgentPresetSeat_module_css_default.introText,
|
|
427
|
+
children: characters.map((character, index) => (0, react_jsx_runtime.jsx)("span", {
|
|
428
|
+
className: AgentPresetSeat_module_css_default.introChar,
|
|
429
|
+
style: { animationDelay: `${INTRO_TEXT_DELAY_MS + index * stagger}ms` },
|
|
430
|
+
children: character
|
|
431
|
+
}, index))
|
|
432
|
+
}) : label;
|
|
433
|
+
return (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Menu, {
|
|
434
|
+
open,
|
|
435
|
+
onClose: () => {
|
|
436
|
+
setOpen(false);
|
|
437
|
+
},
|
|
438
|
+
items: state.options.map((option) => {
|
|
439
|
+
const text = presetDisplayText(option, t);
|
|
440
|
+
return {
|
|
441
|
+
id: option.id,
|
|
442
|
+
label: (0, react_jsx_runtime.jsxs)("span", {
|
|
443
|
+
className: AgentPresetSeat_module_css_default.item,
|
|
444
|
+
children: [(0, react_jsx_runtime.jsx)("span", {
|
|
445
|
+
className: AgentPresetSeat_module_css_default.itemName,
|
|
446
|
+
children: text.name
|
|
447
|
+
}), (0, react_jsx_runtime.jsx)("span", {
|
|
448
|
+
className: AgentPresetSeat_module_css_default.itemDesc,
|
|
449
|
+
children: text.description ?? t("noDescription")
|
|
450
|
+
})]
|
|
451
|
+
})
|
|
452
|
+
};
|
|
453
|
+
}),
|
|
454
|
+
selectedId: state.current,
|
|
455
|
+
onSelect: (id) => {
|
|
456
|
+
setOpen(false);
|
|
457
|
+
select(id);
|
|
458
|
+
},
|
|
459
|
+
align: "start",
|
|
460
|
+
portal: true,
|
|
461
|
+
anchor: (0, react_jsx_runtime.jsxs)("button", {
|
|
462
|
+
type: "button",
|
|
463
|
+
className: AgentPresetSeat_module_css_default.seat,
|
|
464
|
+
"aria-haspopup": "menu",
|
|
465
|
+
"aria-expanded": open,
|
|
466
|
+
title: state.error ?? t("seatHint"),
|
|
467
|
+
disabled: state.busy,
|
|
468
|
+
onClick: () => {
|
|
469
|
+
setOpen((value) => !value);
|
|
470
|
+
},
|
|
471
|
+
children: [
|
|
472
|
+
(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconAgentPresetOutline16, { className: introducing ? `${AgentPresetSeat_module_css_default.seatIcon} ${AgentPresetSeat_module_css_default.introIcon}` : AgentPresetSeat_module_css_default.seatIcon }),
|
|
473
|
+
shownLabel,
|
|
474
|
+
(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutline14, { className: AgentPresetSeat_module_css_default.chevron })
|
|
475
|
+
]
|
|
476
|
+
})
|
|
477
|
+
});
|
|
478
|
+
}
|
|
479
|
+
//#endregion
|
|
480
|
+
//#region lib/types/client/settings-store.js
|
|
481
|
+
/**
|
|
482
|
+
* Agent-preset default-settings controller.
|
|
483
|
+
*
|
|
484
|
+
* Options and the current default both come from one `agentPreset.list` call:
|
|
485
|
+
* the roster already reports which id a session with no explicit choice gets,
|
|
486
|
+
* so the row needs no schema introspection. Writes target the settings
|
|
487
|
+
* namespace's `default` field, which is what the host resolves at creation.
|
|
488
|
+
*/
|
|
489
|
+
/** The agent-preset settings namespace on the host wire. */
|
|
490
|
+
const AGENT_PRESET_SETTINGS_NS = "agent-presets";
|
|
491
|
+
/**
|
|
492
|
+
* Human text for a rejected wire call. A transport failure rejects with an
|
|
493
|
+
* Error; a host or a runtime can reject with anything, and the surface still
|
|
494
|
+
* has to say something.
|
|
495
|
+
* @param error - the rejection value.
|
|
496
|
+
* @returns the message to show.
|
|
497
|
+
*/
|
|
498
|
+
function messageOf(error) {
|
|
499
|
+
return error instanceof Error ? error.message : String(error);
|
|
500
|
+
}
|
|
501
|
+
/**
|
|
502
|
+
* Persist one preset as the default for sessions created later.
|
|
503
|
+
*
|
|
504
|
+
* The default is a settings field rather than a preset property, so both the
|
|
505
|
+
* General row and the management section write it here — one home for which
|
|
506
|
+
* namespace and field the host resolves at session creation.
|
|
507
|
+
* @param api - the settings wire face.
|
|
508
|
+
* @param id - the preset to make default.
|
|
509
|
+
* @returns the failure message, or undefined once the write landed.
|
|
510
|
+
*/
|
|
511
|
+
async function writeDefaultPreset(api, id) {
|
|
512
|
+
let response;
|
|
513
|
+
try {
|
|
514
|
+
response = await api.settings.update({
|
|
515
|
+
ns: AGENT_PRESET_SETTINGS_NS,
|
|
516
|
+
patch: { default: id }
|
|
517
|
+
});
|
|
518
|
+
} catch (error) {
|
|
519
|
+
return messageOf(error);
|
|
520
|
+
}
|
|
521
|
+
return response.result.ok ? void 0 : response.result.error.message;
|
|
522
|
+
}
|
|
523
|
+
/**
|
|
524
|
+
* Read the roster, folding both refusal shapes into one message.
|
|
525
|
+
*
|
|
526
|
+
* The wire refuses in two ways — the transport rejects, or it answers an
|
|
527
|
+
* `ok: false` envelope — and every surface treats them identically. Folding
|
|
528
|
+
* them here keeps each store's `load` about what it does with a roster rather
|
|
529
|
+
* than about how the call can fail.
|
|
530
|
+
* @param api - the agent-preset wire face.
|
|
531
|
+
* @returns the roster, or the message to show in its place.
|
|
532
|
+
*/
|
|
533
|
+
async function readRoster(api) {
|
|
534
|
+
try {
|
|
535
|
+
const response = await api.agentPresets.list({});
|
|
536
|
+
return response.result.ok ? {
|
|
537
|
+
ok: true,
|
|
538
|
+
value: response.result.value
|
|
539
|
+
} : {
|
|
540
|
+
ok: false,
|
|
541
|
+
error: response.result.error.message
|
|
542
|
+
};
|
|
543
|
+
} catch (error) {
|
|
544
|
+
return {
|
|
545
|
+
ok: false,
|
|
546
|
+
error: messageOf(error)
|
|
547
|
+
};
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
/**
|
|
551
|
+
* The opening move every roster-backed surface makes: refuse a read that is
|
|
552
|
+
* already in flight, mark the store loading, then read.
|
|
553
|
+
*
|
|
554
|
+
* A surface that gets `undefined` returns without touching its snapshot
|
|
555
|
+
* further — either another read owns it, or this one already wrote the
|
|
556
|
+
* failure. What differs between surfaces starts after this.
|
|
557
|
+
* @param api - the agent-preset wire face.
|
|
558
|
+
* @param store - the surface's own snapshot store.
|
|
559
|
+
* @returns the roster, or undefined when the caller should return.
|
|
560
|
+
*/
|
|
561
|
+
async function beginRosterRead(api, store) {
|
|
562
|
+
const before = store.getSnapshot();
|
|
563
|
+
if (before.status === "loading") return void 0;
|
|
564
|
+
store.set({
|
|
565
|
+
...before,
|
|
566
|
+
status: "loading",
|
|
567
|
+
error: null
|
|
568
|
+
});
|
|
569
|
+
const roster = await readRoster(api);
|
|
570
|
+
if (roster.ok) return roster.value;
|
|
571
|
+
store.set({
|
|
572
|
+
...store.getSnapshot(),
|
|
573
|
+
status: "error",
|
|
574
|
+
error: roster.error
|
|
575
|
+
});
|
|
576
|
+
}
|
|
577
|
+
/**
|
|
578
|
+
* The roster entries as the pickers render them: healthy presets only.
|
|
579
|
+
*
|
|
580
|
+
* The chip and the row exist to choose the NEXT session's composition, and a
|
|
581
|
+
* broken preset cannot compose one — offering it would defer the discovery
|
|
582
|
+
* of that fact to a failed session start. The management section renders the
|
|
583
|
+
* full roster (broken rows included) from its own store instead.
|
|
584
|
+
*
|
|
585
|
+
* The chip, the row, and the management section all show the same facts, and
|
|
586
|
+
* `exactOptionalPropertyTypes` makes "absent" and "present as undefined"
|
|
587
|
+
* different shapes — so the spread dance belongs in one place rather than
|
|
588
|
+
* once per store.
|
|
589
|
+
* @param presets - the roster the host answered with.
|
|
590
|
+
* @returns one option per selectable preset, in roster order.
|
|
591
|
+
*/
|
|
592
|
+
function presetOptions(presets) {
|
|
593
|
+
return presets.filter((preset) => preset.broken === void 0).map((preset) => ({
|
|
594
|
+
id: preset.id,
|
|
595
|
+
trust: preset.trust,
|
|
596
|
+
...preset.name === void 0 ? {} : { name: preset.name },
|
|
597
|
+
...preset.description === void 0 ? {} : { description: preset.description }
|
|
598
|
+
}));
|
|
599
|
+
}
|
|
600
|
+
const INITIAL$2 = {
|
|
601
|
+
status: "idle",
|
|
602
|
+
error: null,
|
|
603
|
+
writable: true,
|
|
604
|
+
currentValue: "",
|
|
605
|
+
options: []
|
|
606
|
+
};
|
|
607
|
+
/** Reads the roster and persists the chosen default. */
|
|
608
|
+
var AgentPresetSettingsController = class {
|
|
609
|
+
api;
|
|
610
|
+
/** Row snapshot the renderer subscribes to. */
|
|
611
|
+
store = (0, _deepseek_ai_dsh_client_runtime_client.createSnapshotStore)(INITIAL$2);
|
|
612
|
+
constructor(api) {
|
|
613
|
+
this.api = api;
|
|
614
|
+
}
|
|
615
|
+
set(patch) {
|
|
616
|
+
this.store.set({
|
|
617
|
+
...this.store.getSnapshot(),
|
|
618
|
+
...patch
|
|
619
|
+
});
|
|
620
|
+
}
|
|
621
|
+
/**
|
|
622
|
+
* Load the roster. An empty roster means the deployment composes no
|
|
623
|
+
* presets, which is a valid deployment rather than a failure — the row
|
|
624
|
+
* reports `unavailable` and renders nothing.
|
|
625
|
+
* @returns once the snapshot reflects the host.
|
|
626
|
+
*/
|
|
627
|
+
async load() {
|
|
628
|
+
const roster = await beginRosterRead(this.api, this.store);
|
|
629
|
+
if (roster === void 0) return;
|
|
630
|
+
const { presets } = roster;
|
|
631
|
+
const [first] = presets;
|
|
632
|
+
if (first === void 0) {
|
|
633
|
+
this.set({
|
|
634
|
+
status: "unavailable",
|
|
635
|
+
options: [],
|
|
636
|
+
currentValue: ""
|
|
637
|
+
});
|
|
638
|
+
return;
|
|
639
|
+
}
|
|
640
|
+
try {
|
|
641
|
+
const described = await this.api.settings.describe({});
|
|
642
|
+
this.set({
|
|
643
|
+
status: "ready",
|
|
644
|
+
error: null,
|
|
645
|
+
writable: described.result.ok && described.result.value.writable,
|
|
646
|
+
options: presetOptions(presets),
|
|
647
|
+
currentValue: presets.find((preset) => preset.isDefault)?.id ?? first.id
|
|
648
|
+
});
|
|
649
|
+
} catch (error) {
|
|
650
|
+
this.set({
|
|
651
|
+
status: "error",
|
|
652
|
+
error: messageOf(error)
|
|
653
|
+
});
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
/**
|
|
657
|
+
* Persist one preset as the default for sessions created later. Running
|
|
658
|
+
* sessions keep the composition they were created with, so this never
|
|
659
|
+
* disturbs work in progress.
|
|
660
|
+
* @param id - the preset to make default.
|
|
661
|
+
* @returns once the write settled and the roster was re-read.
|
|
662
|
+
*/
|
|
663
|
+
async select(id) {
|
|
664
|
+
const before = this.store.getSnapshot();
|
|
665
|
+
if (before.status === "saving" || id === before.currentValue) return;
|
|
666
|
+
this.set({
|
|
667
|
+
status: "saving",
|
|
668
|
+
error: null,
|
|
669
|
+
currentValue: id
|
|
670
|
+
});
|
|
671
|
+
const failure = await writeDefaultPreset(this.api, id);
|
|
672
|
+
if (failure !== void 0) {
|
|
673
|
+
this.set({
|
|
674
|
+
status: "ready",
|
|
675
|
+
currentValue: before.currentValue,
|
|
676
|
+
error: failure
|
|
677
|
+
});
|
|
678
|
+
return;
|
|
679
|
+
}
|
|
680
|
+
await this.load();
|
|
681
|
+
}
|
|
682
|
+
};
|
|
683
|
+
//#endregion
|
|
684
|
+
//#region lib/types/client/section-store.js
|
|
685
|
+
/**
|
|
686
|
+
* Agent-preset management controller: the roster as a list, a copy dialog as
|
|
687
|
+
* the only way a preset is created, and a read-only viewer over the shipped
|
|
688
|
+
* compositions.
|
|
689
|
+
*
|
|
690
|
+
* The browser edits no composition text. A new preset is a host-side copy of
|
|
691
|
+
* an existing one (`{ from, id, name? }` is all that crosses the wire), and
|
|
692
|
+
* everything after creation happens in the preset's own files — which is why
|
|
693
|
+
* the page's other job is getting the user TO those files: open the directory
|
|
694
|
+
* where the host has a desktop, show its path where it does not.
|
|
695
|
+
*
|
|
696
|
+
* The host stays the single fact source. Every mutation writes through the
|
|
697
|
+
* wire and the page re-reads the roster afterwards, because a copy changes
|
|
698
|
+
* more than the row it targeted.
|
|
699
|
+
*/
|
|
700
|
+
/** Ids a preset directory may be named, mirroring the host's own rule. */
|
|
701
|
+
const PRESET_ID = /^[a-z0-9][a-z0-9-]*$/;
|
|
702
|
+
const INITIAL$1 = {
|
|
703
|
+
status: "idle",
|
|
704
|
+
error: null,
|
|
705
|
+
authorable: false,
|
|
706
|
+
hasDocument: false,
|
|
707
|
+
rows: [],
|
|
708
|
+
copy: null,
|
|
709
|
+
view: null,
|
|
710
|
+
pendingDelete: null,
|
|
711
|
+
deleting: false,
|
|
712
|
+
revealedPaths: {}
|
|
713
|
+
};
|
|
714
|
+
/**
|
|
715
|
+
* Why this copy cannot be submitted yet, as a locale key, or undefined when
|
|
716
|
+
* it can. Client-side only: the host re-checks the id and its answer is what
|
|
717
|
+
* the dialog reports on failure.
|
|
718
|
+
* @param draft - the open copy dialog.
|
|
719
|
+
* @param rows - the roster, for the collision check.
|
|
720
|
+
* @returns the blocking reason's locale key, or undefined when submittable.
|
|
721
|
+
*/
|
|
722
|
+
function draftBlocker(draft, rows) {
|
|
723
|
+
if (draft.id === "") return "idRequired";
|
|
724
|
+
if (!PRESET_ID.test(draft.id)) return "idInvalid";
|
|
725
|
+
if (rows.some((row) => row.id === draft.id)) return "idTaken";
|
|
726
|
+
}
|
|
727
|
+
/** Reads the roster and drives the copy dialog, viewer, and location reveals. */
|
|
728
|
+
var AgentPresetSectionController = class {
|
|
729
|
+
api;
|
|
730
|
+
rosterChanged;
|
|
731
|
+
/** Page snapshot the renderer subscribes to. */
|
|
732
|
+
store = (0, _deepseek_ai_dsh_client_runtime_client.createSnapshotStore)(INITIAL$1);
|
|
733
|
+
constructor(api, rosterChanged = () => {}) {
|
|
734
|
+
this.api = api;
|
|
735
|
+
this.rosterChanged = rosterChanged;
|
|
736
|
+
}
|
|
737
|
+
set(patch) {
|
|
738
|
+
this.store.set({
|
|
739
|
+
...this.store.getSnapshot(),
|
|
740
|
+
...patch
|
|
741
|
+
});
|
|
742
|
+
}
|
|
743
|
+
patchCopy(patch) {
|
|
744
|
+
const { copy } = this.store.getSnapshot();
|
|
745
|
+
if (copy === null) return;
|
|
746
|
+
this.set({ copy: {
|
|
747
|
+
...copy,
|
|
748
|
+
...patch
|
|
749
|
+
} });
|
|
750
|
+
}
|
|
751
|
+
/**
|
|
752
|
+
* Load the roster. An empty roster means the deployment composes no
|
|
753
|
+
* presets, which is a valid deployment rather than a failure — the section
|
|
754
|
+
* reports `unavailable` and renders nothing.
|
|
755
|
+
* @returns once the snapshot reflects the host.
|
|
756
|
+
*/
|
|
757
|
+
async load() {
|
|
758
|
+
const roster = await beginRosterRead(this.api, this.store);
|
|
759
|
+
if (roster === void 0) return;
|
|
760
|
+
const { presets, authorable, hasDocument } = roster;
|
|
761
|
+
if (presets.length === 0) {
|
|
762
|
+
this.set({
|
|
763
|
+
status: "unavailable",
|
|
764
|
+
rows: [],
|
|
765
|
+
authorable,
|
|
766
|
+
hasDocument,
|
|
767
|
+
copy: null,
|
|
768
|
+
view: null
|
|
769
|
+
});
|
|
770
|
+
return;
|
|
771
|
+
}
|
|
772
|
+
const revealed = this.store.getSnapshot().revealedPaths;
|
|
773
|
+
const kept = Object.fromEntries(Object.entries(revealed).filter(([id]) => presets.some((preset) => preset.id === id)));
|
|
774
|
+
this.set({
|
|
775
|
+
status: "ready",
|
|
776
|
+
error: null,
|
|
777
|
+
authorable,
|
|
778
|
+
hasDocument,
|
|
779
|
+
rows: presets.map((preset) => ({ ...preset })),
|
|
780
|
+
revealedPaths: kept
|
|
781
|
+
});
|
|
782
|
+
}
|
|
783
|
+
/**
|
|
784
|
+
* Open one shipped preset's composition in the read-only viewer.
|
|
785
|
+
* @param id - the preset to view.
|
|
786
|
+
* @returns once the composition loaded or the failure is on the page.
|
|
787
|
+
*/
|
|
788
|
+
async view(id) {
|
|
789
|
+
this.set({ error: null });
|
|
790
|
+
try {
|
|
791
|
+
const response = await this.api.agentPresets.read({ agentPreset: id });
|
|
792
|
+
if (!response.result.ok) {
|
|
793
|
+
this.set({ error: response.result.error.message });
|
|
794
|
+
return;
|
|
795
|
+
}
|
|
796
|
+
const { name, content } = response.result.value;
|
|
797
|
+
this.set({ view: {
|
|
798
|
+
id,
|
|
799
|
+
title: name ?? id,
|
|
800
|
+
content
|
|
801
|
+
} });
|
|
802
|
+
} catch (error) {
|
|
803
|
+
this.set({ error: messageOf(error) });
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
/** Close the read-only viewer. */
|
|
807
|
+
closeView() {
|
|
808
|
+
this.set({ view: null });
|
|
809
|
+
}
|
|
810
|
+
/**
|
|
811
|
+
* Open the copy dialog over one preset.
|
|
812
|
+
* @param from - the preset the copy will start from.
|
|
813
|
+
*/
|
|
814
|
+
beginCopy(from) {
|
|
815
|
+
const row = this.store.getSnapshot().rows.find((candidate) => candidate.id === from);
|
|
816
|
+
this.set({
|
|
817
|
+
error: null,
|
|
818
|
+
copy: {
|
|
819
|
+
from,
|
|
820
|
+
fromTitle: row?.name ?? from,
|
|
821
|
+
id: "",
|
|
822
|
+
name: "",
|
|
823
|
+
saving: false,
|
|
824
|
+
error: null
|
|
825
|
+
}
|
|
826
|
+
});
|
|
827
|
+
}
|
|
828
|
+
/** Close the copy dialog, discarding whatever was typed. */
|
|
829
|
+
cancelCopy() {
|
|
830
|
+
this.set({ copy: null });
|
|
831
|
+
}
|
|
832
|
+
/**
|
|
833
|
+
* Name the preset the copy creates.
|
|
834
|
+
* @param id - the id typed into the dialog.
|
|
835
|
+
*/
|
|
836
|
+
setCopyId(id) {
|
|
837
|
+
this.patchCopy({
|
|
838
|
+
id,
|
|
839
|
+
error: null
|
|
840
|
+
});
|
|
841
|
+
}
|
|
842
|
+
/**
|
|
843
|
+
* Name the copy's display name.
|
|
844
|
+
* @param name - the display name typed into the dialog.
|
|
845
|
+
*/
|
|
846
|
+
setCopyName(name) {
|
|
847
|
+
this.patchCopy({
|
|
848
|
+
name,
|
|
849
|
+
error: null
|
|
850
|
+
});
|
|
851
|
+
}
|
|
852
|
+
/**
|
|
853
|
+
* Submit the copy, re-read the roster, then take the user to the new
|
|
854
|
+
* preset's files — the directory opens where the host has a desktop, and
|
|
855
|
+
* its path appears on the new row where it does not.
|
|
856
|
+
* @returns once the copy settled and the page reflects it.
|
|
857
|
+
*/
|
|
858
|
+
async confirmCopy() {
|
|
859
|
+
const draft = this.store.getSnapshot().copy;
|
|
860
|
+
if (draft === null || draft.saving) return;
|
|
861
|
+
if (draftBlocker(draft, this.store.getSnapshot().rows) !== void 0) return;
|
|
862
|
+
this.patchCopy({
|
|
863
|
+
saving: true,
|
|
864
|
+
error: null
|
|
865
|
+
});
|
|
866
|
+
try {
|
|
867
|
+
const name = draft.name.trim();
|
|
868
|
+
const response = await this.api.agentPresets.copy({
|
|
869
|
+
from: draft.from,
|
|
870
|
+
agentPreset: draft.id,
|
|
871
|
+
...name === "" ? {} : { name }
|
|
872
|
+
});
|
|
873
|
+
if (!response.result.ok) {
|
|
874
|
+
this.patchCopy({
|
|
875
|
+
saving: false,
|
|
876
|
+
error: response.result.error.message
|
|
877
|
+
});
|
|
878
|
+
return;
|
|
879
|
+
}
|
|
880
|
+
this.set({ copy: null });
|
|
881
|
+
await this.load();
|
|
882
|
+
this.rosterChanged();
|
|
883
|
+
await this.openLocation(draft.id);
|
|
884
|
+
} catch (error) {
|
|
885
|
+
this.patchCopy({
|
|
886
|
+
saving: false,
|
|
887
|
+
error: messageOf(error)
|
|
888
|
+
});
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
/**
|
|
892
|
+
* Open one preset's directory on the host desktop, or reveal its path on
|
|
893
|
+
* the row where the deployment has no opener to hand it to.
|
|
894
|
+
* @param id - the preset whose files the user wants.
|
|
895
|
+
* @returns once the host answered and the page reflects it.
|
|
896
|
+
*/
|
|
897
|
+
async openLocation(id) {
|
|
898
|
+
try {
|
|
899
|
+
const response = await this.api.agentPresets.openDocument({ agentPreset: id });
|
|
900
|
+
if (!response.result.ok) {
|
|
901
|
+
this.set({ error: response.result.error.message });
|
|
902
|
+
return;
|
|
903
|
+
}
|
|
904
|
+
if (response.result.value.opened) return;
|
|
905
|
+
const { path } = response.result.value;
|
|
906
|
+
this.set({ revealedPaths: {
|
|
907
|
+
...this.store.getSnapshot().revealedPaths,
|
|
908
|
+
[id]: path
|
|
909
|
+
} });
|
|
910
|
+
} catch (error) {
|
|
911
|
+
this.set({ error: messageOf(error) });
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
/**
|
|
915
|
+
* Ask for confirmation before deleting one preset.
|
|
916
|
+
* @param id - the preset to delete, or null to dismiss the confirmation.
|
|
917
|
+
*/
|
|
918
|
+
confirmDelete(id) {
|
|
919
|
+
if (this.store.getSnapshot().deleting) return;
|
|
920
|
+
this.set({ pendingDelete: id });
|
|
921
|
+
}
|
|
922
|
+
/**
|
|
923
|
+
* Delete the preset awaiting confirmation, then re-read the roster.
|
|
924
|
+
*
|
|
925
|
+
* A session already composed from it keeps running: its composition was
|
|
926
|
+
* mounted at creation and nothing re-reads the file.
|
|
927
|
+
* @returns once the delete settled and the page reflects it.
|
|
928
|
+
*/
|
|
929
|
+
async remove() {
|
|
930
|
+
const { pendingDelete, deleting } = this.store.getSnapshot();
|
|
931
|
+
if (pendingDelete === null || deleting) return;
|
|
932
|
+
this.set({
|
|
933
|
+
deleting: true,
|
|
934
|
+
error: null
|
|
935
|
+
});
|
|
936
|
+
try {
|
|
937
|
+
const response = await this.api.agentPresets.remove({ agentPreset: pendingDelete });
|
|
938
|
+
if (!response.result.ok) {
|
|
939
|
+
this.set({
|
|
940
|
+
deleting: false,
|
|
941
|
+
pendingDelete: null,
|
|
942
|
+
error: response.result.error.message
|
|
943
|
+
});
|
|
944
|
+
return;
|
|
945
|
+
}
|
|
946
|
+
this.set({
|
|
947
|
+
deleting: false,
|
|
948
|
+
pendingDelete: null
|
|
949
|
+
});
|
|
950
|
+
await this.load();
|
|
951
|
+
this.rosterChanged();
|
|
952
|
+
} catch (error) {
|
|
953
|
+
this.set({
|
|
954
|
+
deleting: false,
|
|
955
|
+
pendingDelete: null,
|
|
956
|
+
error: messageOf(error)
|
|
957
|
+
});
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
/**
|
|
961
|
+
* Make one preset the default for sessions created later. Running sessions
|
|
962
|
+
* keep the composition they began with, so this never disturbs work.
|
|
963
|
+
* @param id - the preset to make default.
|
|
964
|
+
* @returns once the write settled and the roster was re-read.
|
|
965
|
+
*/
|
|
966
|
+
async makeDefault(id) {
|
|
967
|
+
const failure = await writeDefaultPreset(this.api, id);
|
|
968
|
+
if (failure !== void 0) {
|
|
969
|
+
this.set({ error: failure });
|
|
970
|
+
return;
|
|
971
|
+
}
|
|
972
|
+
await this.load();
|
|
973
|
+
}
|
|
974
|
+
};
|
|
975
|
+
//#endregion
|
|
976
|
+
//#region \0dsh-css:/private/var/folders/nm/n5smty9962gf5rhjc5855kt80000gn/T/dsh-edge-release-worktree.XXXXXX.RcJjogaGt4/repo/packages/client/ui-agent-preset/src/client/AgentPresetSection.module.css.mjs
|
|
977
|
+
const css = ".V0QFfq_section{max-width:720px;color:var(--dsw-alias-label-primary);flex-direction:column;gap:12px;display:flex}.V0QFfq_title{margin:0;font-size:18px;font-weight:600}.V0QFfq_intro{color:var(--dsw-alias-label-tertiary);margin:0;font-size:13px}.V0QFfq_group{flex-direction:column;gap:10px;display:flex}.V0QFfq_group+.V0QFfq_group{margin-top:20px}.V0QFfq_groupHead{letter-spacing:.06em;text-transform:uppercase;color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;font-weight:600}.V0QFfq_cards{grid-template-columns:repeat(auto-fill,minmax(268px,1fr));grid-auto-rows:1fr;gap:12px;margin:0;padding:0;list-style:none;display:grid}.V0QFfq_card{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:12px;flex-direction:column;transition:border-color .16s,background .16s;display:flex}.V0QFfq_card:hover:not(.V0QFfq_cardActive){border-color:var(--dsw-alias-label-dimmed)}.V0QFfq_cardActive{background:var(--dsw-alias-bg-layer-2);border-color:var(--dsw-alias-label-primary)}.V0QFfq_cardBroken,.V0QFfq_cardBroken:hover{border-color:var(--dsw-alias-state-error-primary)}.V0QFfq_brokenBadge{white-space:nowrap;background:var(--dsw-alias-state-error-primary);color:var(--dsw-alias-bg-layer-3);border-radius:999px;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px}.V0QFfq_cardBrokenReason{color:var(--dsw-alias-state-error-primary);overflow-wrap:anywhere;font-size:12px;line-height:1.5}.V0QFfq_cardMain{appearance:none;font:inherit;color:inherit;text-align:left;cursor:pointer;background:0 0;border:0;border-radius:12px 12px 0 0;flex-direction:column;flex:1;gap:8px;padding:14px 16px 12px;display:flex}.V0QFfq_cardMain:disabled{cursor:default}.V0QFfq_cardMain:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:-2px}.V0QFfq_cardHead{align-items:center;gap:8px;display:flex}.V0QFfq_cardName{font-size:15px;font-weight:600;line-height:1.4}.V0QFfq_badge,.V0QFfq_inUse{white-space:nowrap;border-radius:999px;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px}.V0QFfq_badge{border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-tertiary)}.V0QFfq_inUse{background:var(--dsw-alias-label-primary);color:var(--dsw-alias-bg-layer-3);margin-left:auto}.V0QFfq_cardDesc{color:var(--dsw-alias-label-secondary);-webkit-line-clamp:4;overflow-wrap:anywhere;-webkit-box-orient:vertical;min-height:42px;font-size:13px;line-height:1.55;display:-webkit-box;overflow:hidden}.V0QFfq_cardId{font-family:var(--dsw-font-mono,ui-monospace, SFMono-Regular, Menlo, monospace);color:var(--dsw-alias-label-dimmed);margin-top:auto;font-size:11px}.V0QFfq_cardFoot{border-top:1px solid var(--dsw-alias-border-l2);justify-content:flex-end;gap:2px;padding:6px 10px;display:flex}.V0QFfq_iconButton{appearance:none;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:0;border-radius:7px;align-items:center;padding:6px;display:inline-flex;position:relative}.V0QFfq_iconButton:disabled{opacity:.4;cursor:default}.V0QFfq_iconButton:hover:not(:disabled){background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary)}.V0QFfq_iconButton:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:-1px}.V0QFfq_iconButton:after{content:attr(data-tip);background:var(--dsw-alias-label-primary);color:var(--dsw-alias-bg-layer-3);white-space:nowrap;opacity:0;pointer-events:none;border-radius:6px;padding:3px 8px;font-size:11px;line-height:17px;transition:opacity .12s;position:absolute;bottom:calc(100% + 6px);left:50%;transform:translate(-50%)}.V0QFfq_iconButton:hover:after,.V0QFfq_iconButton:focus-visible:after{opacity:1}.V0QFfq_iconDanger:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover-danger);color:var(--dsw-alias-state-error-primary)}.V0QFfq_revealedPath{color:var(--dsw-alias-label-tertiary);align-items:baseline;gap:6px;margin:0;padding:6px 16px 10px;font-size:11px;display:flex}.V0QFfq_revealedPath code{font-family:var(--dsw-font-mono,ui-monospace, SFMono-Regular, Menlo, monospace);color:var(--dsw-alias-label-secondary);user-select:all;overflow-wrap:anywhere}.V0QFfq_revealedPathLabel{white-space:nowrap}.V0QFfq_secondaryButton{color:var(--dsw-alias-label-secondary);font:inherit;cursor:pointer;background:0 0;border:none;border-radius:7px;padding:5px 8px;font-size:12.5px}.V0QFfq_secondaryButton:hover:not(:disabled){background:var(--dsw-alias-bg-layer-1)}.V0QFfq_secondaryButton:disabled{opacity:.5;cursor:default}.V0QFfq_field{flex-direction:column;gap:6px;display:flex}.V0QFfq_fieldLabel{color:var(--dsw-alias-label-secondary);font-size:12px;font-weight:500}.V0QFfq_input{box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2);font:inherit;background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);border-radius:10px;padding:9px 12px;font-size:13px}.V0QFfq_input:focus{border-color:var(--dsw-alias-brand-primary);outline:none}.V0QFfq_input::placeholder{color:var(--dsw-alias-label-dimmed)}.V0QFfq_dialog{width:min(560px,100%)}.V0QFfq_dialogFields{flex-direction:column;gap:12px;display:flex}.V0QFfq_viewerCode{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);max-height:min(52vh,480px);color:var(--dsw-alias-label-secondary);font-family:var(--dsw-font-mono,ui-monospace, SFMono-Regular, Menlo, monospace);white-space:pre;tab-size:2;--dsh-scrollbar-thumb:var(--dsw-alias-scrollbar-bg-l2);--dsh-scrollbar-thumb-hover:var(--dsw-alias-scrollbar-hover-l2);border-radius:10px;margin:0;padding:12px;font-size:12.5px;line-height:1.5;overflow:auto}.V0QFfq_error{color:var(--dsw-alias-state-error-primary);margin:0;font-size:12px}.V0QFfq_deleteDialog{width:min(480px,100%)}.V0QFfq_deleteConfirm:not(:disabled){border-color:var(--dsw-alias-state-error-primary);color:var(--dsw-alias-state-error-primary)}.V0QFfq_deleteConfirm:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover-danger)}.V0QFfq_creatorButton{box-sizing:border-box;border:1px dashed var(--dsw-alias-border-l3);height:44px;font:inherit;color:var(--dsw-alias-label-primary);cursor:pointer;background:0 0;border-radius:12px;justify-content:center;align-self:stretch;align-items:center;gap:6px;font-size:14px;line-height:22px;display:flex}.V0QFfq_creatorButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.V0QFfq_creatorButton:disabled{opacity:.4;cursor:default}";
|
|
978
|
+
const tagId = "@deepseek-ai/dsh-client-ui-agent-preset/AgentPresetSection.module.css";
|
|
979
|
+
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
980
|
+
const tag = document.createElement("style");
|
|
981
|
+
tag.dataset.plugin = "@deepseek-ai/dsh-client-ui-agent-preset";
|
|
982
|
+
tag.dataset.pluginCss = tagId;
|
|
983
|
+
tag.textContent = css;
|
|
984
|
+
document.head.appendChild(tag);
|
|
985
|
+
}
|
|
986
|
+
var AgentPresetSection_module_css_default = {
|
|
987
|
+
"deleteConfirm": "V0QFfq_deleteConfirm",
|
|
988
|
+
"cardId": "V0QFfq_cardId",
|
|
989
|
+
"input": "V0QFfq_input",
|
|
990
|
+
"intro": "V0QFfq_intro",
|
|
991
|
+
"cardBrokenReason": "V0QFfq_cardBrokenReason",
|
|
992
|
+
"error": "V0QFfq_error",
|
|
993
|
+
"cardHead": "V0QFfq_cardHead",
|
|
994
|
+
"brokenBadge": "V0QFfq_brokenBadge",
|
|
995
|
+
"cardName": "V0QFfq_cardName",
|
|
996
|
+
"cards": "V0QFfq_cards",
|
|
997
|
+
"dialogFields": "V0QFfq_dialogFields",
|
|
998
|
+
"cardActive": "V0QFfq_cardActive",
|
|
999
|
+
"cardBroken": "V0QFfq_cardBroken",
|
|
1000
|
+
"cardDesc": "V0QFfq_cardDesc",
|
|
1001
|
+
"creatorButton": "V0QFfq_creatorButton",
|
|
1002
|
+
"iconButton": "V0QFfq_iconButton",
|
|
1003
|
+
"cardMain": "V0QFfq_cardMain",
|
|
1004
|
+
"revealedPath": "V0QFfq_revealedPath",
|
|
1005
|
+
"viewerCode": "V0QFfq_viewerCode",
|
|
1006
|
+
"inUse": "V0QFfq_inUse",
|
|
1007
|
+
"title": "V0QFfq_title",
|
|
1008
|
+
"badge": "V0QFfq_badge",
|
|
1009
|
+
"revealedPathLabel": "V0QFfq_revealedPathLabel",
|
|
1010
|
+
"fieldLabel": "V0QFfq_fieldLabel",
|
|
1011
|
+
"group": "V0QFfq_group",
|
|
1012
|
+
"field": "V0QFfq_field",
|
|
1013
|
+
"deleteDialog": "V0QFfq_deleteDialog",
|
|
1014
|
+
"groupHead": "V0QFfq_groupHead",
|
|
1015
|
+
"dialog": "V0QFfq_dialog",
|
|
1016
|
+
"secondaryButton": "V0QFfq_secondaryButton",
|
|
1017
|
+
"cardFoot": "V0QFfq_cardFoot",
|
|
1018
|
+
"iconDanger": "V0QFfq_iconDanger",
|
|
1019
|
+
"section": "V0QFfq_section",
|
|
1020
|
+
"card": "V0QFfq_card"
|
|
1021
|
+
};
|
|
1022
|
+
//#endregion
|
|
1023
|
+
//#region lib/types/client/AgentPresetSection.js
|
|
1024
|
+
/**
|
|
1025
|
+
* Agent-presets settings section: the roster as cards, a copy dialog as the
|
|
1026
|
+
* only way a preset is created, and a read-only viewer over the shipped
|
|
1027
|
+
* compositions.
|
|
1028
|
+
*
|
|
1029
|
+
* The browser edits no composition text — a shipped preset opens read-only to
|
|
1030
|
+
* be READ (it is the known-good composition a copy starts from), and a custom
|
|
1031
|
+
* preset is edited in its own files, which is what the location action leads
|
|
1032
|
+
* to. Deleting a preset leaves running sessions alone: a composition is
|
|
1033
|
+
* mounted once at session creation and nothing re-reads the file.
|
|
1034
|
+
*/
|
|
1035
|
+
function CopyDialog({ state, t, actions }) {
|
|
1036
|
+
const draft = state.copy;
|
|
1037
|
+
const blocker = draft === null ? void 0 : draftBlocker(draft, state.rows);
|
|
1038
|
+
const message = draft === null ? null : draft.error ?? (blocker === void 0 ? null : t(blocker));
|
|
1039
|
+
const source = draft === null ? void 0 : state.rows.find((row) => row.id === draft.from);
|
|
1040
|
+
const sourceTitle = source === void 0 ? draft?.fromTitle : presetDisplayText(source, t).name;
|
|
1041
|
+
return (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
|
|
1042
|
+
open: draft !== null,
|
|
1043
|
+
onClose: () => {
|
|
1044
|
+
actions.cancelCopy();
|
|
1045
|
+
},
|
|
1046
|
+
title: draft === null ? t("copyTitle") : `${t("copyTitle")} · ${t("copyOf")} ${sourceTitle}`,
|
|
1047
|
+
closeLabel: t("close"),
|
|
1048
|
+
description: t("copyIntro"),
|
|
1049
|
+
className: AgentPresetSection_module_css_default.dialog,
|
|
1050
|
+
footer: (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1051
|
+
variant: "outline",
|
|
1052
|
+
disabled: draft?.saving === true,
|
|
1053
|
+
onClick: () => {
|
|
1054
|
+
actions.cancelCopy();
|
|
1055
|
+
},
|
|
1056
|
+
children: t("cancel")
|
|
1057
|
+
}), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1058
|
+
disabled: draft === null || draft.saving || blocker !== void 0,
|
|
1059
|
+
onClick: () => {
|
|
1060
|
+
actions.confirmCopy();
|
|
1061
|
+
},
|
|
1062
|
+
children: draft?.saving === true ? t("creating") : t("create")
|
|
1063
|
+
})] }),
|
|
1064
|
+
children: draft === null ? null : (0, react_jsx_runtime.jsxs)("div", {
|
|
1065
|
+
className: AgentPresetSection_module_css_default.dialogFields,
|
|
1066
|
+
children: [
|
|
1067
|
+
(0, react_jsx_runtime.jsxs)("label", {
|
|
1068
|
+
className: AgentPresetSection_module_css_default.field,
|
|
1069
|
+
children: [(0, react_jsx_runtime.jsx)("span", {
|
|
1070
|
+
className: AgentPresetSection_module_css_default.fieldLabel,
|
|
1071
|
+
children: t("presetId")
|
|
1072
|
+
}), (0, react_jsx_runtime.jsx)("input", {
|
|
1073
|
+
className: AgentPresetSection_module_css_default.input,
|
|
1074
|
+
value: draft.id,
|
|
1075
|
+
autoFocus: true,
|
|
1076
|
+
spellCheck: false,
|
|
1077
|
+
placeholder: t("presetIdPlaceholder"),
|
|
1078
|
+
onChange: (event) => {
|
|
1079
|
+
actions.setCopyId(event.target.value);
|
|
1080
|
+
}
|
|
1081
|
+
})]
|
|
1082
|
+
}),
|
|
1083
|
+
(0, react_jsx_runtime.jsxs)("label", {
|
|
1084
|
+
className: AgentPresetSection_module_css_default.field,
|
|
1085
|
+
children: [(0, react_jsx_runtime.jsx)("span", {
|
|
1086
|
+
className: AgentPresetSection_module_css_default.fieldLabel,
|
|
1087
|
+
children: t("displayName")
|
|
1088
|
+
}), (0, react_jsx_runtime.jsx)("input", {
|
|
1089
|
+
className: AgentPresetSection_module_css_default.input,
|
|
1090
|
+
value: draft.name,
|
|
1091
|
+
spellCheck: false,
|
|
1092
|
+
placeholder: t("displayNamePlaceholder"),
|
|
1093
|
+
onChange: (event) => {
|
|
1094
|
+
actions.setCopyName(event.target.value);
|
|
1095
|
+
}
|
|
1096
|
+
})]
|
|
1097
|
+
}),
|
|
1098
|
+
message === null ? null : (0, react_jsx_runtime.jsx)("p", {
|
|
1099
|
+
className: AgentPresetSection_module_css_default.error,
|
|
1100
|
+
role: "alert",
|
|
1101
|
+
children: message
|
|
1102
|
+
})
|
|
1103
|
+
]
|
|
1104
|
+
})
|
|
1105
|
+
});
|
|
1106
|
+
}
|
|
1107
|
+
/**
|
|
1108
|
+
* Render one card's description, clamped by CSS and offered in full on hover.
|
|
1109
|
+
* The tooltip is attached only while the text is actually cut off, so a short
|
|
1110
|
+
* description does not answer a hover with a bubble repeating the card.
|
|
1111
|
+
* @param props.text - the description as rendered, already localized.
|
|
1112
|
+
* @returns the description element, tooltip-anchored while it overflows.
|
|
1113
|
+
*/
|
|
1114
|
+
function CardDescription({ text }) {
|
|
1115
|
+
const ref = (0, react.useRef)(null);
|
|
1116
|
+
const [truncated, setTruncated] = (0, react.useState)(false);
|
|
1117
|
+
(0, react.useLayoutEffect)(() => {
|
|
1118
|
+
const el = ref.current;
|
|
1119
|
+
/* v8 ignore next -- the ref is attached before layout effects run. */
|
|
1120
|
+
if (el === null) return;
|
|
1121
|
+
const measure = () => {
|
|
1122
|
+
setTruncated(el.scrollHeight > el.clientHeight);
|
|
1123
|
+
};
|
|
1124
|
+
measure();
|
|
1125
|
+
if (typeof ResizeObserver === "undefined") return;
|
|
1126
|
+
const observer = new ResizeObserver(measure);
|
|
1127
|
+
observer.observe(el);
|
|
1128
|
+
return () => {
|
|
1129
|
+
observer.disconnect();
|
|
1130
|
+
};
|
|
1131
|
+
}, [text]);
|
|
1132
|
+
return (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
|
|
1133
|
+
label: text,
|
|
1134
|
+
side: "bottom",
|
|
1135
|
+
delayMs: 400,
|
|
1136
|
+
disabled: !truncated,
|
|
1137
|
+
maxWidth: 360,
|
|
1138
|
+
children: (0, react_jsx_runtime.jsx)("span", {
|
|
1139
|
+
ref,
|
|
1140
|
+
className: AgentPresetSection_module_css_default.cardDesc,
|
|
1141
|
+
title: "",
|
|
1142
|
+
children: text
|
|
1143
|
+
})
|
|
1144
|
+
});
|
|
1145
|
+
}
|
|
1146
|
+
/**
|
|
1147
|
+
* Render the Agent presets section content column.
|
|
1148
|
+
* @param props - composed slot props.
|
|
1149
|
+
* @returns the section, or null when the deployment composes no presets.
|
|
1150
|
+
*/
|
|
1151
|
+
function AgentPresetSection(props) {
|
|
1152
|
+
const { useAgentPresetSection, t, load } = props;
|
|
1153
|
+
const state = useAgentPresetSection((snapshot) => snapshot);
|
|
1154
|
+
const viewedId = state.view?.id;
|
|
1155
|
+
const viewedRow = viewedId === void 0 ? void 0 : state.rows.find((row) => row.id === viewedId);
|
|
1156
|
+
const viewedTitle = state.view === null ? "" : viewedRow === void 0 ? state.view.title : presetDisplayText(viewedRow, t).name;
|
|
1157
|
+
(0, react.useEffect)(() => {
|
|
1158
|
+
load();
|
|
1159
|
+
}, [load]);
|
|
1160
|
+
if (state.status === "unavailable") return null;
|
|
1161
|
+
if (state.status === "error") {
|
|
1162
|
+
/* v8 ignore next -- an error status always carries text; the fallback satisfies the nullable type */
|
|
1163
|
+
const detail = state.error ?? "";
|
|
1164
|
+
return (0, react_jsx_runtime.jsxs)("div", {
|
|
1165
|
+
className: AgentPresetSection_module_css_default.section,
|
|
1166
|
+
children: [(0, react_jsx_runtime.jsx)("p", {
|
|
1167
|
+
className: AgentPresetSection_module_css_default.error,
|
|
1168
|
+
role: "alert",
|
|
1169
|
+
children: `${t("error")} ${detail}`
|
|
1170
|
+
}), (0, react_jsx_runtime.jsx)("button", {
|
|
1171
|
+
type: "button",
|
|
1172
|
+
className: AgentPresetSection_module_css_default.secondaryButton,
|
|
1173
|
+
onClick: () => {
|
|
1174
|
+
load();
|
|
1175
|
+
},
|
|
1176
|
+
children: t("retry")
|
|
1177
|
+
})]
|
|
1178
|
+
});
|
|
1179
|
+
}
|
|
1180
|
+
const creatorButton = props.startCreatorDraft !== void 0 && state.rows.some((row) => row.id === "cordis") ? (0, react_jsx_runtime.jsxs)("button", {
|
|
1181
|
+
type: "button",
|
|
1182
|
+
className: AgentPresetSection_module_css_default.creatorButton,
|
|
1183
|
+
disabled: !state.authorable,
|
|
1184
|
+
title: state.authorable ? void 0 : t("duplicateUnavailable"),
|
|
1185
|
+
onClick: () => {
|
|
1186
|
+
props.startCreatorDraft?.();
|
|
1187
|
+
props.close();
|
|
1188
|
+
},
|
|
1189
|
+
children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconPlusOutline16, { size: 14 }), t("creatorDraft")]
|
|
1190
|
+
}) : null;
|
|
1191
|
+
return (0, react_jsx_runtime.jsxs)("div", {
|
|
1192
|
+
className: AgentPresetSection_module_css_default.section,
|
|
1193
|
+
children: [
|
|
1194
|
+
(0, react_jsx_runtime.jsx)("h2", {
|
|
1195
|
+
className: AgentPresetSection_module_css_default.title,
|
|
1196
|
+
children: t("nav")
|
|
1197
|
+
}),
|
|
1198
|
+
(0, react_jsx_runtime.jsx)("p", {
|
|
1199
|
+
className: AgentPresetSection_module_css_default.intro,
|
|
1200
|
+
children: t("sectionIntro")
|
|
1201
|
+
}),
|
|
1202
|
+
state.error === null ? null : (0, react_jsx_runtime.jsx)("p", {
|
|
1203
|
+
className: AgentPresetSection_module_css_default.error,
|
|
1204
|
+
role: "alert",
|
|
1205
|
+
children: state.error
|
|
1206
|
+
}),
|
|
1207
|
+
[["system", t("builtInGroup")], ["user", t("customGroup")]].map(([trust, heading]) => {
|
|
1208
|
+
const group = state.rows.filter((row) => row.trust === trust).map((row) => ({
|
|
1209
|
+
row,
|
|
1210
|
+
text: presetDisplayText(row, t)
|
|
1211
|
+
}));
|
|
1212
|
+
const tail = trust === "user" ? creatorButton : null;
|
|
1213
|
+
if (group.length === 0 && tail === null) return null;
|
|
1214
|
+
return (0, react_jsx_runtime.jsxs)("section", {
|
|
1215
|
+
className: AgentPresetSection_module_css_default.group,
|
|
1216
|
+
children: [
|
|
1217
|
+
(0, react_jsx_runtime.jsx)("h3", {
|
|
1218
|
+
className: AgentPresetSection_module_css_default.groupHead,
|
|
1219
|
+
children: heading
|
|
1220
|
+
}),
|
|
1221
|
+
group.length === 0 ? null : (0, react_jsx_runtime.jsx)("ul", {
|
|
1222
|
+
className: AgentPresetSection_module_css_default.cards,
|
|
1223
|
+
children: group.map(({ row, text }) => (0, react_jsx_runtime.jsxs)("li", {
|
|
1224
|
+
className: row.broken !== void 0 ? `${AgentPresetSection_module_css_default.card} ${AgentPresetSection_module_css_default.cardBroken}` : row.isDefault ? `${AgentPresetSection_module_css_default.card} ${AgentPresetSection_module_css_default.cardActive}` : AgentPresetSection_module_css_default.card,
|
|
1225
|
+
children: [
|
|
1226
|
+
(0, react_jsx_runtime.jsxs)("button", {
|
|
1227
|
+
type: "button",
|
|
1228
|
+
className: AgentPresetSection_module_css_default.cardMain,
|
|
1229
|
+
"aria-pressed": row.isDefault,
|
|
1230
|
+
disabled: row.isDefault || row.broken !== void 0,
|
|
1231
|
+
"aria-label": `${row.broken !== void 0 ? t("brokenBadge") : row.isDefault ? t("inUse") : t("setDefault")}: ${text.name}`,
|
|
1232
|
+
title: row.broken ?? (row.isDefault ? t("inUse") : t("setDefault")),
|
|
1233
|
+
onClick: () => {
|
|
1234
|
+
props.makeDefault(row.id);
|
|
1235
|
+
},
|
|
1236
|
+
children: [
|
|
1237
|
+
(0, react_jsx_runtime.jsxs)("span", {
|
|
1238
|
+
className: AgentPresetSection_module_css_default.cardHead,
|
|
1239
|
+
children: [
|
|
1240
|
+
(0, react_jsx_runtime.jsx)("span", {
|
|
1241
|
+
className: AgentPresetSection_module_css_default.cardName,
|
|
1242
|
+
children: text.name
|
|
1243
|
+
}),
|
|
1244
|
+
row.broken !== void 0 ? (0, react_jsx_runtime.jsx)("span", {
|
|
1245
|
+
className: AgentPresetSection_module_css_default.brokenBadge,
|
|
1246
|
+
children: t("brokenBadge")
|
|
1247
|
+
}) : null,
|
|
1248
|
+
(0, react_jsx_runtime.jsx)("span", {
|
|
1249
|
+
className: AgentPresetSection_module_css_default.badge,
|
|
1250
|
+
children: row.trust === "user" ? t("userTrust") : t("builtIn")
|
|
1251
|
+
}),
|
|
1252
|
+
row.isDefault ? (0, react_jsx_runtime.jsx)("span", {
|
|
1253
|
+
className: AgentPresetSection_module_css_default.inUse,
|
|
1254
|
+
children: t("inUse")
|
|
1255
|
+
}) : null
|
|
1256
|
+
]
|
|
1257
|
+
}),
|
|
1258
|
+
(0, react_jsx_runtime.jsx)(CardDescription, { text: text.description ?? t("noDescription") }),
|
|
1259
|
+
row.broken === void 0 ? null : (0, react_jsx_runtime.jsx)("span", {
|
|
1260
|
+
className: AgentPresetSection_module_css_default.cardBrokenReason,
|
|
1261
|
+
role: "alert",
|
|
1262
|
+
children: row.broken
|
|
1263
|
+
}),
|
|
1264
|
+
(0, react_jsx_runtime.jsx)("code", {
|
|
1265
|
+
className: AgentPresetSection_module_css_default.cardId,
|
|
1266
|
+
children: row.id
|
|
1267
|
+
})
|
|
1268
|
+
]
|
|
1269
|
+
}),
|
|
1270
|
+
(0, react_jsx_runtime.jsxs)("div", {
|
|
1271
|
+
className: AgentPresetSection_module_css_default.cardFoot,
|
|
1272
|
+
children: [
|
|
1273
|
+
row.trust === "system" ? row.broken === void 0 ? (0, react_jsx_runtime.jsx)("button", {
|
|
1274
|
+
type: "button",
|
|
1275
|
+
className: AgentPresetSection_module_css_default.iconButton,
|
|
1276
|
+
"data-tip": t("view"),
|
|
1277
|
+
"aria-label": `${t("view")}: ${text.name}`,
|
|
1278
|
+
onClick: () => {
|
|
1279
|
+
props.view(row.id);
|
|
1280
|
+
},
|
|
1281
|
+
children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconBrowseOutline16, {})
|
|
1282
|
+
}) : null : (0, react_jsx_runtime.jsx)("button", {
|
|
1283
|
+
type: "button",
|
|
1284
|
+
className: AgentPresetSection_module_css_default.iconButton,
|
|
1285
|
+
"data-tip": state.hasDocument ? t("openLocation") : t("showLocation"),
|
|
1286
|
+
"aria-label": `${state.hasDocument ? t("openLocation") : t("showLocation")}: ${text.name}`,
|
|
1287
|
+
onClick: () => {
|
|
1288
|
+
props.openLocation(row.id);
|
|
1289
|
+
},
|
|
1290
|
+
children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconFolderOpenOutline16, {})
|
|
1291
|
+
}),
|
|
1292
|
+
(0, react_jsx_runtime.jsx)("button", {
|
|
1293
|
+
type: "button",
|
|
1294
|
+
className: AgentPresetSection_module_css_default.iconButton,
|
|
1295
|
+
disabled: !state.authorable || row.broken !== void 0,
|
|
1296
|
+
"data-tip": row.broken !== void 0 ? t("brokenNoCopy") : state.authorable ? t("duplicate") : t("duplicateUnavailable"),
|
|
1297
|
+
"aria-label": `${t("duplicate")}: ${text.name}`,
|
|
1298
|
+
onClick: () => {
|
|
1299
|
+
props.beginCopy(row.id);
|
|
1300
|
+
},
|
|
1301
|
+
children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconCopyOutline16, {})
|
|
1302
|
+
}),
|
|
1303
|
+
row.trust === "user" ? (0, react_jsx_runtime.jsx)("button", {
|
|
1304
|
+
type: "button",
|
|
1305
|
+
className: `${AgentPresetSection_module_css_default.iconButton} ${AgentPresetSection_module_css_default.iconDanger}`,
|
|
1306
|
+
"data-tip": t("delete"),
|
|
1307
|
+
"aria-label": `${t("delete")}: ${text.name}`,
|
|
1308
|
+
onClick: () => {
|
|
1309
|
+
props.confirmDelete(row.id);
|
|
1310
|
+
},
|
|
1311
|
+
children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconTrashOutline16, {})
|
|
1312
|
+
}) : null
|
|
1313
|
+
]
|
|
1314
|
+
}),
|
|
1315
|
+
state.revealedPaths[row.id] === void 0 ? null : (0, react_jsx_runtime.jsxs)("p", {
|
|
1316
|
+
className: AgentPresetSection_module_css_default.revealedPath,
|
|
1317
|
+
children: [(0, react_jsx_runtime.jsx)("span", {
|
|
1318
|
+
className: AgentPresetSection_module_css_default.revealedPathLabel,
|
|
1319
|
+
children: t("revealedPathLabel")
|
|
1320
|
+
}), (0, react_jsx_runtime.jsx)("code", { children: state.revealedPaths[row.id] })]
|
|
1321
|
+
})
|
|
1322
|
+
]
|
|
1323
|
+
}, row.id))
|
|
1324
|
+
}),
|
|
1325
|
+
tail
|
|
1326
|
+
]
|
|
1327
|
+
}, trust);
|
|
1328
|
+
}),
|
|
1329
|
+
(0, react_jsx_runtime.jsx)(CopyDialog, {
|
|
1330
|
+
state,
|
|
1331
|
+
t,
|
|
1332
|
+
actions: {
|
|
1333
|
+
cancelCopy: props.cancelCopy,
|
|
1334
|
+
confirmCopy: props.confirmCopy,
|
|
1335
|
+
setCopyId: props.setCopyId,
|
|
1336
|
+
setCopyName: props.setCopyName
|
|
1337
|
+
}
|
|
1338
|
+
}),
|
|
1339
|
+
(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
|
|
1340
|
+
open: state.view !== null,
|
|
1341
|
+
onClose: () => {
|
|
1342
|
+
props.closeView();
|
|
1343
|
+
},
|
|
1344
|
+
title: state.view === null ? "" : `${t("view")} · ${viewedTitle}`,
|
|
1345
|
+
closeLabel: t("close"),
|
|
1346
|
+
description: t("composition"),
|
|
1347
|
+
className: AgentPresetSection_module_css_default.dialog,
|
|
1348
|
+
footer: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1349
|
+
variant: "outline",
|
|
1350
|
+
autoFocus: true,
|
|
1351
|
+
onClick: () => {
|
|
1352
|
+
props.closeView();
|
|
1353
|
+
},
|
|
1354
|
+
children: t("close")
|
|
1355
|
+
}),
|
|
1356
|
+
children: state.view === null ? null : (0, react_jsx_runtime.jsx)("pre", {
|
|
1357
|
+
className: AgentPresetSection_module_css_default.viewerCode,
|
|
1358
|
+
children: state.view.content
|
|
1359
|
+
})
|
|
1360
|
+
}),
|
|
1361
|
+
(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
|
|
1362
|
+
open: state.pendingDelete !== null,
|
|
1363
|
+
onClose: () => {
|
|
1364
|
+
props.confirmDelete(null);
|
|
1365
|
+
},
|
|
1366
|
+
title: t("deleteTitle"),
|
|
1367
|
+
closeLabel: t("close"),
|
|
1368
|
+
description: t("deleteDescription"),
|
|
1369
|
+
className: AgentPresetSection_module_css_default.deleteDialog,
|
|
1370
|
+
footer: (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1371
|
+
variant: "outline",
|
|
1372
|
+
autoFocus: true,
|
|
1373
|
+
disabled: state.deleting,
|
|
1374
|
+
onClick: () => {
|
|
1375
|
+
props.confirmDelete(null);
|
|
1376
|
+
},
|
|
1377
|
+
children: t("cancel")
|
|
1378
|
+
}), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1379
|
+
variant: "outline",
|
|
1380
|
+
className: AgentPresetSection_module_css_default.deleteConfirm,
|
|
1381
|
+
disabled: state.deleting,
|
|
1382
|
+
onClick: () => {
|
|
1383
|
+
props.remove();
|
|
1384
|
+
},
|
|
1385
|
+
children: state.deleting ? t("deleting") : t("deleteConfirm")
|
|
1386
|
+
})] })
|
|
1387
|
+
})
|
|
1388
|
+
]
|
|
1389
|
+
});
|
|
1390
|
+
}
|
|
1391
|
+
//#endregion
|
|
1392
|
+
//#region lib/types/client/seat-store.js
|
|
1393
|
+
/**
|
|
1394
|
+
* Hero-chip controller: which preset the NEXT session gets.
|
|
1395
|
+
*
|
|
1396
|
+
* The new-session screen has no session, so a pick is staged rather than
|
|
1397
|
+
* applied. It reaches a session when one becomes current and is still blank —
|
|
1398
|
+
* whether the workspace connect created it or reused an existing blank one,
|
|
1399
|
+
* which is why staging cannot simply ride along on `sessions.create`.
|
|
1400
|
+
*
|
|
1401
|
+
* The stage is forgotten once applied: the next new session starts from the
|
|
1402
|
+
* deployment default again, matching the workspace picker beside it.
|
|
1403
|
+
*/
|
|
1404
|
+
const INITIAL = {
|
|
1405
|
+
options: [],
|
|
1406
|
+
current: "",
|
|
1407
|
+
error: null,
|
|
1408
|
+
busy: false,
|
|
1409
|
+
introduce: false
|
|
1410
|
+
};
|
|
1411
|
+
/** Stages the next session's preset and applies it when one appears. */
|
|
1412
|
+
var AgentPresetSeatController = class {
|
|
1413
|
+
api;
|
|
1414
|
+
currentSession;
|
|
1415
|
+
onApplied;
|
|
1416
|
+
/** Chip snapshot the renderer subscribes to. */
|
|
1417
|
+
store = (0, _deepseek_ai_dsh_client_runtime_client.createSnapshotStore)(INITIAL);
|
|
1418
|
+
/**
|
|
1419
|
+
* The deployment default, so a consumed stage can fall back to it without
|
|
1420
|
+
* re-reading the roster.
|
|
1421
|
+
*/
|
|
1422
|
+
fallback = "";
|
|
1423
|
+
/** Set while a pick is waiting for a session; cleared once applied. */
|
|
1424
|
+
staged;
|
|
1425
|
+
constructor(api, currentSession, onApplied) {
|
|
1426
|
+
this.api = api;
|
|
1427
|
+
this.currentSession = currentSession;
|
|
1428
|
+
this.onApplied = onApplied;
|
|
1429
|
+
}
|
|
1430
|
+
set(patch) {
|
|
1431
|
+
this.store.set({
|
|
1432
|
+
...this.store.getSnapshot(),
|
|
1433
|
+
...patch
|
|
1434
|
+
});
|
|
1435
|
+
}
|
|
1436
|
+
/**
|
|
1437
|
+
* Read the roster and open the chip on the deployment default.
|
|
1438
|
+
* @returns once the snapshot reflects the host.
|
|
1439
|
+
*/
|
|
1440
|
+
async load() {
|
|
1441
|
+
try {
|
|
1442
|
+
const response = await this.api.agentPresets.list({});
|
|
1443
|
+
if (!response.result.ok) {
|
|
1444
|
+
this.set({ error: response.result.error.message });
|
|
1445
|
+
return;
|
|
1446
|
+
}
|
|
1447
|
+
const { presets } = response.result.value;
|
|
1448
|
+
this.fallback = presets.find((preset) => preset.isDefault)?.id ?? presets[0]?.id ?? "";
|
|
1449
|
+
this.set({
|
|
1450
|
+
options: presetOptions(presets),
|
|
1451
|
+
current: this.staged ?? this.currentSession()?.agentPreset ?? this.fallback,
|
|
1452
|
+
error: null
|
|
1453
|
+
});
|
|
1454
|
+
} catch (error) {
|
|
1455
|
+
this.set({ error: messageOf(error) });
|
|
1456
|
+
}
|
|
1457
|
+
}
|
|
1458
|
+
/**
|
|
1459
|
+
* Stage one preset for the next session, applying it immediately when a
|
|
1460
|
+
* blank session is already current.
|
|
1461
|
+
* @param id - the preset to stage.
|
|
1462
|
+
* @returns once the stage settled, and the apply too when one happened.
|
|
1463
|
+
*/
|
|
1464
|
+
async select(id) {
|
|
1465
|
+
if (this.store.getSnapshot().busy) return;
|
|
1466
|
+
this.stage(id);
|
|
1467
|
+
await this.apply();
|
|
1468
|
+
}
|
|
1469
|
+
/**
|
|
1470
|
+
* Stage a pick WITHOUT the immediate apply, for a flow that starts the
|
|
1471
|
+
* receiving session after the pick (the settings section's creator entry).
|
|
1472
|
+
* `select()`'s immediate apply would meet the still-current running session
|
|
1473
|
+
* and drop the stage as unservable; staging alone leaves it for the
|
|
1474
|
+
* list-change applier, which fires when the started session becomes
|
|
1475
|
+
* current.
|
|
1476
|
+
* @param id - the preset to stage.
|
|
1477
|
+
* @param introduce - true when the stage came from another screen and the
|
|
1478
|
+
* chip should announce itself on the session it lands on.
|
|
1479
|
+
*/
|
|
1480
|
+
stage(id, introduce = false) {
|
|
1481
|
+
this.staged = id;
|
|
1482
|
+
this.set({
|
|
1483
|
+
current: id,
|
|
1484
|
+
error: null,
|
|
1485
|
+
introduce
|
|
1486
|
+
});
|
|
1487
|
+
}
|
|
1488
|
+
/** Acknowledge the introduction cue once the chip has played it. */
|
|
1489
|
+
introduced() {
|
|
1490
|
+
if (!this.store.getSnapshot().introduce) return;
|
|
1491
|
+
this.set({ introduce: false });
|
|
1492
|
+
}
|
|
1493
|
+
/**
|
|
1494
|
+
* Hand the staged choice to the current session, if there is one to take it.
|
|
1495
|
+
*
|
|
1496
|
+
* Called both by `select()` and by whoever observes the current session
|
|
1497
|
+
* changing, because the session may appear either before or after the pick.
|
|
1498
|
+
* @returns once the switch settled, or immediately when there is nothing to do.
|
|
1499
|
+
*/
|
|
1500
|
+
async apply() {
|
|
1501
|
+
const staged = this.staged;
|
|
1502
|
+
const session = this.currentSession();
|
|
1503
|
+
if (staged === void 0 || session === void 0) return;
|
|
1504
|
+
if (!session.blank || session.agentPreset === staged) {
|
|
1505
|
+
this.staged = void 0;
|
|
1506
|
+
return;
|
|
1507
|
+
}
|
|
1508
|
+
this.set({
|
|
1509
|
+
busy: true,
|
|
1510
|
+
error: null
|
|
1511
|
+
});
|
|
1512
|
+
try {
|
|
1513
|
+
const response = await this.api.agentPresets.select({
|
|
1514
|
+
sessionId: session.id,
|
|
1515
|
+
agentPreset: staged
|
|
1516
|
+
});
|
|
1517
|
+
this.staged = void 0;
|
|
1518
|
+
if (!response.result.ok) {
|
|
1519
|
+
this.set({
|
|
1520
|
+
busy: false,
|
|
1521
|
+
error: response.result.error.message,
|
|
1522
|
+
current: this.fallback
|
|
1523
|
+
});
|
|
1524
|
+
return;
|
|
1525
|
+
}
|
|
1526
|
+
this.set({
|
|
1527
|
+
busy: false,
|
|
1528
|
+
current: response.result.value.agentPreset
|
|
1529
|
+
});
|
|
1530
|
+
this.onApplied?.(session.id, response.result.value.agentPreset);
|
|
1531
|
+
} catch (error) {
|
|
1532
|
+
this.staged = void 0;
|
|
1533
|
+
this.set({
|
|
1534
|
+
busy: false,
|
|
1535
|
+
error: messageOf(error),
|
|
1536
|
+
current: this.fallback
|
|
1537
|
+
});
|
|
1538
|
+
}
|
|
1539
|
+
}
|
|
1540
|
+
};
|
|
1541
|
+
//#endregion
|
|
1542
|
+
//#region lib/types/client/index.js
|
|
1543
|
+
/**
|
|
1544
|
+
* Agent-preset surface plugin, browser half — four surfaces over one roster:
|
|
1545
|
+
* a General-settings row for the default preset, a chip on the new-session
|
|
1546
|
+
* screen for the session about to start, a read-only label in the session
|
|
1547
|
+
* header, and a settings section that manages the roster (copy, delete,
|
|
1548
|
+
* default, and the way into a preset's own files).
|
|
1549
|
+
*
|
|
1550
|
+
* A running session keeps the composition it began with (the host refuses to
|
|
1551
|
+
* adopt an existing session under a different preset). That is what splits
|
|
1552
|
+
* the choice from the display: the General row and the hero chip are both
|
|
1553
|
+
* before-the-fact, while the header only reports what a session already runs.
|
|
1554
|
+
*/
|
|
1555
|
+
/** Required services (cordis fiber inject). */
|
|
1556
|
+
const inject = [
|
|
1557
|
+
"slots",
|
|
1558
|
+
"locale",
|
|
1559
|
+
"connection",
|
|
1560
|
+
"remote"
|
|
1561
|
+
];
|
|
1562
|
+
/**
|
|
1563
|
+
* Mount the General-settings row.
|
|
1564
|
+
* @param ctx - the browser plugin context.
|
|
1565
|
+
*/
|
|
1566
|
+
function apply(ctx) {
|
|
1567
|
+
const { api } = ctx.get("connection");
|
|
1568
|
+
const controller = new AgentPresetSettingsController(api);
|
|
1569
|
+
const rosterReaders = /* @__PURE__ */ new Set();
|
|
1570
|
+
const section = new AgentPresetSectionController(api, () => {
|
|
1571
|
+
controller.load();
|
|
1572
|
+
for (const read of rosterReaders) read();
|
|
1573
|
+
});
|
|
1574
|
+
ctx.effect(() => ctx.locale.register("settings.agentPreset", {
|
|
1575
|
+
zh,
|
|
1576
|
+
en
|
|
1577
|
+
}), "ui-agent-preset: settings row dictionaries");
|
|
1578
|
+
const injected = () => ({
|
|
1579
|
+
hooks: { agentPreset: controller.store },
|
|
1580
|
+
load: () => controller.load(),
|
|
1581
|
+
select: (id) => controller.select(id)
|
|
1582
|
+
});
|
|
1583
|
+
ctx.effect(() => {
|
|
1584
|
+
const refresh = () => {
|
|
1585
|
+
controller.load();
|
|
1586
|
+
if (section.store.getSnapshot().status !== "idle") section.load();
|
|
1587
|
+
};
|
|
1588
|
+
const disposers = [ctx.remote.$on("settings/document-updated", (ns) => {
|
|
1589
|
+
if (ns !== "agent-presets") return;
|
|
1590
|
+
refresh();
|
|
1591
|
+
}), ctx.on("connection/reset", () => {
|
|
1592
|
+
refresh();
|
|
1593
|
+
})];
|
|
1594
|
+
return () => {
|
|
1595
|
+
for (const dispose of disposers) dispose();
|
|
1596
|
+
};
|
|
1597
|
+
}, "ui-agent-preset: settings refresh");
|
|
1598
|
+
let creatorDraft;
|
|
1599
|
+
ctx.inject([
|
|
1600
|
+
"slots",
|
|
1601
|
+
"conversation",
|
|
1602
|
+
"sessions",
|
|
1603
|
+
"workspaces"
|
|
1604
|
+
], (scope) => {
|
|
1605
|
+
const api = scope.get("connection").api;
|
|
1606
|
+
const seat = new AgentPresetSeatController(api, () => {
|
|
1607
|
+
const state = scope.sessions.list.getSnapshot();
|
|
1608
|
+
const summary = state.current === void 0 ? void 0 : state.byId[state.current];
|
|
1609
|
+
return summary === void 0 ? void 0 : {
|
|
1610
|
+
id: summary.id,
|
|
1611
|
+
blank: summary.blank,
|
|
1612
|
+
...summary.agentPreset === void 0 ? {} : { agentPreset: summary.agentPreset }
|
|
1613
|
+
};
|
|
1614
|
+
}, (sessionId, agentPreset) => {
|
|
1615
|
+
scope.sessions.noteAgentPreset(sessionId, agentPreset);
|
|
1616
|
+
});
|
|
1617
|
+
const seatInjected = () => ({
|
|
1618
|
+
hooks: { agentPresetSeat: seat.store },
|
|
1619
|
+
load: () => seat.load(),
|
|
1620
|
+
select: (id) => seat.select(id),
|
|
1621
|
+
introduced: () => {
|
|
1622
|
+
seat.introduced();
|
|
1623
|
+
}
|
|
1624
|
+
});
|
|
1625
|
+
const labelInjected = () => ({
|
|
1626
|
+
hooks: { agentPresets: controller.store },
|
|
1627
|
+
load: () => controller.load()
|
|
1628
|
+
});
|
|
1629
|
+
scope.effect(() => {
|
|
1630
|
+
const stop = scope.sessions.list.subscribe(() => {
|
|
1631
|
+
seat.apply();
|
|
1632
|
+
});
|
|
1633
|
+
const settingsMoved = scope.remote.$on("settings/document-updated", (ns) => {
|
|
1634
|
+
if (ns !== "agent-presets") return;
|
|
1635
|
+
seat.load();
|
|
1636
|
+
});
|
|
1637
|
+
const presetSelected = scope.remote.$on("agent-preset/selected", (sessionId, agentPreset) => {
|
|
1638
|
+
scope.sessions.noteAgentPreset(sessionId, agentPreset);
|
|
1639
|
+
});
|
|
1640
|
+
const readRoster = () => {
|
|
1641
|
+
seat.load();
|
|
1642
|
+
};
|
|
1643
|
+
rosterReaders.add(readRoster);
|
|
1644
|
+
creatorDraft = () => {
|
|
1645
|
+
seat.stage("cordis", true);
|
|
1646
|
+
scope.workspaces.startSession();
|
|
1647
|
+
};
|
|
1648
|
+
const chip = scope.slots.register({
|
|
1649
|
+
name: "conversation.hero.agentPreset",
|
|
1650
|
+
locale: "settings.agentPreset",
|
|
1651
|
+
inject: seatInjected
|
|
1652
|
+
}, AgentPresetSeat);
|
|
1653
|
+
const label = scope.slots.register({
|
|
1654
|
+
name: "conversation.session.header.actions",
|
|
1655
|
+
id: "agent-preset",
|
|
1656
|
+
order: -10,
|
|
1657
|
+
locale: "settings.agentPreset",
|
|
1658
|
+
inject: labelInjected
|
|
1659
|
+
}, AgentPresetLabel);
|
|
1660
|
+
return () => {
|
|
1661
|
+
stop();
|
|
1662
|
+
settingsMoved();
|
|
1663
|
+
presetSelected();
|
|
1664
|
+
rosterReaders.delete(readRoster);
|
|
1665
|
+
creatorDraft = void 0;
|
|
1666
|
+
chip();
|
|
1667
|
+
label();
|
|
1668
|
+
};
|
|
1669
|
+
}, "ui-agent-preset: new-session chip and header label");
|
|
1670
|
+
});
|
|
1671
|
+
const sectionInjected = () => ({
|
|
1672
|
+
hooks: { agentPresetSection: section.store },
|
|
1673
|
+
load: () => section.load(),
|
|
1674
|
+
view: (id) => section.view(id),
|
|
1675
|
+
closeView: () => {
|
|
1676
|
+
section.closeView();
|
|
1677
|
+
},
|
|
1678
|
+
beginCopy: (from) => {
|
|
1679
|
+
section.beginCopy(from);
|
|
1680
|
+
},
|
|
1681
|
+
cancelCopy: () => {
|
|
1682
|
+
section.cancelCopy();
|
|
1683
|
+
},
|
|
1684
|
+
setCopyId: (id) => {
|
|
1685
|
+
section.setCopyId(id);
|
|
1686
|
+
},
|
|
1687
|
+
setCopyName: (name) => {
|
|
1688
|
+
section.setCopyName(name);
|
|
1689
|
+
},
|
|
1690
|
+
confirmCopy: () => section.confirmCopy(),
|
|
1691
|
+
openLocation: (id) => section.openLocation(id),
|
|
1692
|
+
...creatorDraft === void 0 ? {} : { startCreatorDraft: creatorDraft },
|
|
1693
|
+
confirmDelete: (id) => {
|
|
1694
|
+
section.confirmDelete(id);
|
|
1695
|
+
},
|
|
1696
|
+
remove: () => section.remove(),
|
|
1697
|
+
makeDefault: (id) => section.makeDefault(id)
|
|
1698
|
+
});
|
|
1699
|
+
ctx.slots.inject("settings.general.item", () => ctx.slots.register({
|
|
1700
|
+
name: "settings.general.item",
|
|
1701
|
+
id: "agent-preset",
|
|
1702
|
+
order: -25,
|
|
1703
|
+
locale: "settings.agentPreset",
|
|
1704
|
+
inject: injected
|
|
1705
|
+
}, AgentPresetRow));
|
|
1706
|
+
ctx.slots.inject("settings.section", () => ctx.slots.register({
|
|
1707
|
+
name: "settings.section",
|
|
1708
|
+
id: "agent-presets",
|
|
1709
|
+
order: 20,
|
|
1710
|
+
label: () => ctx.locale.bind("settings.agentPreset")("nav"),
|
|
1711
|
+
locale: "settings.agentPreset",
|
|
1712
|
+
inject: sectionInjected
|
|
1713
|
+
}, AgentPresetSection));
|
|
1714
|
+
}
|
|
1715
|
+
//#endregion
|
|
1716
|
+
exports.AGENT_PRESET_SETTINGS_NS = AGENT_PRESET_SETTINGS_NS;
|
|
1717
|
+
exports.apply = apply;
|
|
1718
|
+
exports.draftBlocker = draftBlocker;
|
|
1719
|
+
exports.inject = inject;
|
|
1720
|
+
exports.writeDefaultPreset = writeDefaultPreset;
|
|
1721
|
+
return module.exports;
|
|
1722
|
+
}
|
|
1723
|
+
});
|
|
1724
|
+
|
|
1725
|
+
//# sourceMappingURL=client.js.map
|