@carljia/omd-dsh 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.
@@ -0,0 +1,270 @@
1
+ import z from "@deepseek-ai/schemastery";
2
+ import { defineTool } from "@deepseek-ai/dsh-tools";
3
+ import { assertSubagentMaxDepth } from "@deepseek-ai/dsh-subagent";
4
+ import { scopeOf } from "@deepseek-ai/dsh-scope";
5
+ /**
6
+ * @module @carljia/omd-dsh/task
7
+ *
8
+ * omd-task: tiered subagent delegation tool (the DSH-native equivalent of
9
+ * OMD task(category=...)).
10
+ *
11
+ * The shipped dsh-tool-subagent pins ONE model/persona/toolFilter per tool
12
+ * instance, so a model cannot choose a model per call. DSH subagents
13
+ * service DOES accept per-request agentOptions/persona/toolFilter, and this
14
+ * row exposes that: the model passes a tier argument per call, and each
15
+ * tier maps to a fixed worker profile (provider/model/maxTokens/persona/
16
+ * toolFilter). Strong models stay at the top level while cheap tiers do
17
+ * repetitive investigation work -- differentiated invocation inside one
18
+ * mode, configured entirely in the preset YAML.
19
+ */
20
+ /** Cordis plugin name. */
21
+ const name = "omd-task";
22
+ /** Services this row needs. */
23
+ const inject = ["tools", "subagents", "systemPrompt"];
24
+ /** Prompt order after bounded delegation policy and before child reporting. */
25
+ const SUBAGENT_SECTION_ORDER = 116.5;
26
+ const TierSchema = z.object({
27
+ provider: z.string().required(),
28
+ model: z.string().required(),
29
+ hint: z.string(),
30
+ persona: z.string(),
31
+ toolFilter: z.object({
32
+ allow: z.array(z.string()),
33
+ deny: z.array(z.string()),
34
+ }),
35
+ maxTokens: z.number().step(1).min(1).max(Number.MAX_SAFE_INTEGER),
36
+ });
37
+ /** Runtime schema for the omd-task row. */
38
+ const Config = z.object({
39
+ provider: z.string().default("spawn"),
40
+ toolName: z.string().default("omd_task"),
41
+ backgroundMode: z.union(["continuable", "foreground"]).default("continuable"),
42
+ tiers: z.dict(TierSchema).required(),
43
+ defaultTier: z.string(),
44
+ maxDepth: z.union([z.natural().max(Number.MAX_SAFE_INTEGER), z.const("provider-managed")]).default(3),
45
+ });
46
+ const TIER_NAME_PATTERN = /^[a-z0-9][a-z0-9_-]*$/;
47
+ /** Render text blocks from a canonical JSON block array. */
48
+ function outputValueText(values) {
49
+ return values
50
+ .filter((value) => typeof value === "object" && value !== null && !Array.isArray(value) && value.type === "text" && typeof value.text === "string")
51
+ .map((value) => value.text)
52
+ .join("");
53
+ }
54
+ /** A non-completed stop reason means the child did not finish cleanly. */
55
+ function stopReasonError(result) {
56
+ switch (result.stopReason) {
57
+ case "completed": return;
58
+ case "aborted": return "subagent run was cancelled";
59
+ case "error": return "subagent run failed";
60
+ case "max-tokens": return "subagent run hit its token limit before finishing";
61
+ case "refusal": return "subagent declined the task";
62
+ default: return "subagent run ended abnormally (" + String(result.stopReason) + ")";
63
+ }
64
+ }
65
+ /** Append failure detail and the child preserved partial answer. */
66
+ function withDiagnosticAndPartialText(error, result) {
67
+ const diagnostic = result.diagnostic === undefined ? "" : "\nDiagnostic: " + result.diagnostic;
68
+ const text = result.output.filter((block) => block.type === "text").map((block) => block.text).join("");
69
+ return error + diagnostic + (text.length === 0 ? "" : "\nPartial output before the run ended:\n" + text);
70
+ }
71
+ /** Collect and release one foreground run. */
72
+ async function settleForegroundRun(run) {
73
+ const [execution] = await Promise.allSettled([run.result.then((result) => {
74
+ const error = stopReasonError(result);
75
+ if (error !== undefined)
76
+ throw new Error(withDiagnosticAndPartialText(error, result));
77
+ return {
78
+ kind: "foreground",
79
+ runId: run.id,
80
+ output: result.output,
81
+ };
82
+ })]);
83
+ const [disposal] = await Promise.allSettled([Promise.resolve().then(() => run.dispose())]);
84
+ if (execution.status === "rejected") {
85
+ if (disposal.status === "rejected")
86
+ throw new AggregateError([execution.reason, disposal.reason], "subagent run failed: " + String(execution.reason) + "; dispose failed: " + String(disposal.reason));
87
+ throw execution.reason;
88
+ }
89
+ if (disposal.status === "rejected")
90
+ throw disposal.reason;
91
+ return execution.value;
92
+ }
93
+ /** Validate row config beyond the schema. Returns an error string or undefined. */
94
+ function configError(config) {
95
+ const tierNames = Object.keys(config.tiers);
96
+ if (tierNames.length === 0)
97
+ return "omd-task: `tiers` must define at least one tier";
98
+ for (const tierName of tierNames) {
99
+ if (!TIER_NAME_PATTERN.test(tierName)) {
100
+ return "omd-task: invalid tier name \"" + tierName + "\" (must match [a-z0-9][a-z0-9_-]*): " + tierNames.join(", ");
101
+ }
102
+ const filter = config.tiers[tierName].toolFilter;
103
+ if (filter !== undefined && filter.allow === undefined && filter.deny === undefined) {
104
+ return "omd-task: tier \"" + tierName + "\" configures toolFilter but names neither allow nor deny";
105
+ }
106
+ }
107
+ if (config.defaultTier !== undefined && config.tiers[config.defaultTier] === undefined) {
108
+ return "omd-task: defaultTier \"" + config.defaultTier + "\" is not one of the tiers: " + tierNames.join(", ");
109
+ }
110
+ return undefined;
111
+ }
112
+ /** Human-readable enumeration of the tiers for the tool description. */
113
+ function tierCatalog(tiers) {
114
+ const lines = [];
115
+ for (const tierName of Object.keys(tiers)) {
116
+ const tier = tiers[tierName];
117
+ const hint = tier.hint === undefined ? "no hint configured" : tier.hint;
118
+ lines.push("- tier \"" + tierName + "\": " + hint + " [model: " + tier.provider + "/" + tier.model + "]");
119
+ }
120
+ return lines.join("\n");
121
+ }
122
+ /** Resolve which tier one call uses. Throws with a helpful message when ambiguous. */
123
+ function resolveTier(config, requested) {
124
+ const tierNames = Object.keys(config.tiers);
125
+ if (requested !== undefined) {
126
+ if (config.tiers[requested] === undefined) {
127
+ throw new Error("omd_task: unknown tier \"" + requested + "\" -- valid tiers: " + tierNames.join(", "));
128
+ }
129
+ return requested;
130
+ }
131
+ if (config.defaultTier !== undefined)
132
+ return config.defaultTier;
133
+ if (tierNames.length === 1)
134
+ return tierNames[0];
135
+ throw new Error("omd_task: choose a tier for this task -- valid tiers: " + tierNames.join(", "));
136
+ }
137
+ function apply(ctx, config) {
138
+ if (scopeOf(ctx) === undefined) {
139
+ throw new Error("omd-task: refusing to mount outside a scoped context; mount this row inside an agent preset");
140
+ }
141
+ const invalid = configError(config);
142
+ if (invalid !== undefined)
143
+ throw new Error(invalid);
144
+ if (config.maxDepth !== "provider-managed")
145
+ assertSubagentMaxDepth(config.maxDepth);
146
+ const continuable = config.backgroundMode === "continuable";
147
+ const toolName = config.toolName;
148
+ let disposeTool;
149
+ const description = "Delegate a task to a tiered subagent. Every tier is a fixed worker profile (model + persona + tool boundary); choose the tier that fits the work and give the task a complete, standalone prompt. Available tiers:\n" +
150
+ tierCatalog(config.tiers) + "\n\n" +
151
+ "Use cheaper tiers for repeated investigation, searching, summarising and mechanical work; use stronger tiers for top-level planning, deep reasoning and hard problems. The subagent returns its result, not its intermediate steps." +
152
+ (continuable ? " This tool runs in the background by default and immediately returns a durable subagent id; the runtime sends you a notice when that run settles. Set run_in_background: false only when your next action depends on receiving the result." : " This call waits for the subagent and returns its result.");
153
+ const mount = (provider) => {
154
+ if (typeof config.maxDepth === "number" && !provider.capabilities.depthLimit) {
155
+ throw new Error("omd-task: provider \"" + provider.name + "\" cannot enforce maxDepth (no depthLimit capability) -- set maxDepth: provider-managed");
156
+ }
157
+ if (continuable && provider.prepareContinuable === undefined) {
158
+ throw new Error("omd-task: provider \"" + provider.name + "\" does not support backgroundMode: continuable");
159
+ }
160
+ disposeTool = ctx.tools.register(defineTool({
161
+ name: toolName,
162
+ description,
163
+ parameters: {
164
+ description: {
165
+ type: "string",
166
+ required: true,
167
+ description: "A short (3-5 word) description of the delegated task, for display.",
168
+ },
169
+ prompt: {
170
+ type: "string",
171
+ required: true,
172
+ description: "The complete, self-contained task for the subagent. It does not share this conversation\u2019s context, so include everything it needs.",
173
+ },
174
+ tier: {
175
+ type: "string",
176
+ description: "Which worker tier to use. " + tierCatalog(config.tiers) + (config.defaultTier !== undefined ? " Leave empty to use the default tier (\"" + config.defaultTier + "\")." : " Required when more than one tier exists."),
177
+ },
178
+ ...(continuable ? { run_in_background: {
179
+ type: "boolean",
180
+ description: "Whether to run in the background and return a durable subagent id immediately. Defaults to true. Set false to wait for the result when your next action depends on it.",
181
+ } } : {}),
182
+ },
183
+ output: {
184
+ schema: { oneOf: [
185
+ {
186
+ type: "object",
187
+ additionalProperties: false,
188
+ properties: {
189
+ kind: { type: "string", required: true, const: "continuable" },
190
+ subagentId: { type: "string", required: true },
191
+ },
192
+ },
193
+ {
194
+ type: "object",
195
+ additionalProperties: false,
196
+ properties: {
197
+ kind: { type: "string", required: true, const: "foreground" },
198
+ runId: { type: "string", required: true },
199
+ output: { type: "array", required: true, items: { type: "json" } },
200
+ },
201
+ },
202
+ ] },
203
+ render: (_args, value) => [{
204
+ type: "text",
205
+ text: value.kind === "continuable" ? "started subagent " + value.subagentId : outputValueText(value.output),
206
+ }],
207
+ },
208
+ isConcurrencySafe: () => true,
209
+ async execute(args, exec) {
210
+ const parent = exec.agent;
211
+ if (!parent)
212
+ throw new Error("omd_task requires a calling agent (exec.agent was undefined)");
213
+ const tierName = resolveTier(config, args.tier);
214
+ const tier = config.tiers[tierName];
215
+ const maxDepth = typeof config.maxDepth === "number" ? config.maxDepth : undefined;
216
+ const request = {
217
+ label: args.description,
218
+ prompt: [{ type: "text", text: args.prompt }],
219
+ parent,
220
+ agentOptions: {
221
+ provider: tier.provider,
222
+ model: tier.model,
223
+ ...(tier.maxTokens !== undefined ? { maxTokens: tier.maxTokens } : {}),
224
+ },
225
+ ...(tier.persona !== undefined ? { persona: tier.persona } : {}),
226
+ ...(tier.toolFilter !== undefined ? { toolFilter: tier.toolFilter } : {}),
227
+ ...(maxDepth !== undefined ? { maxDepth } : {}),
228
+ };
229
+ if (continuable && args.run_in_background !== false) {
230
+ return {
231
+ kind: "continuable",
232
+ subagentId: (await ctx.subagents.startContinuable({
233
+ provider: config.provider,
234
+ label: args.description,
235
+ request,
236
+ signal: exec.signal,
237
+ })).childId,
238
+ };
239
+ }
240
+ return settleForegroundRun(await ctx.subagents.start(config.provider, {
241
+ ...request,
242
+ signal: exec.signal,
243
+ }));
244
+ },
245
+ }));
246
+ };
247
+ ctx.on("subagent/provider-added", (provider) => {
248
+ if (provider.name === config.provider && disposeTool === undefined)
249
+ mount(provider);
250
+ });
251
+ ctx.on("subagent/provider-removed", (providerName) => {
252
+ if (providerName !== config.provider || disposeTool === undefined)
253
+ return;
254
+ disposeTool();
255
+ disposeTool = undefined;
256
+ });
257
+ const present = ctx.subagents.getProvider(config.provider);
258
+ if (present !== undefined)
259
+ mount(present);
260
+ else
261
+ ctx.logger.info("omd-task: subagent provider \"" + config.provider + "\" not registered yet; the \"" + toolName + "\" tool will register when it appears");
262
+ if (continuable)
263
+ ctx.systemPrompt.section({
264
+ name: "tool:" + toolName,
265
+ order: SUBAGENT_SECTION_ORDER,
266
+ text: (context) => disposeTool === undefined || ctx.tools.get(toolName, context.scope) === undefined ? "" :
267
+ "Use " + toolName + " in the background by default. Start independent delegations together in one assistant message and continue useful work while they run. Set run_in_background: false only when your next action depends on that subagent result. When a background run settles, the runtime sends you a notice containing its outcome and any final assistant message.",
268
+ });
269
+ }
270
+ export { Config, apply, inject, name };
@@ -0,0 +1,80 @@
1
+ {
2
+ "version": 1,
3
+ "defaults": {
4
+ "provider": "deepseek-official"
5
+ },
6
+ "modes": {
7
+ "executor": {
8
+ "provider": "deepseek-official",
9
+ "model": "deepseek-v4-pro",
10
+ "tiers": {
11
+ "fast": {
12
+ "provider": "deepseek-official",
13
+ "model": "deepseek-v4-flash",
14
+ "hint": "cheap and fast — repetitive investigation, searching, summarising, mechanical work",
15
+ "persona": "You are a FAST worker subagent (快速执行子代理): complete the assigned task efficiently with the tools you have; prefer short, focused answers.",
16
+ "toolFilter": { "deny": ["write", "edit"], "denyShell": true }
17
+ },
18
+ "deep": {
19
+ "provider": "deepseek-official",
20
+ "model": "deepseek-v4-pro",
21
+ "hint": "strong reasoning — hard problems, architecture, deep debugging",
22
+ "persona": "You are a DEEP worker subagent (深度推理子代理): solve the assigned hard task with careful reasoning; verify your conclusions before answering."
23
+ }
24
+ }
25
+ },
26
+ "architect": {
27
+ "provider": "deepseek-official",
28
+ "model": "deepseek-v4-pro",
29
+ "tiers": {
30
+ "fast": {
31
+ "provider": "deepseek-official",
32
+ "model": "deepseek-v4-flash",
33
+ "hint": "cheap and fast — repetitive investigation, searching, summarising, mechanical work",
34
+ "persona": "You are a FAST worker subagent (快速执行子代理): complete the assigned task efficiently with the tools you have; prefer short, focused answers.",
35
+ "toolFilter": { "deny": ["write", "edit"], "denyShell": true }
36
+ },
37
+ "deep": {
38
+ "provider": "deepseek-official",
39
+ "model": "deepseek-v4-pro",
40
+ "hint": "strong reasoning — hard problems, architecture, deep debugging",
41
+ "persona": "You are a DEEP worker subagent (深度推理子代理): solve the assigned hard task with careful reasoning; verify your conclusions before answering."
42
+ }
43
+ }
44
+ },
45
+ "planner": {
46
+ "provider": "deepseek-official",
47
+ "model": "deepseek-v4-pro",
48
+ "tiers": {
49
+ "investigate": {
50
+ "provider": "deepseek-official",
51
+ "model": "deepseek-v4-flash",
52
+ "hint": "cheap and fast — content investigation, searching, summarising",
53
+ "persona": "You are a CONTENT INVESTIGATOR subagent (内容调查员): investigate the assigned topic by reading and searching; report findings precisely with sources."
54
+ },
55
+ "review": {
56
+ "provider": "deepseek-official",
57
+ "model": "deepseek-v4-pro",
58
+ "hint": "strong reasoning — critical review of plans and designs",
59
+ "persona": "You are a PLAN REVIEWER subagent (方案评审员): critically review the assigned plan or design; list defects, risks and missing edge cases precisely."
60
+ }
61
+ }
62
+ },
63
+ "reviewer": {
64
+ "provider": "deepseek-official",
65
+ "model": "deepseek-v4-flash"
66
+ },
67
+ "explorer": {
68
+ "provider": "deepseek-official",
69
+ "model": "deepseek-v4-flash"
70
+ },
71
+ "librarian": {
72
+ "provider": "deepseek-official",
73
+ "model": "deepseek-v4-flash"
74
+ },
75
+ "chat": {
76
+ "provider": "deepseek-official",
77
+ "model": "deepseek-v4-flash"
78
+ }
79
+ }
80
+ }
package/package.json ADDED
@@ -0,0 +1,73 @@
1
+ {
2
+ "name": "@carljia/omd-dsh",
3
+ "version": "0.1.0",
4
+ "description": "OMD 理念的 DeepSeek Harness 插件:模式能力边界 + 按模式配模型 + tier 差异化子代理委派",
5
+ "keywords": [
6
+ "deepseek-harness",
7
+ "dsh",
8
+ "agent-presets",
9
+ "multi-agent",
10
+ "omd",
11
+ "subagent",
12
+ "orchestration"
13
+ ],
14
+ "author": "Carl Jia <jiazz197@gmail.com>",
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "git+https://github.com/jiazz197-cmyk/omd-dsh.git"
18
+ },
19
+ "homepage": "https://github.com/jiazz197-cmyk/omd-dsh#readme",
20
+ "bugs": {
21
+ "url": "https://github.com/jiazz197-cmyk/omd-dsh/issues"
22
+ },
23
+ "engines": {
24
+ "node": ">=20"
25
+ },
26
+ "type": "module",
27
+ "main": "lib/index.js",
28
+ "types": "lib/index.d.ts",
29
+ "exports": {
30
+ ".": {
31
+ "types": "./lib/index.d.ts",
32
+ "default": "./lib/index.js"
33
+ },
34
+ "./task": {
35
+ "types": "./lib/task.d.ts",
36
+ "default": "./lib/task.js"
37
+ },
38
+ "./package.json": "./package.json"
39
+ },
40
+ "bin": {
41
+ "omd-dsh": "lib/cli.js"
42
+ },
43
+ "files": [
44
+ "lib",
45
+ "presets",
46
+ "omd-matrix.json",
47
+ "README.md",
48
+ "LICENSE"
49
+ ],
50
+ "license": "MIT",
51
+ "peerDependencies": {
52
+ "@deepseek-ai/cordis": "^4.0.1",
53
+ "@deepseek-ai/schemastery": "^3.18.1",
54
+ "@deepseek-ai/dsh-scope": "^0.1.1-rc.2",
55
+ "@deepseek-ai/dsh-subagent": "^0.1.1-rc.2",
56
+ "@deepseek-ai/dsh-tools": "^0.1.1-rc.2",
57
+ "@deepseek-ai/dsh-llm": "^0.1.1-rc.2",
58
+ "@deepseek-ai/dsh-system-prompt": "^0.1.1-rc.2"
59
+ },
60
+ "devDependencies": {
61
+ "@types/node": "^24.0.0",
62
+ "@deepseek-ai/schemastery": "^3.18.1",
63
+ "typescript": "^5.6.0",
64
+ "vitest": "^3.0.0"
65
+ },
66
+ "scripts": {
67
+ "build": "tsc -p tsconfig.json && node scripts/postbuild.mjs",
68
+ "test": "vitest run",
69
+ "prepare": "tsc -p tsconfig.json && node scripts/postbuild.mjs",
70
+ "prepack": "tsc -p tsconfig.json && node scripts/postbuild.mjs",
71
+ "prepublishOnly": "npm test"
72
+ }
73
+ }
@@ -0,0 +1,112 @@
1
+ # omd-architect preset (OMD architect mode). Generated by omd-dsh — see README for the mode matrix.
2
+
3
+ - id: persona
4
+ name: '@deepseek-ai/dsh-persona'
5
+ config:
6
+ text: >-
7
+ You are in OMD ARCHITECT mode (OMD · 架构构建): a deep builder on DeepSeek Harness. Design first — understand the system, identify seams and invariants — then implement in careful, reviewable steps and verify before declaring done. Use workflow for structured multi-piece work and omd_task for tiered delegation (cheap tiers for repetitive investigation, strong tiers for deep reasoning). 本模式路由模型:{{model}}(provider: {{provider}})。
8
+
9
+ # [omd-dsh:mode:start]
10
+ # [omd-dsh:mode:end]
11
+ - id: agent-instructions
12
+ name: '@deepseek-ai/dsh-agent-instructions'
13
+ config:
14
+ maxBytes: 65536
15
+
16
+ - id: tool-bash
17
+ name: '@deepseek-ai/dsh-tool-bash'
18
+ disabled: !!js process.platform === 'win32'
19
+
20
+ - id: tool-pwsh
21
+ name: '@deepseek-ai/dsh-tool-pwsh'
22
+ disabled: !!js process.platform !== 'win32'
23
+
24
+ - id: tool-fs
25
+ name: '@deepseek-ai/dsh-tool-fs'
26
+
27
+ - id: tool-fs-search
28
+ name: '@deepseek-ai/dsh-tool-fs-search'
29
+ config:
30
+ sampleOverCapGlobResults: false
31
+
32
+ - id: tool-jobs
33
+ name: '@deepseek-ai/dsh-tool-jobs'
34
+
35
+ - id: skill-filesystem
36
+ name: '@deepseek-ai/dsh-skill-filesystem'
37
+
38
+ - id: tool-skill
39
+ name: '@deepseek-ai/dsh-tool-skill'
40
+
41
+ - id: tool-goal
42
+ name: '@deepseek-ai/dsh-tool-goal'
43
+
44
+ - id: compaction
45
+ name: cordis:group
46
+ group: true
47
+ isolate:
48
+ compaction: true
49
+ toolResultPruner: true
50
+ config:
51
+ - id: compaction-basic
52
+ name: '@deepseek-ai/dsh-compaction-basic'
53
+
54
+ - id: command-compact
55
+ name: '@deepseek-ai/dsh-command-compact'
56
+
57
+ - id: tool-result-pruner
58
+ name: '@deepseek-ai/dsh-compaction-tool-result-pruner'
59
+ config:
60
+ thresholdChars: 8192
61
+ headChars: 4096
62
+ tailChars: 1024
63
+
64
+ - id: delegation
65
+ name: cordis:group
66
+ group: true
67
+ isolate:
68
+ workflowEngine: true
69
+ config:
70
+ - id: tool-subagent-control
71
+ name: '@deepseek-ai/dsh-tool-subagent-control'
72
+
73
+ - id: tool-subagent-list-agents
74
+ name: '@deepseek-ai/dsh-tool-subagent-control/list-agents'
75
+
76
+ - id: tool-subagent
77
+ name: '@deepseek-ai/dsh-tool-subagent'
78
+ config:
79
+ provider: spawn
80
+ toolName: subagent
81
+ backgroundMode: continuable
82
+
83
+ - id: tool-subagent-fork
84
+ name: '@deepseek-ai/dsh-tool-subagent'
85
+ config:
86
+ provider: fork
87
+ toolName: subagent_fork
88
+ backgroundMode: continuable
89
+
90
+ - id: workflow-worker-thread
91
+ name: '@deepseek-ai/dsh-workflow-worker-thread'
92
+ config:
93
+ provider: spawn
94
+
95
+ - id: tool-workflow
96
+ name: '@deepseek-ai/dsh-tool-workflow'
97
+
98
+ # [omd-dsh:task:start]
99
+ # [omd-dsh:task:end]
100
+ - id: tool-ask-user
101
+ name: '@deepseek-ai/dsh-tool-ask-user'
102
+
103
+ - id: tool-todo
104
+ name: '@deepseek-ai/dsh-tool-todo'
105
+ config:
106
+ allowParallelInProgress: true
107
+
108
+ - id: tool-web
109
+ name: '@deepseek-ai/dsh-tool-web'
110
+ config:
111
+ fetch: false
112
+ searchTimeoutMs: 60000
@@ -0,0 +1,3 @@
1
+ name: OMD · 架构构建
2
+ description: 深度构建模式:完整工具集 + workflow + omd_task 差异化委派(不含 ralph)。
3
+ order: 102
@@ -0,0 +1,23 @@
1
+ # omd-chat preset (OMD chat mode). Generated by omd-dsh — see README for the mode matrix.
2
+
3
+ - id: persona
4
+ name: '@deepseek-ai/dsh-persona'
5
+ config:
6
+ text: >-
7
+ You are in OMD CHAT mode (OMD · 对话): a lightweight conversational assistant on DeepSeek Harness. Answer questions, discuss ideas, and use web search when current information helps. You have no filesystem or shell tools. 本模式路由模型:{{model}}(provider: {{provider}})。
8
+
9
+ # [omd-dsh:mode:start]
10
+ # [omd-dsh:mode:end]
11
+ - id: tool-ask-user
12
+ name: '@deepseek-ai/dsh-tool-ask-user'
13
+
14
+ - id: tool-todo
15
+ name: '@deepseek-ai/dsh-tool-todo'
16
+ config:
17
+ allowParallelInProgress: true
18
+
19
+ - id: tool-web
20
+ name: '@deepseek-ai/dsh-tool-web'
21
+ config:
22
+ fetch: false
23
+ searchTimeoutMs: 60000
@@ -0,0 +1,3 @@
1
+ name: OMD · 对话
2
+ description: 轻量对话模式:无文件系统与 shell 工具,仅 web 搜索 + 提问 + 待办。
3
+ order: 107