@avantf/dsh-mem 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.md +140 -0
- package/lib/client.js +5901 -0
- package/lib/client.js.map +1 -0
- package/lib/dsh-build.json +7 -0
- package/lib/index.js +14329 -0
- package/lib/types/client/domains.d.ts +52 -0
- package/lib/types/client/domains.d.ts.map +1 -0
- package/lib/types/client/domains.js +25 -0
- package/lib/types/client/domains.js.map +1 -0
- package/lib/types/client/index.d.ts +35 -0
- package/lib/types/client/index.d.ts.map +1 -0
- package/lib/types/client/index.js +1351 -0
- package/lib/types/client/index.js.map +1 -0
- package/lib/types/client/ingest.d.ts +24 -0
- package/lib/types/client/ingest.d.ts.map +1 -0
- package/lib/types/client/ingest.js +30 -0
- package/lib/types/client/ingest.js.map +1 -0
- package/lib/types/client/paging.d.ts +30 -0
- package/lib/types/client/paging.d.ts.map +1 -0
- package/lib/types/client/paging.js +36 -0
- package/lib/types/client/paging.js.map +1 -0
- package/lib/types/client/summarize.d.ts +11 -0
- package/lib/types/client/summarize.d.ts.map +1 -0
- package/lib/types/client/summarize.js +79 -0
- package/lib/types/client/summarize.js.map +1 -0
- package/lib/types/envinit-bootstrap.d.ts +43 -0
- package/lib/types/envinit-bootstrap.js +323 -0
- package/lib/types/envinit.d.ts +145 -0
- package/lib/types/envinit.d.ts.map +1 -0
- package/lib/types/envinit.js +495 -0
- package/lib/types/envinit.js.map +1 -0
- package/lib/types/hints.d.ts +42 -0
- package/lib/types/hints.d.ts.map +1 -0
- package/lib/types/hints.js +54 -0
- package/lib/types/hints.js.map +1 -0
- package/lib/types/index.d.ts +74 -0
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/index.js +708 -0
- package/lib/types/index.js.map +1 -0
- package/lib/types/inject.d.ts +14 -0
- package/lib/types/inject.d.ts.map +1 -0
- package/lib/types/inject.js +14 -0
- package/lib/types/inject.js.map +1 -0
- package/lib/types/open.d.ts +27 -0
- package/lib/types/open.d.ts.map +1 -0
- package/lib/types/open.js +133 -0
- package/lib/types/open.js.map +1 -0
- package/lib/types/prompt.d.ts +49 -0
- package/lib/types/prompt.d.ts.map +1 -0
- package/lib/types/prompt.js +65 -0
- package/lib/types/prompt.js.map +1 -0
- package/lib/types/provision.d.ts +117 -0
- package/lib/types/provision.d.ts.map +1 -0
- package/lib/types/provision.js +233 -0
- package/lib/types/provision.js.map +1 -0
- package/lib/types/remote.d.ts +17 -0
- package/lib/types/remote.d.ts.map +1 -0
- package/lib/types/remote.js +233 -0
- package/lib/types/remote.js.map +1 -0
- package/lib/types/tool_schema.d.ts +40 -0
- package/lib/types/tool_schema.d.ts.map +1 -0
- package/lib/types/tool_schema.js +149 -0
- package/lib/types/tool_schema.js.map +1 -0
- package/package.json +109 -0
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This plugin's compatibility spec, and the wiring that runs it.
|
|
3
|
+
*
|
|
4
|
+
* The rules, the probes, the report and the post-registration check all live in
|
|
5
|
+
* `@avantf/dsh-compat` (shared with the rest of the family). What stays here is only what is true of
|
|
6
|
+
* THIS plugin: the services and methods it calls, the dsh packages that identify the host, the wire
|
|
7
|
+
* schema names and tool names that must be visible afterwards, the events it listens to, and the
|
|
8
|
+
* Chinese report a user reads. See `DESIGN.md` §12.1.
|
|
9
|
+
*
|
|
10
|
+
* **Who obtains the base.** Not this module. The family framework `@avantf/dsh-envinit` provisions
|
|
11
|
+
* `@avantf/dsh-compat` as the `mem:compat` manifest item and hands back the directory it landed in
|
|
12
|
+
* (`src/envinit.ts`); this module is given the loaded module and derives everything from it. That is
|
|
13
|
+
* the whole point of the framework: acquisition (resolve → managed copy → verified download →
|
|
14
|
+
* atomic publish) is one shared mechanism, and the plugin only declares what it needs.
|
|
15
|
+
*
|
|
16
|
+
* The base therefore has NO import path of its own here — not even a dynamic one. A static `import`
|
|
17
|
+
* would throw `ERR_MODULE_NOT_FOUND` while the artifact was being evaluated (the base is not a
|
|
18
|
+
* runtime dependency of the published plugin any more), and a bare dynamic `import()` would bypass
|
|
19
|
+
* the framework's managed copy. The plugin loads the module the framework resolved, by file URL.
|
|
20
|
+
*
|
|
21
|
+
* The plugin computes the gate's verdict here and hands it to the engine as plain data
|
|
22
|
+
* (`{ load, status, reason }`), so the inlined engine bundle never imports the base either.
|
|
23
|
+
*
|
|
24
|
+
* @module @avantf/dsh-mem/provision
|
|
25
|
+
*/
|
|
26
|
+
import { readFile } from 'node:fs/promises';
|
|
27
|
+
import { defineTool } from '@deepseek-ai/dsh-tools';
|
|
28
|
+
import { hostContribution } from './remote.js';
|
|
29
|
+
/** The base package id, named here too so the item declaration and the spec need no import. */
|
|
30
|
+
export const COMPAT_PACKAGE = '@avantf/dsh-compat';
|
|
31
|
+
/**
|
|
32
|
+
* Fallback range for `@avantf/dsh-compat`, used only when `package.json` has lost the dependency
|
|
33
|
+
* entry. The manifest is the single source of truth (`compatRange()`); `scripts/pack-plugin.mjs`
|
|
34
|
+
* pins this constant to it so the two cannot drift.
|
|
35
|
+
*/
|
|
36
|
+
export const COMPAT_RANGE = '^0.1.0';
|
|
37
|
+
/**
|
|
38
|
+
* The services this plugin calls, with the methods it calls on them.
|
|
39
|
+
*
|
|
40
|
+
* `required` is this plugin's REFUSAL policy, not cordis's `inject`: `typert` is injected (the real
|
|
41
|
+
* wire face is registered at mount) yet a composition without the registry must still mount the
|
|
42
|
+
* memory tools, so its absence is a note rather than a refusal. Optional services are read with
|
|
43
|
+
* `ctx.get()`.
|
|
44
|
+
*
|
|
45
|
+
* `tools` lists only `register` because that is the one method this plugin calls; the post-load
|
|
46
|
+
* check reads `get`, but guards it and degrades to "not verified", so demanding it here would refuse
|
|
47
|
+
* a host this plugin can still drive.
|
|
48
|
+
*/
|
|
49
|
+
export const SERVICE_CONTRACTS = [
|
|
50
|
+
{ name: 'tools', required: true, methods: ['register'] },
|
|
51
|
+
{ name: 'systemPrompt', required: true, methods: ['section', 'context'] },
|
|
52
|
+
{ name: 'typert', required: false, methods: ['register', 'get', 'list', 'listPackages', 'toJSONSchema'] },
|
|
53
|
+
// Read with `ctx.get()` only by the refusal megaphone; a host without it must not become a refusal.
|
|
54
|
+
{ name: 'commands', required: false, methods: ['register'] },
|
|
55
|
+
];
|
|
56
|
+
/**
|
|
57
|
+
* The events this plugin listens to — reported, never verified.
|
|
58
|
+
*
|
|
59
|
+
* A listener for a name the host no longer emits registers happily and then never runs: the house
|
|
60
|
+
* hints would simply stop appearing. Nothing inside a plugin can prove the host still emits a name,
|
|
61
|
+
* so the list is a known limit the gate records and the running dsh version is the operator's signal.
|
|
62
|
+
*/
|
|
63
|
+
export const REQUIRED_EVENTS = ['agent/inbox/inserted', 'tools/result'];
|
|
64
|
+
/** Packages released in lockstep with dsh; their version says which dsh is running. */
|
|
65
|
+
export const VERSION_PACKAGES = ['@deepseek-ai/dsh-tools', '@deepseek-ai/dsh-typert-protocol'];
|
|
66
|
+
/** This plugin's npm package id, which names the probe and verification keys. */
|
|
67
|
+
const PACKAGE_ID = String(hostContribution.package ?? '@avantf/dsh-mem');
|
|
68
|
+
/** Best-effort one-line reason for a caught value. */
|
|
69
|
+
export function reasonOf(error) {
|
|
70
|
+
return error instanceof Error ? error.message : String(error);
|
|
71
|
+
}
|
|
72
|
+
/** Emit a warning without ever letting the logger turn it into a crash. */
|
|
73
|
+
export function warn(log, message) {
|
|
74
|
+
try {
|
|
75
|
+
log?.warn(message);
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
// A logger that throws is not evidence of anything.
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* The range of `@avantf/dsh-compat` this build is written against.
|
|
83
|
+
*
|
|
84
|
+
* Read from THIS plugin's manifest, which is the single source of truth — the framework does not
|
|
85
|
+
* pick it, and a hardcoded constant would silently keep provisioning an old range after the family
|
|
86
|
+
* publishes a new one. The constant is only a fallback for a manifest that lost the entry.
|
|
87
|
+
*
|
|
88
|
+
* It lives in `devDependencies`, deliberately. Nothing imports the base: the framework fetches it
|
|
89
|
+
* into its own managed home and this plugin loads it from there, so a RUNTIME dependency would
|
|
90
|
+
* install a second copy on every consumer that no code path ever loads. `devDependencies` still
|
|
91
|
+
* ships in the packed manifest (pnpm keeps it, rewriting `catalog:` like any other field), so the
|
|
92
|
+
* range travels with the artifact; it just is not installed.
|
|
93
|
+
*/
|
|
94
|
+
export async function compatRange(manifestUrl = new URL('../package.json', import.meta.url)) {
|
|
95
|
+
try {
|
|
96
|
+
const raw = JSON.parse(await readFile(manifestUrl, 'utf8'));
|
|
97
|
+
const declared = raw.devDependencies?.[COMPAT_PACKAGE] ?? raw.dependencies?.[COMPAT_PACKAGE];
|
|
98
|
+
if (typeof declared === 'string' && declared.trim() !== '')
|
|
99
|
+
return declared;
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
// Fall through to the pinned fallback.
|
|
103
|
+
}
|
|
104
|
+
return COMPAT_RANGE;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Build the plugin-specific half of the gate from a loaded base.
|
|
108
|
+
*
|
|
109
|
+
* Called ONCE per process (the loaded runtime is cached by `src/envinit.ts`), which is what makes the
|
|
110
|
+
* lazy construction equivalent to the module-level constants it replaces — `readBuildVersions` still
|
|
111
|
+
* reads the baked `lib/dsh-build.json` beside the built entry, falling back per package to the peer
|
|
112
|
+
* range floor when it is absent (a dev tree, a test run).
|
|
113
|
+
*/
|
|
114
|
+
export function runtimeFromCompat(module) {
|
|
115
|
+
const peerFloors = module.readDeclaredVersions(new URL('../package.json', import.meta.url), VERSION_PACKAGES);
|
|
116
|
+
const buildVersionsUrl = new URL(`./${module.BUILD_VERSIONS_FILE}`, import.meta.url);
|
|
117
|
+
const schemaNames = module.schemaNamesFrom(hostContribution);
|
|
118
|
+
const spec = {
|
|
119
|
+
packageId: PACKAGE_ID,
|
|
120
|
+
services: SERVICE_CONTRACTS,
|
|
121
|
+
// The version THIS BUILD was compiled against: the exact one baked at build time, falling back
|
|
122
|
+
// per package to the peer range floor. A range floor alone cannot say what the build linked.
|
|
123
|
+
declared: module.readBuildVersions(buildVersionsUrl, VERSION_PACKAGES, peerFloors),
|
|
124
|
+
// Resolved from THIS package's links: the packages that identify the host are its peers. Note
|
|
125
|
+
// this is NOT the host's identity — see the base package's README «已知边界».
|
|
126
|
+
runtime: module.readRuntimeVersions(VERSION_PACKAGES, import.meta.url),
|
|
127
|
+
// The base package knows no dsh type, so the probe's declaration comes from here — the probe must
|
|
128
|
+
// mirror the declaration path the REAL tools use.
|
|
129
|
+
probeTool: module.toolProbeDeclaration(defineTool),
|
|
130
|
+
// The wire probe IS the real host face, codecs and all. A probe that merely RESEMBLED it once
|
|
131
|
+
// reported `ok` on a 0.1.6 host whose codec contract had moved, and the real registration then
|
|
132
|
+
// threw halfway through `apply` — the half-mounted outcome this gate exists to prevent. Same
|
|
133
|
+
// object, same host, so "the probe passed" now means "this registration passes".
|
|
134
|
+
probeTypert: () => hostContribution,
|
|
135
|
+
schemaNames,
|
|
136
|
+
events: REQUIRED_EVENTS,
|
|
137
|
+
};
|
|
138
|
+
return { module, prefix: module.COMPAT_PREFIX, spec, schemaNames };
|
|
139
|
+
}
|
|
140
|
+
/** The "the check itself failed" outcome: keep loading, say why. */
|
|
141
|
+
function cannotDetermine(error, log, prefix) {
|
|
142
|
+
const message = `${prefix} WARNING — the compatibility check itself failed (${reasonOf(error)}); loading anyway`;
|
|
143
|
+
warn(log, message);
|
|
144
|
+
return {
|
|
145
|
+
verdict: {
|
|
146
|
+
load: true,
|
|
147
|
+
skipped: true,
|
|
148
|
+
status: 'probe-skipped',
|
|
149
|
+
problems: [],
|
|
150
|
+
warnings: [message],
|
|
151
|
+
notes: ['the check itself failed'],
|
|
152
|
+
lines: [{ level: 'warn', message }],
|
|
153
|
+
reason: '',
|
|
154
|
+
},
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Run the gate. Call this FIRST in `apply()`: on a refusal nothing has been registered yet, so
|
|
159
|
+
* "do not load" costs nothing to unwind. Never throws — not even with a throwing logger, because
|
|
160
|
+
* "cannot tell" is not "incompatible".
|
|
161
|
+
* @param ctx - the plugin's context.
|
|
162
|
+
* @param log - the plugin's logger.
|
|
163
|
+
* @param compat - the loaded gate runtime (see `src/envinit.ts`).
|
|
164
|
+
* @param spec - what to judge (defaults to the runtime's spec; injectable so the version path is
|
|
165
|
+
* testable without a second host).
|
|
166
|
+
* @returns the verdict `apply` branches on.
|
|
167
|
+
*/
|
|
168
|
+
export function provision(ctx, log, compat, spec = compat.spec) {
|
|
169
|
+
let evidence;
|
|
170
|
+
try {
|
|
171
|
+
evidence = compat.module.gatherEvidence(ctx, spec);
|
|
172
|
+
}
|
|
173
|
+
catch (error) {
|
|
174
|
+
return cannotDetermine(error, log, compat.prefix);
|
|
175
|
+
}
|
|
176
|
+
let verdict;
|
|
177
|
+
try {
|
|
178
|
+
verdict = compat.module.verdictOf(evidence);
|
|
179
|
+
}
|
|
180
|
+
catch (error) {
|
|
181
|
+
return cannotDetermine(error, log, compat.prefix);
|
|
182
|
+
}
|
|
183
|
+
for (const line of verdict.lines) {
|
|
184
|
+
try {
|
|
185
|
+
log[line.level](line.message);
|
|
186
|
+
}
|
|
187
|
+
catch {
|
|
188
|
+
// A logger that throws must not turn a verdict into a crash.
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return { verdict };
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Keep one `/mem` command that reports a refusal.
|
|
195
|
+
*
|
|
196
|
+
* The plugin provides nothing else when it refuses, and the alternative is a user watching a tab
|
|
197
|
+
* that never loads with no way to ask why.
|
|
198
|
+
* @param ctx - the plugin's context.
|
|
199
|
+
* @param verdict - the refusal to report.
|
|
200
|
+
* @param log - the plugin's logger.
|
|
201
|
+
* @param compat - the loaded gate runtime.
|
|
202
|
+
*/
|
|
203
|
+
export function registerCompatMegaphone(ctx, verdict, log, compat) {
|
|
204
|
+
compat.module.registerMegaphone({
|
|
205
|
+
ctx,
|
|
206
|
+
log,
|
|
207
|
+
command: { name: 'mem', description: '报告记忆插件为何未加载(兼容性检查未通过)' },
|
|
208
|
+
text: compat.module.compatReport(verdict, {
|
|
209
|
+
heading: '记忆插件未加载:与当前 dsh 的兼容性检查未通过,插件已拒绝加载(不注册服务、工具、prompt 段与真实 typert face)。',
|
|
210
|
+
warningsLabel: '风险提示:',
|
|
211
|
+
warnings: verdict.warnings,
|
|
212
|
+
fix: '修复:在本仓库重建(`pnpm build:dsh`),或把 `@deepseek-ai/dsh` 换回本构建声明的版本。',
|
|
213
|
+
}),
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* The second phase: every real registration must be visible afterwards.
|
|
218
|
+
*
|
|
219
|
+
* Warn-only by design — the plugin is mounted by now, so there is no clean "do not load" left to
|
|
220
|
+
* take, and a silently dropped schema or tool is exactly what nothing else would report.
|
|
221
|
+
* @param input - the live context, the real tool names, the logger, and the loaded gate runtime.
|
|
222
|
+
* @returns the registrations that did not show up (empty on success).
|
|
223
|
+
*/
|
|
224
|
+
export function verifyRegisteredFaces(input) {
|
|
225
|
+
return input.compat.module.verifyRegisteredFaces({
|
|
226
|
+
ctx: input.ctx,
|
|
227
|
+
log: input.log,
|
|
228
|
+
packageId: input.compat.spec.packageId,
|
|
229
|
+
schemaNames: input.compat.schemaNames,
|
|
230
|
+
toolNames: input.toolNames,
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
//# sourceMappingURL=provision.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provision.js","sourceRoot":"","sources":["../../src/provision.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { InvocationDescriptor, TypertRemoteContribution } from '@deepseek-ai/dsh-typert-protocol';
|
|
2
|
+
import type { TypertContribution } from '@deepseek-ai/dsh-typert-registry/types';
|
|
3
|
+
export declare const descriptors: readonly InvocationDescriptor[];
|
|
4
|
+
/** Client face: mounted by the client half through `ctx.remote.$mount()`. */
|
|
5
|
+
export declare const clientContribution: TypertRemoteContribution;
|
|
6
|
+
/**
|
|
7
|
+
* Host face: registered by the host half through `ctx.typert.register()`.
|
|
8
|
+
*
|
|
9
|
+
* The schema assertions name `TypertSchema['schema']` — the FIELD they are assigned to — rather
|
|
10
|
+
* than this package's own `z.ZodType`. The two are different zod copies: the plugin pins
|
|
11
|
+
* zod 4.4.3, the harness bundles 4.6.2, and `ZodType` gained members between them, so a cast to
|
|
12
|
+
* the local `z.ZodType` could never be assignable and the annotation said nothing. Through
|
|
13
|
+
* `TypertSchema['schema']` the assertion is at least against the type the field actually
|
|
14
|
+
* requires, and a future zod alignment (which would make the cast unnecessary) shows up here.
|
|
15
|
+
*/
|
|
16
|
+
export declare const hostContribution: TypertContribution;
|
|
17
|
+
//# sourceMappingURL=remote.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote.d.ts","sourceRoot":"","sources":["../../src/remote.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EACV,oBAAoB,EAGpB,wBAAwB,EACzB,MAAM,kCAAkC,CAAA;AACzC,OAAO,KAAK,EAAE,kBAAkB,EAAgB,MAAM,wCAAwC,CAAA;AAuE9F,eAAO,MAAM,WAAW,EAAE,SAAS,oBAAoB,EAqGtD,CAAA;AAED,6EAA6E;AAC7E,eAAO,MAAM,kBAAkB,EAAE,wBAGhC,CAAA;AAqBD;;;;;;;;;GASG;AACH,eAAO,MAAM,gBAAgB,EAAE,kBA0C9B,CAAA"}
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hand-written Typert wire faces for the `avantfMem` Remote namespace.
|
|
3
|
+
*
|
|
4
|
+
* DSH packages normally ship generator-produced faces (`typert.host.js` /
|
|
5
|
+
* `typert.remote-client.js`), but the Typert generator runs only inside the
|
|
6
|
+
* harness workspace. Both faces are therefore hand-written here, following the
|
|
7
|
+
* generator's exact conventions: zod v4 strict codecs, one `args` object
|
|
8
|
+
* parameter per method, `<pkg>#<namespace>/<method>` invocation ids, and a host
|
|
9
|
+
* contribution registered through `ctx.typert.register()` (the documented
|
|
10
|
+
* path for hand-written wire schemas, see `@deepseek-ai/dsh-typert-loader`).
|
|
11
|
+
*
|
|
12
|
+
* The five methods mirror the five agent tools (remember/recall/admin/kb/query)
|
|
13
|
+
* so the 记忆/知识 tabs can do full CRUD + KB management. Args carry the merged
|
|
14
|
+
* optional field set of the contract's action unions; the HOST re-validates
|
|
15
|
+
* every payload with the contract zod schema before dispatch, so the wire face
|
|
16
|
+
* only needs to guarantee JSON shape sanity. Five methods have no tool behind
|
|
17
|
+
* them — `openDoc` (the 知识 tab's 「编辑」/「打开目录」 buttons), `classifySource`
|
|
18
|
+
* and `browseDir` (its source input and 选择 picker), `kbDomains` (its domain
|
|
19
|
+
* dropdown) and `kbAddDomain` (its 「+」 next to that dropdown).
|
|
20
|
+
*
|
|
21
|
+
* The host half consumes `hostContribution`; the client half mounts
|
|
22
|
+
* `clientContribution` via `ctx.remote.$mount()`.
|
|
23
|
+
*/
|
|
24
|
+
import { z } from 'zod';
|
|
25
|
+
const PACKAGE = '@avantf/dsh-mem';
|
|
26
|
+
const NAMESPACE = 'avantfMem';
|
|
27
|
+
const endpointId = (method) => `${PACKAGE}#${NAMESPACE}/${method}`;
|
|
28
|
+
const fieldSymbol = (method, field) => `${PACKAGE}#${NAMESPACE}/${method}:${field}`;
|
|
29
|
+
const resultSymbol = (method) => fieldSymbol(method, 'result');
|
|
30
|
+
/**
|
|
31
|
+
* zod v4 strict codec envelope the Typert boundary validates with.
|
|
32
|
+
*
|
|
33
|
+
* Carries BOTH members on purpose: the host's validator moved from `codec.schema.parse` (0.1.5) to
|
|
34
|
+
* `codec.create()` (0.1.6), and each generation checks only its own. One shape therefore serves
|
|
35
|
+
* either host — the same "one shape satisfies two revisions" trick the job plugin's `strict()` uses.
|
|
36
|
+
*/
|
|
37
|
+
function strict(schema, typeSymbol) {
|
|
38
|
+
return { mode: 'strict', typeSymbol, schema, create: () => schema };
|
|
39
|
+
}
|
|
40
|
+
/** One JSON wire parameter; optional parameters accept a missing wire field. */
|
|
41
|
+
function parameter(method, name, schema, acceptsUndefined) {
|
|
42
|
+
return {
|
|
43
|
+
name,
|
|
44
|
+
wire: name,
|
|
45
|
+
source: 'json',
|
|
46
|
+
codec: strict(schema, fieldSymbol(method, name)),
|
|
47
|
+
...(acceptsUndefined === undefined ? {} : { acceptsUndefined }),
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
const text = z.string();
|
|
51
|
+
// Optional wire fields are written as `X.optional()`, NOT `z.union([z.undefined(), X])`. The two
|
|
52
|
+
// accept the same payloads, but the union is invisible to the HOST's JSON-Schema projector:
|
|
53
|
+
// `z.toJSONSchema()` throws "Undefined cannot be represented in JSON Schema" over it, and the
|
|
54
|
+
// startup compatibility gate projects the REAL wire face through that host method — so the union
|
|
55
|
+
// form made a healthy host read as an incompatible one. `.optional()` projects to a non-required
|
|
56
|
+
// property, which is exactly what these fields are.
|
|
57
|
+
const count = z.number().int().optional();
|
|
58
|
+
const optionalText = z.string().optional();
|
|
59
|
+
const bool = z.boolean().optional();
|
|
60
|
+
const textArray = z.array(z.string()).optional();
|
|
61
|
+
/** One direct Remote method carrying a single `args` object parameter. */
|
|
62
|
+
function direct(method, args) {
|
|
63
|
+
return {
|
|
64
|
+
id: endpointId(method),
|
|
65
|
+
service: NAMESPACE,
|
|
66
|
+
namespace: NAMESPACE,
|
|
67
|
+
method,
|
|
68
|
+
invocation: { kind: 'direct' },
|
|
69
|
+
parameters: [parameter(method, 'args', args)],
|
|
70
|
+
// The runtime's result shapes vary by store backend and evolve fast;
|
|
71
|
+
// keep the boundary tolerant (`z.any()` never rejects a host reply).
|
|
72
|
+
result: strict(z.any(), resultSymbol(method)),
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
export const descriptors = [
|
|
76
|
+
// remember: add/update/remove/helpful/unhelpful (action defaults to 'add' host-side)
|
|
77
|
+
direct('remember', z.object({
|
|
78
|
+
action: optionalText.optional(),
|
|
79
|
+
content: optionalText.optional(),
|
|
80
|
+
fact_id: count.optional(),
|
|
81
|
+
category: optionalText.optional(),
|
|
82
|
+
ttl_days: count.optional(),
|
|
83
|
+
reason: optionalText.optional(),
|
|
84
|
+
})),
|
|
85
|
+
// recall: search/ask/chain/probe/reason/related/contradict (defaults to 'search')
|
|
86
|
+
direct('recall', z.object({
|
|
87
|
+
action: optionalText.optional(),
|
|
88
|
+
query: optionalText.optional(),
|
|
89
|
+
entity: optionalText.optional(),
|
|
90
|
+
entities: textArray.optional(),
|
|
91
|
+
subj: optionalText.optional(),
|
|
92
|
+
pred: optionalText.optional(),
|
|
93
|
+
obj: optionalText.optional(),
|
|
94
|
+
second_pred: optionalText.optional(),
|
|
95
|
+
category: optionalText.optional(),
|
|
96
|
+
limit: count.optional(),
|
|
97
|
+
max_tokens: count.optional(),
|
|
98
|
+
})),
|
|
99
|
+
// admin: stats/list/detail/archive/restore/vectors_*/contradict_*/maintenance (defaults to 'list')
|
|
100
|
+
//
|
|
101
|
+
// Every field the client sends must be declared here: a strict codec PARSES the args before they
|
|
102
|
+
// go out (harness `api/gateway` `parseInput`), and a zod object drops unknown keys — a missing
|
|
103
|
+
// field is not an error, it is a silently emptied request that then fails contract validation
|
|
104
|
+
// host-side. That is exactly how the three 矛盾裁决 buttons shipped broken: `contradiction_id`,
|
|
105
|
+
// `resolution` and `loser_fact_id` were never declared, so only `{action}` reached the host.
|
|
106
|
+
// `test/remote_wire.spec.ts` pins the invariant that actually generalises — declared ⊇ the
|
|
107
|
+
// contract union's fields — because "declared ⊇ what the client source sends" has blind spots a
|
|
108
|
+
// wrapper function (`kbCall(label, args)`) or a conditional spread hides.
|
|
109
|
+
direct('admin', z.object({
|
|
110
|
+
action: optionalText.optional(),
|
|
111
|
+
fact_id: count.optional(),
|
|
112
|
+
category: optionalText.optional(),
|
|
113
|
+
status: optionalText.optional(),
|
|
114
|
+
limit: count.optional(),
|
|
115
|
+
offset: count.optional(),
|
|
116
|
+
reason: optionalText.optional(),
|
|
117
|
+
dry_run: bool.optional(),
|
|
118
|
+
contradiction_id: count.optional(),
|
|
119
|
+
resolution: optionalText.optional(),
|
|
120
|
+
loser_fact_id: count.optional(),
|
|
121
|
+
})),
|
|
122
|
+
// kb: ingest/import/list/detail/remove/reindex/sync (action REQUIRED — no safe default)
|
|
123
|
+
//
|
|
124
|
+
// `overwrite` is a field of THIS face only: the UI's 入库 form sends it after the user confirms
|
|
125
|
+
// the collision dialog, and the CLI after `--overwrite`. It is deliberately NOT a field of
|
|
126
|
+
// `KB_ADD_TOOL.input`, so the add-only mode cannot leak into the model's view.
|
|
127
|
+
//
|
|
128
|
+
// `adopt` is the 知识 tab's 「认领文件」 button: sync one document whose frontmatter was destroyed
|
|
129
|
+
// by a whole-file overwrite, accepting the store's guess about which row it belongs to. It was
|
|
130
|
+
// missing from this face, so the button sent `{action:'sync', doc_id}` and reported
|
|
131
|
+
// 「认领完成:0 篇」 — the fourth field to ship silently undeclared.
|
|
132
|
+
direct('kb', z.object({
|
|
133
|
+
action: optionalText.optional(),
|
|
134
|
+
text: optionalText.optional(),
|
|
135
|
+
source_uri: optionalText.optional(),
|
|
136
|
+
domain: optionalText.optional(),
|
|
137
|
+
source: optionalText.optional(),
|
|
138
|
+
title: optionalText.optional(),
|
|
139
|
+
paths: textArray.optional(),
|
|
140
|
+
doc_id: count.optional(),
|
|
141
|
+
limit: count.optional(),
|
|
142
|
+
offset: count.optional(),
|
|
143
|
+
dry_run: bool.optional(),
|
|
144
|
+
overwrite: bool.optional(),
|
|
145
|
+
adopt: bool.optional(),
|
|
146
|
+
})),
|
|
147
|
+
// query: cross-store retrieval
|
|
148
|
+
direct('query', z.object({
|
|
149
|
+
query: text,
|
|
150
|
+
kind: optionalText.optional(),
|
|
151
|
+
domain: optionalText.optional(),
|
|
152
|
+
source: optionalText.optional(),
|
|
153
|
+
limit: count.optional(),
|
|
154
|
+
max_tokens: count.optional(),
|
|
155
|
+
})),
|
|
156
|
+
// classifySource / browseDir: UI-only. The 知识 tab has ONE source input, so the host has to say
|
|
157
|
+
// what a string IS (URL / file / directory / missing / pasted text) and let the user browse for a
|
|
158
|
+
// path — a browser can check `^https?://` and nothing else, and only the host may stat a path.
|
|
159
|
+
direct('classifySource', z.object({ text: optionalText.optional() })),
|
|
160
|
+
direct('browseDir', z.object({ path: optionalText.optional() })),
|
|
161
|
+
// kbDomains: UI-only. The 知识 tab's domain control is a picker, and the two halves of its option
|
|
162
|
+
// list — the configured `knowledge.domains` allowlist and the domains already in the library —
|
|
163
|
+
// live host-side, so the client asks for the union instead of guessing it.
|
|
164
|
+
direct('kbDomains', z.object({})),
|
|
165
|
+
// kbAddDomain: UI-only (no agent tool mirrors it, deliberately — an autonomous writer is where
|
|
166
|
+
// domain sprawl would come from). Appends the name to the store config's `domains` allowlist and
|
|
167
|
+
// to the live set, and answers with the new catalog so the picker can select it.
|
|
168
|
+
direct('kbAddDomain', z.object({ domain: text })),
|
|
169
|
+
// openDoc: UI-only (no agent tool mirrors it) — hand one managed document file, or the
|
|
170
|
+
// directory holding it, to the user's editor. The host resolves the path from `doc_id`, so the
|
|
171
|
+
// client never supplies a path the host would have to trust.
|
|
172
|
+
direct('openDoc', z.object({
|
|
173
|
+
doc_id: count,
|
|
174
|
+
target: optionalText.optional(),
|
|
175
|
+
})),
|
|
176
|
+
];
|
|
177
|
+
/** Client face: mounted by the client half through `ctx.remote.$mount()`. */
|
|
178
|
+
export const clientContribution = {
|
|
179
|
+
package: PACKAGE,
|
|
180
|
+
descriptors,
|
|
181
|
+
};
|
|
182
|
+
/** Declare one registered wire schema: the factory 0.1.6 calls, plus the schema 0.1.5 reads. */
|
|
183
|
+
function declared(name, schema) {
|
|
184
|
+
return { name, schema, create: () => schema };
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Host face: registered by the host half through `ctx.typert.register()`.
|
|
188
|
+
*
|
|
189
|
+
* The schema assertions name `TypertSchema['schema']` — the FIELD they are assigned to — rather
|
|
190
|
+
* than this package's own `z.ZodType`. The two are different zod copies: the plugin pins
|
|
191
|
+
* zod 4.4.3, the harness bundles 4.6.2, and `ZodType` gained members between them, so a cast to
|
|
192
|
+
* the local `z.ZodType` could never be assignable and the annotation said nothing. Through
|
|
193
|
+
* `TypertSchema['schema']` the assertion is at least against the type the field actually
|
|
194
|
+
* requires, and a future zod alignment (which would make the cast unnecessary) shows up here.
|
|
195
|
+
*/
|
|
196
|
+
export const hostContribution = {
|
|
197
|
+
package: PACKAGE,
|
|
198
|
+
face: 'host',
|
|
199
|
+
schemas: descriptors.flatMap((descriptor) => [
|
|
200
|
+
...descriptor.parameters.map(parameter => declared(`${descriptor.method}${parameter.name}`, parameter.codec.schema)),
|
|
201
|
+
declared(`${descriptor.method}Result`, descriptor.result.schema),
|
|
202
|
+
]),
|
|
203
|
+
model: {
|
|
204
|
+
services: [
|
|
205
|
+
{
|
|
206
|
+
key: 'avantfMemory',
|
|
207
|
+
exportName: 'avantfMemory',
|
|
208
|
+
description: 'avantf-mem runtime facade: memory store, knowledge store, ingestion, lifecycle, cross-retrieval router',
|
|
209
|
+
summary: 'avantf-mem engine runtime',
|
|
210
|
+
tags: [],
|
|
211
|
+
members: [],
|
|
212
|
+
types: [],
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
key: NAMESPACE,
|
|
216
|
+
exportName: NAMESPACE,
|
|
217
|
+
description: 'Client Remote namespace: remember / recall / admin / kb / query over the avantf-mem stores',
|
|
218
|
+
summary: 'avantf-mem client remote',
|
|
219
|
+
tags: [],
|
|
220
|
+
members: descriptors.map(descriptor => ({
|
|
221
|
+
kind: 'method',
|
|
222
|
+
name: descriptor.method,
|
|
223
|
+
signature: '(args: object) => Promise<unknown>',
|
|
224
|
+
})),
|
|
225
|
+
types: [],
|
|
226
|
+
},
|
|
227
|
+
],
|
|
228
|
+
events: [],
|
|
229
|
+
objects: [],
|
|
230
|
+
},
|
|
231
|
+
invocations: descriptors,
|
|
232
|
+
};
|
|
233
|
+
//# sourceMappingURL=remote.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote.js","sourceRoot":"","sources":["../../src/remote.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { type ToolSpec } from '@avantf/mem-contract';
|
|
2
|
+
export type ParamSpec = {
|
|
3
|
+
type: 'string' | 'number' | 'integer' | 'boolean' | 'array' | 'object';
|
|
4
|
+
description?: string;
|
|
5
|
+
required?: true;
|
|
6
|
+
enum?: readonly string[];
|
|
7
|
+
items?: ParamSpec;
|
|
8
|
+
};
|
|
9
|
+
/** The slice of zod v4's `def` this derivation reads (structure only, never type tags). */
|
|
10
|
+
export interface ZodDef {
|
|
11
|
+
type?: string;
|
|
12
|
+
shape?: Record<string, unknown>;
|
|
13
|
+
options?: unknown[];
|
|
14
|
+
/** A literal's / enum's values; v4 keeps them in an array. */
|
|
15
|
+
values?: unknown;
|
|
16
|
+
}
|
|
17
|
+
export declare function zodDef(schema: unknown): ZodDef;
|
|
18
|
+
/** Nearest `description` on a schema (wrappers included — the converter already unwrapped them). */
|
|
19
|
+
export declare function schemaDescription(schema: unknown): string | undefined;
|
|
20
|
+
export declare function zodToSpec(schema: unknown): ParamSpec;
|
|
21
|
+
/** Materialize one zod object branch's fields, or undefined for a non-object. */
|
|
22
|
+
export declare function branchShape(schema: unknown): Record<string, unknown> | undefined;
|
|
23
|
+
/**
|
|
24
|
+
* Flatten a tool input schema into DSH's implicit parameter map. A discriminated
|
|
25
|
+
* union contributes one required `action` enum plus the merged field set (fields
|
|
26
|
+
* stay optional at the schema level because requiredness differs per action; the
|
|
27
|
+
* per-action requirement is stated in each field's description and enforced by
|
|
28
|
+
* `spec.input` validation before dispatch). A plain object marks its own required
|
|
29
|
+
* fields directly.
|
|
30
|
+
*
|
|
31
|
+
* The merged descriptions come from the contract's {@link mergedFieldDescription}, the SAME
|
|
32
|
+
* function `toolInputJsonSchema` uses for the MCP surface. Taking each field's first branch
|
|
33
|
+
* verbatim is what made the two model-facing surfaces disagree: `mem_admin`'s `fact_id` said
|
|
34
|
+
* "action=detail 时必填" on this surface while the MCP schema said
|
|
35
|
+
* "【detail/archive/restore/pin/unpin 必填】" — so a model calling `archive` without it had to
|
|
36
|
+
* learn the requirement from a `violations` retry. Both surfaces now read the same merged
|
|
37
|
+
* descriptions, which is what keeps them in agreement field for field.
|
|
38
|
+
*/
|
|
39
|
+
export declare function flattenToolSpec(spec: ToolSpec): Record<string, ParamSpec>;
|
|
40
|
+
//# sourceMappingURL=tool_schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool_schema.d.ts","sourceRoot":"","sources":["../../src/tool_schema.ts"],"names":[],"mappings":"AAgBA,OAAO,EAA0B,KAAK,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAE5E,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,QAAQ,CAAA;IACtE,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,IAAI,CAAA;IACf,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACxB,KAAK,CAAC,EAAE,SAAS,CAAA;CAClB,CAAA;AAED,2FAA2F;AAC3F,MAAM,WAAW,MAAM;IACrB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC/B,OAAO,CAAC,EAAE,OAAO,EAAE,CAAA;IACnB,8DAA8D;IAC9D,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB;AAED,wBAAgB,MAAM,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAE9C;AAkBD,oGAAoG;AACpG,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAGrE;AAqBD,wBAAgB,SAAS,CAAC,MAAM,EAAE,OAAO,GAAG,SAAS,CAEpD;AAED,iFAAiF;AACjF,wBAAgB,WAAW,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAEhF;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAiDzE"}
|