@dsh-plugin/dsh-loader 1.1.0-dev.32278873528 → 1.2.0-dev.32741629392
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 +160 -0
- package/README.md +1 -1
- package/README.zh_CN.md +1 -1
- package/dist/adapters/dsh-1-x.js +4 -0
- package/dist/adapters/dsh-1-x.js.map +1 -1
- package/dist/api.d.ts +2 -0
- package/dist/api.js +18 -2
- package/dist/api.js.map +1 -1
- package/dist/client.d.ts +0 -1
- package/dist/client.js +13 -3
- package/dist/client.js.map +1 -1
- package/dist/index.js +7 -1
- package/dist/index.js.map +1 -1
- package/dist/patch.d.ts +112 -0
- package/dist/patch.js +179 -0
- package/dist/patch.js.map +1 -0
- package/dist/services/dsh-symbols.d.ts +70 -0
- package/dist/services/dsh-symbols.js +82 -0
- package/dist/services/dsh-symbols.js.map +1 -0
- package/dist/services/llm.d.ts +30 -0
- package/dist/services/llm.js +35 -0
- package/dist/services/llm.js.map +1 -0
- package/dist/services/registry.d.ts +144 -0
- package/dist/services/registry.js +209 -0
- package/dist/services/registry.js.map +1 -0
- package/dist/services/settings.d.ts +6 -0
- package/dist/services/settings.js +29 -1
- package/dist/services/settings.js.map +1 -1
- package/dist/services/web.js +20 -4
- package/dist/services/web.js.map +1 -1
- package/dist/setup.js +17 -1
- package/dist/setup.js.map +1 -1
- package/dist/types.d.ts +55 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/lib/client.js +2775 -4
- package/lib/client.js.map +1 -1
- package/lib/types/adapters/dsh-1-x.d.ts +23 -0
- package/lib/types/adapters/index.d.ts +22 -0
- package/lib/types/client-ui.d.ts +40 -0
- package/lib/types/client.d.ts +156 -0
- package/lib/types/patch.d.ts +112 -0
- package/lib/types/registry.d.ts +35 -0
- package/lib/types/services/dsh-symbols.d.ts +70 -0
- package/lib/types/services/llm.d.ts +30 -0
- package/lib/types/services/registry.d.ts +144 -0
- package/lib/types/services/settings.d.ts +47 -0
- package/lib/types/types.d.ts +166 -0
- package/lib/types/ui/anchors.d.ts +56 -0
- package/lib/types/ui/components.d.ts +159 -0
- package/lib/types/ui/icons.d.ts +142 -0
- package/lib/types/ui/index.d.ts +30 -0
- package/lib/types/ui/menu.d.ts +104 -0
- package/lib/types/ui/slots.d.ts +152 -0
- package/lib/types/ui/style.d.ts +97 -0
- package/lib/types/version.d.ts +2 -0
- package/package.json +45 -11
- package/src/stable/compaction-basic.d.ts +1 -0
- package/src/stable/compaction-basic.js +5 -0
- package/src/stable/credentials.d.ts +1 -0
- package/src/stable/credentials.js +5 -0
- package/src/stable/subagent.d.ts +1 -0
- package/src/stable/subagent.js +5 -0
- package/src/stable/timeout.d.ts +1 -0
- package/src/stable/timeout.js +5 -0
package/dist/patch.js
ADDED
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The dshloader PATCH protocol (`ctx.dshLoader.patch` / `__dshLoader__.patch`).
|
|
3
|
+
*
|
|
4
|
+
* Monkey-patching a host method or global is the only way to intervene in
|
|
5
|
+
* behaviour dsh exposes no extension point for. Three plugins in this family
|
|
6
|
+
* each hand-rolled the protocol and they did NOT agree:
|
|
7
|
+
*
|
|
8
|
+
* - dsh-loader's own `Module._resolveFilename` hook → identity-checked restore
|
|
9
|
+
* - dsh-network-settings' `globalThis.fetch` wrapper → identity-checked restore
|
|
10
|
+
* - dsh-better-sidebar's `workspaces.openPath` wrap → UNCONDITIONAL restore
|
|
11
|
+
*
|
|
12
|
+
* The last one silently destroys a later plugin's wrapper when it disposes
|
|
13
|
+
* first, even though its own comment promised the opposite. This module is the
|
|
14
|
+
* single correct implementation; every patch site delegates here.
|
|
15
|
+
*
|
|
16
|
+
* The five guarantees:
|
|
17
|
+
*
|
|
18
|
+
* 1. RAW original — each patch captures EXACTLY the value present when it
|
|
19
|
+
* installed (another plugin's wrapper when one is already there) and
|
|
20
|
+
* restores that value verbatim, never a bound copy. This is what lets a
|
|
21
|
+
* chain of wrappers survive disposal in any order.
|
|
22
|
+
* 2. Identity-checked restore — disposal only reverts the slot when it still
|
|
23
|
+
* holds OUR wrapper. If somebody patched on top afterwards, we leave the
|
|
24
|
+
* chain alone (reverting would delete their wrapper).
|
|
25
|
+
* 3. Re-apply safety — re-applying the same `id` recovers the true original
|
|
26
|
+
* first, so HMR / repeated `apply()` can never nest a wrapper in itself.
|
|
27
|
+
* This holds while our patch is the OUTERMOST one; if a foreign patch was
|
|
28
|
+
* layered on top in between, re-applying chains instead (un-nesting a
|
|
29
|
+
* middle wrapper is not possible without rebuilding the whole chain).
|
|
30
|
+
* 4. Cross-instance durability — slot bookkeeping lives in a WeakMap parked on
|
|
31
|
+
* `globalThis` under a `Symbol.for` key, so a reloaded module instance still
|
|
32
|
+
* sees the original captured by its predecessor. Targets are never mutated.
|
|
33
|
+
* 5. Loud misuse — patching a non-function method, or a missing target, throws
|
|
34
|
+
* instead of silently no-op'ing.
|
|
35
|
+
*
|
|
36
|
+
* Pure and environment-agnostic: no DOM, no Node builtins, so the same module
|
|
37
|
+
* serves the host half and the browser half.
|
|
38
|
+
*
|
|
39
|
+
* @module @dsh-plugin/dsh-loader/patch
|
|
40
|
+
*/
|
|
41
|
+
/**
|
|
42
|
+
* Registry key on `globalThis`. `Symbol.for` (not a fresh Symbol) so a
|
|
43
|
+
* re-instantiated module — HMR, a second bundle copy — finds the same registry
|
|
44
|
+
* and therefore the same captured originals.
|
|
45
|
+
*/
|
|
46
|
+
const REGISTRY_KEY = Symbol.for('dshloader.patch.registry.v1');
|
|
47
|
+
/** The process-wide patch registry (targets are keys; nothing is written onto them). */
|
|
48
|
+
function registry() {
|
|
49
|
+
const scope = globalThis;
|
|
50
|
+
let found = scope[REGISTRY_KEY];
|
|
51
|
+
if (found === undefined) {
|
|
52
|
+
found = new WeakMap();
|
|
53
|
+
scope[REGISTRY_KEY] = found;
|
|
54
|
+
}
|
|
55
|
+
return found;
|
|
56
|
+
}
|
|
57
|
+
/** The slot table for one target, created on first use. */
|
|
58
|
+
function slotsOf(target) {
|
|
59
|
+
const reg = registry();
|
|
60
|
+
let table = reg.get(target);
|
|
61
|
+
if (table === undefined) {
|
|
62
|
+
table = new Map();
|
|
63
|
+
reg.set(target, table);
|
|
64
|
+
}
|
|
65
|
+
return table;
|
|
66
|
+
}
|
|
67
|
+
/** Read the current value of `target[key]` without tripping getters twice. */
|
|
68
|
+
function read(target, key) {
|
|
69
|
+
return target[key];
|
|
70
|
+
}
|
|
71
|
+
/** Write `target[key]`, surfacing a frozen / read-only slot as a loud error. */
|
|
72
|
+
function write(target, key, value, what) {
|
|
73
|
+
try {
|
|
74
|
+
target[key] = value;
|
|
75
|
+
}
|
|
76
|
+
catch (cause) {
|
|
77
|
+
throw new Error(`dshloader.patch: cannot write ${what} — the slot is read-only or frozen`, { cause });
|
|
78
|
+
}
|
|
79
|
+
if (read(target, key) !== value) {
|
|
80
|
+
// A non-writable data property assigns silently in sloppy mode.
|
|
81
|
+
throw new Error(`dshloader.patch: writing ${what} had no effect — the slot is not writable`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Build the handle for one installed slot. Kept separate so a re-apply of the
|
|
86
|
+
* same id can hand back a handle over the existing bookkeeping.
|
|
87
|
+
*/
|
|
88
|
+
function makeHandle(target, key, slot) {
|
|
89
|
+
return {
|
|
90
|
+
get active() {
|
|
91
|
+
return read(target, key) === slot.wrapper;
|
|
92
|
+
},
|
|
93
|
+
get original() {
|
|
94
|
+
return slot.original;
|
|
95
|
+
},
|
|
96
|
+
dispose() {
|
|
97
|
+
// Guarantee 2: only revert while the slot still carries OUR wrapper.
|
|
98
|
+
if (read(target, key) !== slot.wrapper)
|
|
99
|
+
return;
|
|
100
|
+
write(target, key, slot.original, `${String(key)} (restore)`);
|
|
101
|
+
const table = registry().get(target);
|
|
102
|
+
if (table?.get(key) === slot)
|
|
103
|
+
table.delete(key);
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Patch one slot of `target`. The low-level primitive behind
|
|
109
|
+
* {@link PatchAPI.method} and {@link PatchAPI.global}.
|
|
110
|
+
*
|
|
111
|
+
* @param target - object owning the slot (a service instance, `globalThis`, …).
|
|
112
|
+
* @param key - property key to wrap.
|
|
113
|
+
* @param wrap - receives the value currently in the slot (the previous wrapper
|
|
114
|
+
* when another patch is already installed — chaining is intended) and returns
|
|
115
|
+
* the replacement.
|
|
116
|
+
* @param options - see {@link PatchOptions}.
|
|
117
|
+
* @returns the handle whose `dispose()` reverts this patch.
|
|
118
|
+
*/
|
|
119
|
+
export function patchSlot(target, key, wrap, options = {}) {
|
|
120
|
+
if (target === null || (typeof target !== 'object' && typeof target !== 'function')) {
|
|
121
|
+
throw new TypeError(`dshloader.patch: target must be an object, received ${typeof target}`);
|
|
122
|
+
}
|
|
123
|
+
if (typeof wrap !== 'function') {
|
|
124
|
+
throw new TypeError('dshloader.patch: wrap must be a function');
|
|
125
|
+
}
|
|
126
|
+
const id = options.id ?? 'anonymous';
|
|
127
|
+
const table = slotsOf(target);
|
|
128
|
+
const existing = table.get(key);
|
|
129
|
+
// Guarantee 3: a re-apply of the same id must not wrap our own wrapper.
|
|
130
|
+
// Restore the captured original first, then patch the pristine slot.
|
|
131
|
+
if (existing !== undefined && existing.id === id && read(target, key) === existing.wrapper) {
|
|
132
|
+
write(target, key, existing.original, `${String(key)} (re-apply reset)`);
|
|
133
|
+
table.delete(key);
|
|
134
|
+
}
|
|
135
|
+
const current = read(target, key);
|
|
136
|
+
if (typeof current !== 'function') {
|
|
137
|
+
throw new TypeError(`dshloader.patch: ${String(key)} is ${current === undefined ? 'missing' : typeof current}, not a function`);
|
|
138
|
+
}
|
|
139
|
+
// Guarantee 1: capture EXACTLY the value present at install time. When another
|
|
140
|
+
// plugin already wrapped this slot, that wrapper is our original and restoring
|
|
141
|
+
// it is what keeps their patch alive (see the ordered-disposal tests).
|
|
142
|
+
const original = current;
|
|
143
|
+
const wrapper = wrap(current);
|
|
144
|
+
if (typeof wrapper !== 'function') {
|
|
145
|
+
throw new TypeError('dshloader.patch: wrap must return a function');
|
|
146
|
+
}
|
|
147
|
+
write(target, key, wrapper, String(key));
|
|
148
|
+
const slot = { original, wrapper, id };
|
|
149
|
+
table.set(key, slot);
|
|
150
|
+
return makeHandle(target, key, slot);
|
|
151
|
+
}
|
|
152
|
+
/** Whether a dshloader patch is currently installed on `target[key]`. */
|
|
153
|
+
export function isPatched(target, key) {
|
|
154
|
+
const slot = registry().get(target)?.get(key);
|
|
155
|
+
return slot !== undefined && read(target, key) === slot.wrapper;
|
|
156
|
+
}
|
|
157
|
+
/** The patch id currently installed on `target[key]`, or `undefined`. */
|
|
158
|
+
export function patchIdOf(target, key) {
|
|
159
|
+
const slot = registry().get(target)?.get(key);
|
|
160
|
+
return slot !== undefined && read(target, key) === slot.wrapper ? slot.id : undefined;
|
|
161
|
+
}
|
|
162
|
+
/** Build the `patch` facade. Stateless — all bookkeeping is in the global registry. */
|
|
163
|
+
export function createPatchAPI() {
|
|
164
|
+
return {
|
|
165
|
+
method(target, key, wrap, options) {
|
|
166
|
+
return patchSlot(target, key, wrap, options);
|
|
167
|
+
},
|
|
168
|
+
global(key, wrap, options = {}) {
|
|
169
|
+
const scope = options.scope ?? globalThis;
|
|
170
|
+
return patchSlot(scope, key, wrap, options);
|
|
171
|
+
},
|
|
172
|
+
slot(target, key, wrap, options) {
|
|
173
|
+
return patchSlot(target, key, wrap, options);
|
|
174
|
+
},
|
|
175
|
+
isPatched,
|
|
176
|
+
patchIdOf,
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
//# sourceMappingURL=patch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"patch.js","sourceRoot":"","sources":["../src/patch.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/** Node's `setTimeout` ceiling (2^31 - 1), used when dsh-timeout is unavailable. */
|
|
2
|
+
export declare const NODE_MAX_TIMER_DELAY_MS = 2147483647;
|
|
3
|
+
/** The raw modules this facade forwards to, as resolved at boot. */
|
|
4
|
+
export interface DshSymbolModules {
|
|
5
|
+
tools?: {
|
|
6
|
+
defineTool?: unknown;
|
|
7
|
+
ToolArgsError?: unknown;
|
|
8
|
+
};
|
|
9
|
+
timeout?: {
|
|
10
|
+
deadline?: unknown;
|
|
11
|
+
MAX_TIMER_DELAY_MS?: number;
|
|
12
|
+
};
|
|
13
|
+
credentials?: {
|
|
14
|
+
credentialRef?: unknown;
|
|
15
|
+
};
|
|
16
|
+
subagent?: {
|
|
17
|
+
delegationDepthOf?: unknown;
|
|
18
|
+
};
|
|
19
|
+
compaction?: {
|
|
20
|
+
BasicCompactionEngine?: unknown;
|
|
21
|
+
};
|
|
22
|
+
llm?: {
|
|
23
|
+
BlockAssembler?: unknown;
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Module-level dsh symbols, grouped by owning package.
|
|
28
|
+
*
|
|
29
|
+
* Types are deliberately loose (`any`-shaped call signatures): pinning dsh's
|
|
30
|
+
* internal shapes here would defeat the shim's purpose, exactly as
|
|
31
|
+
* `src/types.ts` explains for the service surfaces.
|
|
32
|
+
*/
|
|
33
|
+
export interface DshSymbolsAPI {
|
|
34
|
+
tools: {
|
|
35
|
+
/** `defineTool(definition)` — build a tool definition dsh's registry accepts. */
|
|
36
|
+
defineTool<T>(definition: T): T;
|
|
37
|
+
/** `ToolArgsError` — the error class dsh expects for invalid tool arguments. */
|
|
38
|
+
readonly ToolArgsError: new (messages: string[]) => Error;
|
|
39
|
+
};
|
|
40
|
+
timeout: {
|
|
41
|
+
/** `deadline(...)` — dsh's cancellation-aware deadline helper. */
|
|
42
|
+
deadline<T>(...args: any[]): T;
|
|
43
|
+
/** dsh's timer ceiling; falls back to Node's own 2^31-1 when unavailable. */
|
|
44
|
+
readonly MAX_TIMER_DELAY_MS: number;
|
|
45
|
+
};
|
|
46
|
+
credentials: {
|
|
47
|
+
/** `credentialRef(ref)` — brand a raw reference for `credentials.resolve`. */
|
|
48
|
+
credentialRef(ref: unknown): unknown;
|
|
49
|
+
};
|
|
50
|
+
subagent: {
|
|
51
|
+
/** `delegationDepthOf(agent)` — how deep a delegated agent sits. */
|
|
52
|
+
delegationDepthOf(agent: unknown): number;
|
|
53
|
+
};
|
|
54
|
+
compaction: {
|
|
55
|
+
/**
|
|
56
|
+
* `BasicCompactionEngine` — the base class a plugin subclasses to override
|
|
57
|
+
* `summarize`. Throws when unavailable, because a subclass declaration has
|
|
58
|
+
* no meaningful fallback.
|
|
59
|
+
*/
|
|
60
|
+
readonly BasicCompactionEngine: new (...args: any[]) => any;
|
|
61
|
+
};
|
|
62
|
+
llm: {
|
|
63
|
+
/** `BlockAssembler` — dsh's streaming content-block assembler. */
|
|
64
|
+
readonly BlockAssembler: new (...args: any[]) => any;
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
/** Build the `ctx.dshLoader.dsh` facade over boot-resolved modules. */
|
|
68
|
+
export declare function createDshSymbolsAPI(opts: {
|
|
69
|
+
modules?: DshSymbolModules;
|
|
70
|
+
}): DshSymbolsAPI;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Module-level dsh symbols (`ctx.dshLoader.dsh`).
|
|
3
|
+
*
|
|
4
|
+
* Some things a plugin needs are MODULE-level exports of `@deepseek-ai/*`
|
|
5
|
+
* packages rather than methods on a cordis service, so `services.get(...)`
|
|
6
|
+
* cannot reach them: `defineTool`, `ToolArgsError`, `deadline`,
|
|
7
|
+
* `credentialRef`, `delegationDepthOf`, and the `BasicCompactionEngine` base
|
|
8
|
+
* class a plugin subclasses.
|
|
9
|
+
*
|
|
10
|
+
* WHY A FACADE AND NOT THE STABLE SUBPATHS: the `@dsh-plugin/dsh-loader/tools`
|
|
11
|
+
* style subpaths are `export * from '@deepseek-ai/...'`, which requires that
|
|
12
|
+
* package to be resolvable FROM dshloader's own location — true for a client
|
|
13
|
+
* bundle (the browser module table resolves it) but not reliably true on the
|
|
14
|
+
* host, where dshloader sits in the profile and dsh is installed globally. A
|
|
15
|
+
* failed ESM static import is a hard boot failure; a facade degrades per symbol
|
|
16
|
+
* and says why. See docs/facades.md §0.
|
|
17
|
+
*
|
|
18
|
+
* Resolution happens once at boot (see `preloadRegistryModules`), so every
|
|
19
|
+
* accessor here is synchronous.
|
|
20
|
+
*
|
|
21
|
+
* @module @dsh-plugin/dsh-loader/services/dsh-symbols
|
|
22
|
+
*/
|
|
23
|
+
import { LOG_PREFIX } from '../version.js';
|
|
24
|
+
/** Node's `setTimeout` ceiling (2^31 - 1), used when dsh-timeout is unavailable. */
|
|
25
|
+
export const NODE_MAX_TIMER_DELAY_MS = 2147483647;
|
|
26
|
+
/** Build a loud accessor for one required symbol. */
|
|
27
|
+
function required(value, pkg, symbol) {
|
|
28
|
+
if (value === undefined || value === null) {
|
|
29
|
+
throw new Error(`${LOG_PREFIX}:dsh.${symbol} — ${pkg} is unavailable in this runtime; ` +
|
|
30
|
+
'the calling plugin cannot proceed without it');
|
|
31
|
+
}
|
|
32
|
+
return value;
|
|
33
|
+
}
|
|
34
|
+
/** Build the `ctx.dshLoader.dsh` facade over boot-resolved modules. */
|
|
35
|
+
export function createDshSymbolsAPI(opts) {
|
|
36
|
+
const m = opts.modules ?? {};
|
|
37
|
+
return {
|
|
38
|
+
tools: {
|
|
39
|
+
defineTool(definition) {
|
|
40
|
+
const fn = required(m.tools?.defineTool, '@deepseek-ai/dsh-tools', 'tools.defineTool');
|
|
41
|
+
return fn(definition);
|
|
42
|
+
},
|
|
43
|
+
get ToolArgsError() {
|
|
44
|
+
return required(m.tools?.ToolArgsError, '@deepseek-ai/dsh-tools', 'tools.ToolArgsError');
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
timeout: {
|
|
48
|
+
deadline(...args) {
|
|
49
|
+
const fn = required(m.timeout?.deadline, '@deepseek-ai/dsh-timeout', 'timeout.deadline');
|
|
50
|
+
return fn(...args);
|
|
51
|
+
},
|
|
52
|
+
// A platform constant (Node's setTimeout ceiling), not a dsh-versioned
|
|
53
|
+
// value, so falling back to the literal is safe rather than a guess.
|
|
54
|
+
get MAX_TIMER_DELAY_MS() {
|
|
55
|
+
return m.timeout?.MAX_TIMER_DELAY_MS ?? NODE_MAX_TIMER_DELAY_MS;
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
credentials: {
|
|
59
|
+
credentialRef(ref) {
|
|
60
|
+
const fn = required(m.credentials?.credentialRef, '@deepseek-ai/dsh-credentials', 'credentials.credentialRef');
|
|
61
|
+
return fn(ref);
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
subagent: {
|
|
65
|
+
delegationDepthOf(agent) {
|
|
66
|
+
const fn = required(m.subagent?.delegationDepthOf, '@deepseek-ai/dsh-subagent', 'subagent.delegationDepthOf');
|
|
67
|
+
return fn(agent);
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
compaction: {
|
|
71
|
+
get BasicCompactionEngine() {
|
|
72
|
+
return required(m.compaction?.BasicCompactionEngine, '@deepseek-ai/dsh-compaction-basic', 'compaction.BasicCompactionEngine');
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
llm: {
|
|
76
|
+
get BlockAssembler() {
|
|
77
|
+
return required(m.llm?.BlockAssembler, '@deepseek-ai/dsh-llm', 'llm.BlockAssembler');
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=dsh-symbols.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dsh-symbols.js","sourceRoot":"","sources":["../../src/services/dsh-symbols.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3C,oFAAoF;AACpF,MAAM,CAAC,MAAM,uBAAuB,GAAG,UAAU,CAAC;AAsDlD,qDAAqD;AACrD,SAAS,QAAQ,CAAI,KAAc,EAAE,GAAW,EAAE,MAAc;IAC9D,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QAC1C,MAAM,IAAI,KAAK,CACb,GAAG,UAAU,QAAQ,MAAM,MAAM,GAAG,mCAAmC;YACrE,8CAA8C,CACjD,CAAC;IACJ,CAAC;IACD,OAAO,KAAU,CAAC;AACpB,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,mBAAmB,CAAC,IAAoC;IACtE,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC;IAC7B,OAAO;QACL,KAAK,EAAE;YACL,UAAU,CAAC,UAAU;gBACnB,MAAM,EAAE,GAAG,QAAQ,CACjB,CAAC,CAAC,KAAK,EAAE,UAAU,EACnB,wBAAwB,EACxB,kBAAkB,CACnB,CAAC;gBACF,OAAO,EAAE,CAAC,UAAU,CAAsB,CAAC;YAC7C,CAAC;YACD,IAAI,aAAa;gBACf,OAAO,QAAQ,CACb,CAAC,CAAC,KAAK,EAAE,aAAa,EACtB,wBAAwB,EACxB,qBAAqB,CACtB,CAAC;YACJ,CAAC;SACF;QACD,OAAO,EAAE;YACP,QAAQ,CAAC,GAAG,IAAW;gBACrB,MAAM,EAAE,GAAG,QAAQ,CACjB,CAAC,CAAC,OAAO,EAAE,QAAQ,EACnB,0BAA0B,EAC1B,kBAAkB,CACnB,CAAC;gBACF,OAAO,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;YACrB,CAAC;YACD,uEAAuE;YACvE,qEAAqE;YACrE,IAAI,kBAAkB;gBACpB,OAAO,CAAC,CAAC,OAAO,EAAE,kBAAkB,IAAI,uBAAuB,CAAC;YAClE,CAAC;SACF;QACD,WAAW,EAAE;YACX,aAAa,CAAC,GAAG;gBACf,MAAM,EAAE,GAAG,QAAQ,CACjB,CAAC,CAAC,WAAW,EAAE,aAAa,EAC5B,8BAA8B,EAC9B,2BAA2B,CAC5B,CAAC;gBACF,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC;YACjB,CAAC;SACF;QACD,QAAQ,EAAE;YACR,iBAAiB,CAAC,KAAK;gBACrB,MAAM,EAAE,GAAG,QAAQ,CACjB,CAAC,CAAC,QAAQ,EAAE,iBAAiB,EAC7B,2BAA2B,EAC3B,4BAA4B,CAC7B,CAAC;gBACF,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC;YACnB,CAAC;SACF;QACD,UAAU,EAAE;YACV,IAAI,qBAAqB;gBACvB,OAAO,QAAQ,CACb,CAAC,CAAC,UAAU,EAAE,qBAAqB,EACnC,mCAAmC,EACnC,kCAAkC,CACnC,CAAC;YACJ,CAAC;SACF;QACD,GAAG,EAAE;YACH,IAAI,cAAc;gBAChB,OAAO,QAAQ,CACb,CAAC,CAAC,GAAG,EAAE,cAAc,EACrB,sBAAsB,EACtB,oBAAoB,CACrB,CAAC;YACJ,CAAC;SACF;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/** The `@deepseek-ai/dsh-llm` surface the facades forward to. */
|
|
2
|
+
export interface LlmModule {
|
|
3
|
+
createUserMessage?: (input: unknown) => unknown;
|
|
4
|
+
deepFreeze?: <T>(value: T) => T;
|
|
5
|
+
/** Streaming content-block assembler; surfaced through `dshLoader.dsh.llm`. */
|
|
6
|
+
BlockAssembler?: unknown;
|
|
7
|
+
}
|
|
8
|
+
/** The `llm` facade exposed on the host API. */
|
|
9
|
+
export interface LlmAPI {
|
|
10
|
+
/**
|
|
11
|
+
* Build one identified, frozen user-role message.
|
|
12
|
+
*
|
|
13
|
+
* @param input - complete content and source for a new user message.
|
|
14
|
+
* @returns the immutable message.
|
|
15
|
+
* @throws when `@deepseek-ai/dsh-llm` is unavailable — callers building a
|
|
16
|
+
* message have no meaningful fallback, so this fails loudly rather than
|
|
17
|
+
* handing back something the agent loop would reject.
|
|
18
|
+
*/
|
|
19
|
+
createUserMessage(input: unknown): unknown;
|
|
20
|
+
/**
|
|
21
|
+
* Deep-freeze a value with dsh's own helper (so frozen-ness matches what the
|
|
22
|
+
* runtime expects). Falls back to `Object.freeze` on the top level when the
|
|
23
|
+
* module is unavailable.
|
|
24
|
+
*/
|
|
25
|
+
deepFreeze<T>(value: T): T;
|
|
26
|
+
}
|
|
27
|
+
/** Build the `ctx.dshLoader.llm` facade. */
|
|
28
|
+
export declare function createLlmAPI(opts: {
|
|
29
|
+
module?: LlmModule;
|
|
30
|
+
}): LlmAPI;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LLM stable API (`ctx.dshLoader.llm`).
|
|
3
|
+
*
|
|
4
|
+
* Message CONSTRUCTION helpers are module-level exports of
|
|
5
|
+
* `@deepseek-ai/dsh-llm`, not methods on a cordis service, so
|
|
6
|
+
* `services.get('llm')` cannot reach them — a plugin that needs
|
|
7
|
+
* `createUserMessage` would otherwise have to import `@deepseek-ai/*`
|
|
8
|
+
* directly and lose its decoupling.
|
|
9
|
+
*
|
|
10
|
+
* Inference itself stays on the service: `services.get('llm').stream(...)`.
|
|
11
|
+
* This facade deliberately covers only the module-level helpers.
|
|
12
|
+
*
|
|
13
|
+
* @module @dsh-plugin/dsh-loader/services/llm
|
|
14
|
+
*/
|
|
15
|
+
import { LOG_PREFIX } from '../version.js';
|
|
16
|
+
/** Build the `ctx.dshLoader.llm` facade. */
|
|
17
|
+
export function createLlmAPI(opts) {
|
|
18
|
+
const { module } = opts;
|
|
19
|
+
return {
|
|
20
|
+
createUserMessage(input) {
|
|
21
|
+
const make = module?.createUserMessage;
|
|
22
|
+
if (typeof make !== 'function') {
|
|
23
|
+
throw new Error(`${LOG_PREFIX}:llm.createUserMessage — @deepseek-ai/dsh-llm is unavailable; cannot construct a message`);
|
|
24
|
+
}
|
|
25
|
+
return make(input);
|
|
26
|
+
},
|
|
27
|
+
deepFreeze(value) {
|
|
28
|
+
const freeze = module?.deepFreeze;
|
|
29
|
+
if (typeof freeze === 'function')
|
|
30
|
+
return freeze(value);
|
|
31
|
+
return Object.freeze(value);
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=llm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm.js","sourceRoot":"","sources":["../../src/services/llm.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AA8B3C,4CAA4C;AAC5C,MAAM,UAAU,YAAY,CAAC,IAA4B;IACvD,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IACxB,OAAO;QACL,iBAAiB,CAAC,KAAK;YACrB,MAAM,IAAI,GAAG,MAAM,EAAE,iBAAiB,CAAC;YACvC,IAAI,OAAO,IAAI,KAAK,UAAU,EAAE,CAAC;gBAC/B,MAAM,IAAI,KAAK,CACb,GAAG,UAAU,0FAA0F,CACxG,CAAC;YACJ,CAAC;YACD,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC;QACrB,CAAC;QACD,UAAU,CAAC,KAAK;YACd,MAAM,MAAM,GAAG,MAAM,EAAE,UAAU,CAAC;YAClC,IAAI,OAAO,MAAM,KAAK,UAAU;gBAAE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;YACvD,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import type { CordisContext } from '../types.js';
|
|
2
|
+
/** A live tool definition as the tools registry holds it (shape kept loose on purpose). */
|
|
3
|
+
export interface ToolDefinitionLike {
|
|
4
|
+
name?: string;
|
|
5
|
+
description?: string;
|
|
6
|
+
parameters?: Record<string, unknown>;
|
|
7
|
+
execute?: (args: Record<string, unknown>, exec: unknown) => Promise<unknown>;
|
|
8
|
+
[key: string]: unknown;
|
|
9
|
+
}
|
|
10
|
+
/** One permission preset row as the `permissionPresets` table stores it. */
|
|
11
|
+
export interface PermissionPresetLike {
|
|
12
|
+
sandbox: string;
|
|
13
|
+
approval: string;
|
|
14
|
+
name?: string;
|
|
15
|
+
description?: string;
|
|
16
|
+
[key: string]: unknown;
|
|
17
|
+
}
|
|
18
|
+
/** The optional dsh modules the facades need, resolved once at boot. */
|
|
19
|
+
export interface RegistryModules {
|
|
20
|
+
/** `@deepseek-ai/dsh-sandbox` — for `ESCALATION_TARGETS`. */
|
|
21
|
+
sandbox?: {
|
|
22
|
+
ESCALATION_TARGETS?: readonly string[];
|
|
23
|
+
};
|
|
24
|
+
/** `@deepseek-ai/dsh-permission-presets` — for `effectivePermissionPreset`. */
|
|
25
|
+
permissionPresets?: {
|
|
26
|
+
effectivePermissionPreset?: (events: readonly unknown[]) => string | undefined;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* `@deepseek-ai/dsh-settings` — the settings facade DELEGATES to these rather
|
|
30
|
+
* than reimplementing them. `installSettingsSection` in particular carries
|
|
31
|
+
* real upstream behaviour (register `base` from the composition entry, point
|
|
32
|
+
* the source thunk at the resolved scope, fall back to the entry when the
|
|
33
|
+
* service goes away, all riding the scoped fiber); copying that into a shim
|
|
34
|
+
* would be a bug farm.
|
|
35
|
+
*/
|
|
36
|
+
settings?: {
|
|
37
|
+
installSettingsSection?: (ctx: unknown, ns: unknown, schema: unknown, entry: unknown, hooks: unknown) => void;
|
|
38
|
+
settingsNamespace?: (id: string) => unknown;
|
|
39
|
+
SettingsConflictError?: new (...args: never[]) => Error;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* `@deepseek-ai/dsh-llm` — message-construction helpers are MODULE-level
|
|
43
|
+
* exports, not service methods, so `services.get('llm')` cannot reach them.
|
|
44
|
+
*/
|
|
45
|
+
llm?: import('./llm.js').LlmModule;
|
|
46
|
+
/** `@deepseek-ai/dsh-tools` — `defineTool` / `ToolArgsError` are module-level. */
|
|
47
|
+
tools?: {
|
|
48
|
+
defineTool?: unknown;
|
|
49
|
+
ToolArgsError?: unknown;
|
|
50
|
+
};
|
|
51
|
+
/** `@deepseek-ai/dsh-timeout` — `deadline` / `MAX_TIMER_DELAY_MS`. */
|
|
52
|
+
timeout?: {
|
|
53
|
+
deadline?: unknown;
|
|
54
|
+
MAX_TIMER_DELAY_MS?: number;
|
|
55
|
+
};
|
|
56
|
+
/** `@deepseek-ai/dsh-credentials` — `credentialRef`. */
|
|
57
|
+
credentials?: {
|
|
58
|
+
credentialRef?: unknown;
|
|
59
|
+
};
|
|
60
|
+
/** `@deepseek-ai/dsh-subagent` — `delegationDepthOf`. */
|
|
61
|
+
subagent?: {
|
|
62
|
+
delegationDepthOf?: unknown;
|
|
63
|
+
};
|
|
64
|
+
/** `@deepseek-ai/dsh-compaction-basic` — the `BasicCompactionEngine` base class. */
|
|
65
|
+
compaction?: {
|
|
66
|
+
BasicCompactionEngine?: unknown;
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Load the optional dsh modules the facades proxy.
|
|
71
|
+
*
|
|
72
|
+
* The specifiers are held in variables so TypeScript does not try to resolve
|
|
73
|
+
* them at build time: dshloader declares no `@deepseek-ai/*` dependency, and
|
|
74
|
+
* these packages only exist in the dsh runtime that loads the profile.
|
|
75
|
+
*
|
|
76
|
+
* @returns whatever resolved; a missing module simply stays `undefined`.
|
|
77
|
+
*/
|
|
78
|
+
export declare function preloadRegistryModules(): Promise<RegistryModules>;
|
|
79
|
+
/** Tool-registry accessors. */
|
|
80
|
+
export interface ToolsRegistryAPI {
|
|
81
|
+
/** Every registered tool definition; `[]` when the registry shape is unreachable. */
|
|
82
|
+
list(): ToolDefinitionLike[];
|
|
83
|
+
/** One definition by tool name. */
|
|
84
|
+
get(name: string): ToolDefinitionLike | undefined;
|
|
85
|
+
/**
|
|
86
|
+
* Run `patcher` over every registered definition now and after every
|
|
87
|
+
* `tools/change`, so load order between this plugin and the tool plugins does
|
|
88
|
+
* not matter.
|
|
89
|
+
*
|
|
90
|
+
* A definition is handed to a given `id` at most once (a non-enumerable
|
|
91
|
+
* `Symbol.for` marker on the definition), which is what stops a `tools/change`
|
|
92
|
+
* storm from wrapping `execute` again and again.
|
|
93
|
+
*
|
|
94
|
+
* @param patcher - mutates one live definition; throwing is contained and logged.
|
|
95
|
+
* @param options.id - stable patch id, used for the once-per-definition marker.
|
|
96
|
+
* @returns a disposer that stops the replay (already-applied patches stay).
|
|
97
|
+
*/
|
|
98
|
+
patchAll(patcher: (def: ToolDefinitionLike) => void, options: {
|
|
99
|
+
id: string;
|
|
100
|
+
}): () => void;
|
|
101
|
+
}
|
|
102
|
+
/** Sandbox-registry accessors. */
|
|
103
|
+
export interface SandboxRegistryAPI {
|
|
104
|
+
/** The escalation modes escalation tools advertise; `[]` when unreachable. */
|
|
105
|
+
escalationTargets(): readonly string[];
|
|
106
|
+
/**
|
|
107
|
+
* Advertise one extra escalation mode (idempotent).
|
|
108
|
+
* @returns a disposer removing the mode again; a no-op when unreachable.
|
|
109
|
+
*/
|
|
110
|
+
addEscalationTarget(mode: string): () => void;
|
|
111
|
+
}
|
|
112
|
+
/** Permission-preset registry accessors. */
|
|
113
|
+
export interface PermissionPresetsRegistryAPI {
|
|
114
|
+
/** The live preset table, or `undefined` when the service is absent. */
|
|
115
|
+
table(): Record<string, PermissionPresetLike> | undefined;
|
|
116
|
+
/**
|
|
117
|
+
* Define a preset unless the key already exists (declaration in a
|
|
118
|
+
* `cordis.patch.yml` layer wins).
|
|
119
|
+
* @returns a disposer removing only a preset this call actually added.
|
|
120
|
+
*/
|
|
121
|
+
define(key: string, preset: PermissionPresetLike): () => void;
|
|
122
|
+
/**
|
|
123
|
+
* Fold a session's effective permission-preset key from its event log.
|
|
124
|
+
* @returns the preset key, or `undefined` when the helper is unavailable.
|
|
125
|
+
*/
|
|
126
|
+
effective(events: readonly unknown[]): string | undefined;
|
|
127
|
+
}
|
|
128
|
+
/** The `registry` facade exposed on the host API. */
|
|
129
|
+
export interface RegistryAPI {
|
|
130
|
+
tools: ToolsRegistryAPI;
|
|
131
|
+
sandbox: SandboxRegistryAPI;
|
|
132
|
+
permissionPresets: PermissionPresetsRegistryAPI;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Build the `ctx.dshLoader.registry` facade.
|
|
136
|
+
*
|
|
137
|
+
* @param opts.ctx - the cordis context (services are read lazily, never cached,
|
|
138
|
+
* so a service arriving later is still picked up).
|
|
139
|
+
* @param opts.modules - optional dsh modules from {@link preloadRegistryModules}.
|
|
140
|
+
*/
|
|
141
|
+
export declare function createRegistryAPI(opts: {
|
|
142
|
+
ctx: CordisContext;
|
|
143
|
+
modules?: RegistryModules;
|
|
144
|
+
}): RegistryAPI;
|