@superdoc-dev/sdk 1.19.2 → 1.20.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/action-primitives/doc-index.cjs +215 -0
- package/dist/action-primitives/doc-index.d.ts +83 -0
- package/dist/action-primitives/doc-index.d.ts.map +1 -0
- package/dist/action-primitives/doc-index.js +211 -0
- package/dist/action-primitives/engine.cjs +204 -0
- package/dist/action-primitives/engine.d.ts +71 -0
- package/dist/action-primitives/engine.d.ts.map +1 -0
- package/dist/action-primitives/engine.js +196 -0
- package/dist/action-primitives/receipt.cjs +39 -0
- package/dist/action-primitives/receipt.d.ts +49 -0
- package/dist/action-primitives/receipt.d.ts.map +1 -0
- package/dist/action-primitives/receipt.js +32 -0
- package/dist/action-primitives/resolve.cjs +252 -0
- package/dist/action-primitives/resolve.d.ts +56 -0
- package/dist/action-primitives/resolve.d.ts.map +1 -0
- package/dist/action-primitives/resolve.js +246 -0
- package/dist/action-primitives/session-cache.cjs +43 -0
- package/dist/action-primitives/session-cache.d.ts +19 -0
- package/dist/action-primitives/session-cache.d.ts.map +1 -0
- package/dist/action-primitives/session-cache.js +37 -0
- package/dist/action-primitives/tools/list-transform.cjs +661 -0
- package/dist/action-primitives/tools/list-transform.d.ts +98 -0
- package/dist/action-primitives/tools/list-transform.d.ts.map +1 -0
- package/dist/action-primitives/tools/list-transform.js +656 -0
- package/dist/action-primitives/tools/structure-insert.cjs +1343 -0
- package/dist/action-primitives/tools/structure-insert.d.ts +183 -0
- package/dist/action-primitives/tools/structure-insert.d.ts.map +1 -0
- package/dist/action-primitives/tools/structure-insert.js +1338 -0
- package/dist/action-primitives/tools/text-transform.cjs +669 -0
- package/dist/action-primitives/tools/text-transform.d.ts +64 -0
- package/dist/action-primitives/tools/text-transform.d.ts.map +1 -0
- package/dist/action-primitives/tools/text-transform.js +664 -0
- package/dist/action-primitives/types.d.ts +36 -0
- package/dist/action-primitives/types.d.ts.map +1 -0
- package/dist/action-primitives/types.js +15 -0
- package/dist/agent/actions.cjs +5381 -0
- package/dist/agent/actions.d.ts +404 -0
- package/dist/agent/actions.d.ts.map +1 -0
- package/dist/agent/actions.js +5373 -0
- package/dist/agent/catalog.cjs +483 -0
- package/dist/agent/catalog.d.ts +103 -0
- package/dist/agent/catalog.d.ts.map +1 -0
- package/dist/agent/catalog.js +471 -0
- package/dist/agent/doc-snapshot.cjs +663 -0
- package/dist/agent/doc-snapshot.d.ts +247 -0
- package/dist/agent/doc-snapshot.d.ts.map +1 -0
- package/dist/agent/doc-snapshot.js +657 -0
- package/dist/agent/index.d.ts +16 -0
- package/dist/agent/index.d.ts.map +1 -0
- package/dist/agent/index.js +15 -0
- package/dist/agent/ir.cjs +170 -0
- package/dist/agent/ir.d.ts +216 -0
- package/dist/agent/ir.d.ts.map +1 -0
- package/dist/agent/ir.js +181 -0
- package/dist/agent/operation-catalog.cjs +418 -0
- package/dist/agent/operation-catalog.d.ts +36 -0
- package/dist/agent/operation-catalog.d.ts.map +1 -0
- package/dist/agent/operation-catalog.js +446 -0
- package/dist/agent/runtime.cjs +501 -0
- package/dist/agent/runtime.d.ts +120 -0
- package/dist/agent/runtime.d.ts.map +1 -0
- package/dist/agent/runtime.js +493 -0
- package/dist/embedded-prompts.generated.cjs +13 -0
- package/dist/embedded-prompts.generated.d.ts +4 -0
- package/dist/embedded-prompts.generated.d.ts.map +1 -0
- package/dist/embedded-prompts.generated.js +9 -0
- package/dist/generated/client.cjs +18 -0
- package/dist/generated/client.d.ts +134 -0
- package/dist/generated/client.d.ts.map +1 -1
- package/dist/generated/client.js +18 -0
- package/dist/generated/contract.cjs +622 -3
- package/dist/generated/contract.d.ts.map +1 -1
- package/dist/generated/contract.js +622 -3
- package/dist/index.cjs +3 -7
- package/dist/index.d.ts +8 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -8
- package/dist/presets/core.cjs +454 -0
- package/dist/presets/core.d.ts +20 -0
- package/dist/presets/core.d.ts.map +1 -0
- package/dist/presets/core.js +447 -0
- package/dist/presets.cjs +55 -8
- package/dist/presets.d.ts +39 -8
- package/dist/presets.d.ts.map +1 -1
- package/dist/presets.js +53 -8
- package/dist/prompts/mcp-prompt.md +23 -0
- package/dist/prompts/system-prompt.md +108 -0
- package/dist/runtime/transport-common.cjs +8 -0
- package/dist/runtime/transport-common.d.ts.map +1 -1
- package/dist/runtime/transport-common.js +8 -0
- package/dist/tools.cjs +46 -11
- package/dist/tools.d.ts +55 -8
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +45 -13
- package/package.json +9 -8
- package/tools/__pycache__/__init__.cpython-312.pyc +0 -0
- package/tools/__pycache__/intent_dispatch_generated.cpython-312.pyc +0 -0
- package/tools/catalog.json +14 -0
- package/tools/tools-policy.json +1 -1
- package/tools/tools.anthropic.json +14 -0
- package/tools/tools.generic.json +14 -0
- package/tools/tools.openai.json +14 -0
- package/tools/tools.vercel.json +14 -0
|
@@ -0,0 +1,447 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `core` preset — actions-only LLM-facing surface.
|
|
3
|
+
*
|
|
4
|
+
* Two advertised tools: superdoc_inspect (read-only deterministic snapshots)
|
|
5
|
+
* and superdoc_perform_action (named, statically validated, deterministic edit
|
|
6
|
+
* verbs — the action registry in agent/actions.ts).
|
|
7
|
+
*
|
|
8
|
+
* superdoc_execute_code (model-authored JS against a synchronous in-host doc)
|
|
9
|
+
* is WIP: dispatchable for SDK callers, NOT advertised and NOT in the served
|
|
10
|
+
* system prompt until it ships behind a safety flag. The agent_apply /
|
|
11
|
+
* agent_verify / agent_operation tools are likewise dispatchable but never
|
|
12
|
+
* advertised.
|
|
13
|
+
*
|
|
14
|
+
* @internal
|
|
15
|
+
*/
|
|
16
|
+
import { readFile } from 'node:fs/promises';
|
|
17
|
+
import path from 'node:path';
|
|
18
|
+
import { fileURLToPath } from 'node:url';
|
|
19
|
+
import { SuperDocCliError } from '../runtime/errors.js';
|
|
20
|
+
import { AGENT_TOOL_DEFINITIONS, isAgentToolName, listAgentTools, validateExclusions, PUBLIC_AGENT_TOOL_NAMES, } from '../agent/catalog.js';
|
|
21
|
+
import { agentApply, agentInspect, agentOperation, agentVerify } from '../agent/runtime.js';
|
|
22
|
+
import { superdocPerformAction } from '../agent/actions.js';
|
|
23
|
+
import { EMBEDDED_PROMPTS } from '../embedded-prompts.generated.js';
|
|
24
|
+
// Prompts ship as <dist>/prompts/*.md. Resolve relative to the compiled
|
|
25
|
+
// module, but the module's depth differs by build: in the SDK package this
|
|
26
|
+
// file is dist/presets/core.js (so prompts are at ../prompts), while the
|
|
27
|
+
// bundled CLI inlines it into dist/index.js (so prompts are at ./prompts).
|
|
28
|
+
// Try both so getSystemPrompt works through the SDK AND the CLI host (the
|
|
29
|
+
// path the Python SDK proxies through).
|
|
30
|
+
const MODULE_DIR = path.dirname(fileURLToPath(import.meta.url));
|
|
31
|
+
const PROMPT_DIR_CANDIDATES = [path.resolve(MODULE_DIR, '..', 'prompts'), path.resolve(MODULE_DIR, 'prompts')];
|
|
32
|
+
let _actionsOnlyPromptCache = null;
|
|
33
|
+
let _mcpPromptCache = null;
|
|
34
|
+
/** Exported for unit tests; production callers use the default candidates. */
|
|
35
|
+
export async function readPromptFile(fileName, label, candidateDirs = PROMPT_DIR_CANDIDATES) {
|
|
36
|
+
const tried = [];
|
|
37
|
+
let lastIoError;
|
|
38
|
+
for (const dir of candidateDirs) {
|
|
39
|
+
const promptPath = path.join(dir, fileName);
|
|
40
|
+
tried.push(promptPath);
|
|
41
|
+
try {
|
|
42
|
+
return await readFile(promptPath, 'utf8');
|
|
43
|
+
}
|
|
44
|
+
catch (err) {
|
|
45
|
+
const ioError = err;
|
|
46
|
+
if (ioError?.code !== 'ENOENT') {
|
|
47
|
+
// Permission/IO failures are not "asset missing" — remember the real
|
|
48
|
+
// cause, but still try the other layout candidate.
|
|
49
|
+
lastIoError = ioError;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
// Filesystem candidates exhausted. Native binaries (bun --compile) resolve
|
|
54
|
+
// MODULE_DIR inside bun's virtual filesystem where the .md assets don't
|
|
55
|
+
// exist — fall back to the compiled-in copies (identical content by
|
|
56
|
+
// construction; a drift test enforces it).
|
|
57
|
+
const embedded = EMBEDDED_PROMPTS[fileName];
|
|
58
|
+
if (typeof embedded === 'string') {
|
|
59
|
+
return embedded;
|
|
60
|
+
}
|
|
61
|
+
if (lastIoError) {
|
|
62
|
+
throw new SuperDocCliError(`${label} could not be read: ${lastIoError.message}`, {
|
|
63
|
+
code: 'TOOLS_ASSET_UNREADABLE',
|
|
64
|
+
details: { triedPaths: tried, cause: `${lastIoError.code ?? lastIoError.name}: ${lastIoError.message}` },
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
throw new SuperDocCliError(`${label} not found.`, {
|
|
68
|
+
code: 'TOOLS_ASSET_NOT_FOUND',
|
|
69
|
+
details: { triedPaths: tried },
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
function isRecord(value) {
|
|
73
|
+
return typeof value === 'object' && value != null && !Array.isArray(value);
|
|
74
|
+
}
|
|
75
|
+
function isObviouslyCorruptedToolArgKey(key) {
|
|
76
|
+
const trimmed = key.trim();
|
|
77
|
+
return trimmed.length === 0 || !/[\p{L}\p{N}]/u.test(trimmed);
|
|
78
|
+
}
|
|
79
|
+
function stripCorruptedToolArgKeys(value) {
|
|
80
|
+
if (Array.isArray(value)) {
|
|
81
|
+
return value.map((item) => stripCorruptedToolArgKeys(item));
|
|
82
|
+
}
|
|
83
|
+
if (!isRecord(value))
|
|
84
|
+
return value;
|
|
85
|
+
const clean = {};
|
|
86
|
+
for (const [key, entryValue] of Object.entries(value)) {
|
|
87
|
+
if (isObviouslyCorruptedToolArgKey(key))
|
|
88
|
+
continue;
|
|
89
|
+
clean[key] = stripCorruptedToolArgKeys(entryValue);
|
|
90
|
+
}
|
|
91
|
+
return clean;
|
|
92
|
+
}
|
|
93
|
+
function validateAgentToolArgs(toolName, args) {
|
|
94
|
+
const definition = AGENT_TOOL_DEFINITIONS.find((entry) => entry.name === toolName);
|
|
95
|
+
if (definition == null)
|
|
96
|
+
return;
|
|
97
|
+
const schema = definition.inputSchema;
|
|
98
|
+
const properties = isRecord(schema.properties) ? schema.properties : {};
|
|
99
|
+
const required = Array.isArray(schema.required) ? schema.required : [];
|
|
100
|
+
const knownKeys = new Set(Object.keys(properties));
|
|
101
|
+
const unknownKeys = Object.keys(args).filter((key) => !knownKeys.has(key));
|
|
102
|
+
if (unknownKeys.length > 0) {
|
|
103
|
+
throw new SuperDocCliError(`Unknown argument(s) for ${toolName}: ${unknownKeys.join(', ')}`, {
|
|
104
|
+
code: 'INVALID_ARGUMENT',
|
|
105
|
+
details: { toolName, unknownKeys, knownKeys: [...knownKeys] },
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
const missingKeys = required.filter((key) => args[key] == null);
|
|
109
|
+
if (missingKeys.length > 0) {
|
|
110
|
+
throw new SuperDocCliError(`Missing required argument(s) for ${toolName}: ${missingKeys.join(', ')}`, {
|
|
111
|
+
code: 'INVALID_ARGUMENT',
|
|
112
|
+
details: { toolName, missingKeys },
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
// ---------------------------------------------------------------------------
|
|
117
|
+
// Compaction helpers — keep agent receipts tight in the tool-result payload
|
|
118
|
+
// ---------------------------------------------------------------------------
|
|
119
|
+
/**
|
|
120
|
+
* Max entries for per-item receipt lists (executedOperations, selectedTargets).
|
|
121
|
+
* Receipts live in the conversation and are re-billed as prompt tokens on every
|
|
122
|
+
* subsequent turn; unbounded lists (one op per formatted range/paragraph) made
|
|
123
|
+
* single receipts cost thousands of tokens. 8 keeps enough shape to audit while
|
|
124
|
+
* the accompanying *Count field preserves the true total.
|
|
125
|
+
*/
|
|
126
|
+
const RECEIPT_LIST_CAP = 8;
|
|
127
|
+
function compactCountMap(counts) {
|
|
128
|
+
const compact = {};
|
|
129
|
+
for (const [key, value] of Object.entries(counts)) {
|
|
130
|
+
if (typeof value === 'number' && value !== 0)
|
|
131
|
+
compact[key] = value;
|
|
132
|
+
}
|
|
133
|
+
if (Object.keys(compact).length === 0 && typeof counts.blocks === 'number') {
|
|
134
|
+
compact.blocks = counts.blocks;
|
|
135
|
+
}
|
|
136
|
+
return compact;
|
|
137
|
+
}
|
|
138
|
+
function pickScalarFields(value, keys, limit = 6) {
|
|
139
|
+
if (!isRecord(value))
|
|
140
|
+
return {};
|
|
141
|
+
const entries = keys
|
|
142
|
+
? keys.filter((key) => key in value).map((key) => [key, value[key]])
|
|
143
|
+
: Object.entries(value);
|
|
144
|
+
const compact = {};
|
|
145
|
+
for (const [key, entryValue] of entries) {
|
|
146
|
+
if (typeof entryValue === 'string' ||
|
|
147
|
+
typeof entryValue === 'number' ||
|
|
148
|
+
typeof entryValue === 'boolean' ||
|
|
149
|
+
entryValue == null) {
|
|
150
|
+
compact[key] = entryValue ?? null;
|
|
151
|
+
}
|
|
152
|
+
if (Object.keys(compact).length >= limit)
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
return compact;
|
|
156
|
+
}
|
|
157
|
+
function compactOperationResult(result) {
|
|
158
|
+
if (result == null || typeof result === 'string' || typeof result === 'number' || typeof result === 'boolean') {
|
|
159
|
+
return result;
|
|
160
|
+
}
|
|
161
|
+
if (Array.isArray(result))
|
|
162
|
+
return { itemCount: result.length };
|
|
163
|
+
if (!isRecord(result))
|
|
164
|
+
return { kind: typeof result };
|
|
165
|
+
const compact = {
|
|
166
|
+
...pickScalarFields(result, ['success', 'status', 'count', 'total', 'applied', 'created', 'deleted']),
|
|
167
|
+
};
|
|
168
|
+
if (isRecord(result.revision)) {
|
|
169
|
+
const revision = pickScalarFields(result.revision, ['before', 'after', 'current']);
|
|
170
|
+
if (Object.keys(revision).length > 0)
|
|
171
|
+
compact.revision = revision;
|
|
172
|
+
}
|
|
173
|
+
if (Array.isArray(result.steps)) {
|
|
174
|
+
compact.stepCount = result.steps.length;
|
|
175
|
+
compact.steps = result.steps
|
|
176
|
+
.slice(0, 4)
|
|
177
|
+
.map((step) => (isRecord(step) ? pickScalarFields(step, ['stepId', 'op', 'effect', 'matchCount'], 4) : {}));
|
|
178
|
+
}
|
|
179
|
+
if (Array.isArray(result.items))
|
|
180
|
+
compact.itemCount = result.items.length;
|
|
181
|
+
if (Array.isArray(result.changes))
|
|
182
|
+
compact.changeCount = result.changes.length;
|
|
183
|
+
if (Array.isArray(result.matches))
|
|
184
|
+
compact.matchCount = result.matches.length;
|
|
185
|
+
if (Object.keys(compact).length === 0)
|
|
186
|
+
return { kind: 'object' };
|
|
187
|
+
return compact;
|
|
188
|
+
}
|
|
189
|
+
function compactAgentReceipt(receipt) {
|
|
190
|
+
// Compact the known heavy fields; pass every action-specific evidence field
|
|
191
|
+
// (editsApplied, marker, placement, revertHint, recovery, …) through
|
|
192
|
+
// verbatim — truth-telling receipts are only useful if the model sees them.
|
|
193
|
+
const { status, intent, preSnapshot, postSnapshot, selectedTargets, executedOperations, verification, saveReopen, errors, ...evidence } = receipt;
|
|
194
|
+
return {
|
|
195
|
+
status,
|
|
196
|
+
intent,
|
|
197
|
+
...(preSnapshot
|
|
198
|
+
? {
|
|
199
|
+
preSnapshot: {
|
|
200
|
+
revision: preSnapshot.revision,
|
|
201
|
+
...(preSnapshot.counts ? { counts: compactCountMap(preSnapshot.counts) } : {}),
|
|
202
|
+
},
|
|
203
|
+
}
|
|
204
|
+
: {}),
|
|
205
|
+
...(postSnapshot
|
|
206
|
+
? {
|
|
207
|
+
postSnapshot: {
|
|
208
|
+
revision: postSnapshot.revision,
|
|
209
|
+
...(postSnapshot.counts ? { counts: compactCountMap(postSnapshot.counts) } : {}),
|
|
210
|
+
},
|
|
211
|
+
}
|
|
212
|
+
: {}),
|
|
213
|
+
...(selectedTargets
|
|
214
|
+
? {
|
|
215
|
+
// Cap per-item lists: batch actions (add_comments selectors[],
|
|
216
|
+
// whole-body formatting) can select hundreds of targets, and the
|
|
217
|
+
// receipt is re-sent in conversation history on EVERY later turn.
|
|
218
|
+
// The count carries the evidence; the head carries the shape.
|
|
219
|
+
selectedTargets: selectedTargets.slice(0, RECEIPT_LIST_CAP).map((target) => ({
|
|
220
|
+
selector: target.selector,
|
|
221
|
+
matchedCount: target.matched.length,
|
|
222
|
+
})),
|
|
223
|
+
...(selectedTargets.length > RECEIPT_LIST_CAP ? { selectedTargetCount: selectedTargets.length } : {}),
|
|
224
|
+
}
|
|
225
|
+
: {}),
|
|
226
|
+
...(executedOperations
|
|
227
|
+
? {
|
|
228
|
+
// Same cap: per-range/per-item actions (format_text on every
|
|
229
|
+
// occurrence, whole-body set_font_family) execute one op per item —
|
|
230
|
+
// an uncapped list dominates the token cost of the receipt.
|
|
231
|
+
executedOperations: executedOperations.slice(0, RECEIPT_LIST_CAP).map((operation) => ({
|
|
232
|
+
operationId: operation.operationId,
|
|
233
|
+
...(operation.rationale ? { rationale: operation.rationale } : {}),
|
|
234
|
+
...(operation.result !== undefined ? { result: compactOperationResult(operation.result) } : {}),
|
|
235
|
+
})),
|
|
236
|
+
...(executedOperations.length > RECEIPT_LIST_CAP
|
|
237
|
+
? { executedOperationCount: executedOperations.length }
|
|
238
|
+
: {}),
|
|
239
|
+
}
|
|
240
|
+
: {}),
|
|
241
|
+
...(verification
|
|
242
|
+
? {
|
|
243
|
+
verificationPassed: verification.every((entry) => entry.passed),
|
|
244
|
+
verification: verification.map((entry) => ({
|
|
245
|
+
check: pickScalarFields(entry.check, undefined, 6),
|
|
246
|
+
passed: entry.passed,
|
|
247
|
+
...(entry.detail ? { detail: entry.detail } : {}),
|
|
248
|
+
})),
|
|
249
|
+
}
|
|
250
|
+
: {}),
|
|
251
|
+
...(saveReopen ? { saveReopen } : {}),
|
|
252
|
+
...(errors ? { errors } : {}),
|
|
253
|
+
...evidence,
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
// ---------------------------------------------------------------------------
|
|
257
|
+
// superdoc_execute_code — in-host dispatch for the CLI/SDK-only `doc.executeCode` op
|
|
258
|
+
// ---------------------------------------------------------------------------
|
|
259
|
+
const EXECUTE_CODE_SPEC = {
|
|
260
|
+
operationId: 'doc.executeCode',
|
|
261
|
+
commandTokens: ['execute', 'code'],
|
|
262
|
+
params: [
|
|
263
|
+
{ name: 'sessionId', kind: 'flag', flag: 'session', type: 'string' },
|
|
264
|
+
{ name: 'code', kind: 'flag', flag: 'code', type: 'string' },
|
|
265
|
+
],
|
|
266
|
+
};
|
|
267
|
+
function asRawOperationCapable(documentHandle) {
|
|
268
|
+
const candidate = documentHandle;
|
|
269
|
+
if (typeof candidate.invokeRawOperation !== 'function') {
|
|
270
|
+
throw new SuperDocCliError('superdoc_execute_code requires a session-bound document handle from client.open(); the provided handle cannot dispatch CLI/SDK-only operations.', {
|
|
271
|
+
code: 'TOOL_DISPATCH_NOT_FOUND',
|
|
272
|
+
details: { toolName: 'superdoc_execute_code' },
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
return candidate;
|
|
276
|
+
}
|
|
277
|
+
async function dispatchExecuteCode(documentHandle, args, invokeOptions) {
|
|
278
|
+
const code = typeof args.code === 'string' ? args.code : '';
|
|
279
|
+
// The generated bound client exposes doc.executeCode directly — use it.
|
|
280
|
+
// The invokeRawOperation path predates that binding and no handle produced
|
|
281
|
+
// by client.open() implements it; it remains only for callers that inject
|
|
282
|
+
// their own raw-capable handle.
|
|
283
|
+
const direct = documentHandle.executeCode;
|
|
284
|
+
if (typeof direct === 'function') {
|
|
285
|
+
return direct.call(documentHandle, { code }, invokeOptions);
|
|
286
|
+
}
|
|
287
|
+
const runner = asRawOperationCapable(documentHandle);
|
|
288
|
+
return runner.invokeRawOperation(EXECUTE_CODE_SPEC, { code }, invokeOptions);
|
|
289
|
+
}
|
|
290
|
+
// ---------------------------------------------------------------------------
|
|
291
|
+
// Dispatcher
|
|
292
|
+
// ---------------------------------------------------------------------------
|
|
293
|
+
async function dispatchAgentTool(documentHandle, toolName, args, invokeOptions) {
|
|
294
|
+
switch (toolName) {
|
|
295
|
+
case 'superdoc_inspect':
|
|
296
|
+
return agentInspect(documentHandle, args);
|
|
297
|
+
case 'agent_apply':
|
|
298
|
+
return compactAgentReceipt(await agentApply(documentHandle, args));
|
|
299
|
+
case 'agent_verify':
|
|
300
|
+
return compactAgentReceipt(await agentVerify(documentHandle, args));
|
|
301
|
+
case 'agent_operation':
|
|
302
|
+
return agentOperation(documentHandle, args);
|
|
303
|
+
case 'superdoc_perform_action':
|
|
304
|
+
return compactAgentReceipt(await superdocPerformAction(documentHandle, args));
|
|
305
|
+
case 'superdoc_execute_code':
|
|
306
|
+
return dispatchExecuteCode(documentHandle, args, invokeOptions);
|
|
307
|
+
}
|
|
308
|
+
throw new SuperDocCliError(`Unknown agent tool: ${toolName}`, {
|
|
309
|
+
code: 'TOOL_DISPATCH_NOT_FOUND',
|
|
310
|
+
details: { toolName },
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
// ---------------------------------------------------------------------------
|
|
314
|
+
// Provider cache markers — mirrors the legacy preset
|
|
315
|
+
// ---------------------------------------------------------------------------
|
|
316
|
+
function applyCacheMarkers(tools, provider, cacheRequested) {
|
|
317
|
+
if (!cacheRequested)
|
|
318
|
+
return { tools, cacheStrategy: 'disabled' };
|
|
319
|
+
if (provider === 'anthropic') {
|
|
320
|
+
if (tools.length === 0)
|
|
321
|
+
return { tools, cacheStrategy: 'explicit' };
|
|
322
|
+
const next = tools.slice(0, -1);
|
|
323
|
+
const last = {
|
|
324
|
+
...tools[tools.length - 1],
|
|
325
|
+
cache_control: { type: 'ephemeral' },
|
|
326
|
+
};
|
|
327
|
+
next.push(last);
|
|
328
|
+
return { tools: next, cacheStrategy: 'explicit' };
|
|
329
|
+
}
|
|
330
|
+
if (provider === 'openai')
|
|
331
|
+
return { tools, cacheStrategy: 'automatic' };
|
|
332
|
+
return { tools, cacheStrategy: 'unsupported' };
|
|
333
|
+
}
|
|
334
|
+
// ---------------------------------------------------------------------------
|
|
335
|
+
// PresetDescriptor surface
|
|
336
|
+
// ---------------------------------------------------------------------------
|
|
337
|
+
async function coreGetTools(provider, options) {
|
|
338
|
+
const tools = listAgentTools(provider, { excludeActions: options?.excludeActions });
|
|
339
|
+
return applyCacheMarkers(tools, provider, options?.cache === true);
|
|
340
|
+
}
|
|
341
|
+
async function coreGetCatalog() {
|
|
342
|
+
// Synthetic catalog — describes the advertised LLM-facing tools.
|
|
343
|
+
const publicSet = new Set(PUBLIC_AGENT_TOOL_NAMES);
|
|
344
|
+
const tools = AGENT_TOOL_DEFINITIONS.filter((d) => publicSet.has(d.name)).map((d) => ({
|
|
345
|
+
toolName: d.name,
|
|
346
|
+
description: d.description,
|
|
347
|
+
inputSchema: d.inputSchema,
|
|
348
|
+
mutates: d.name !== 'superdoc_inspect',
|
|
349
|
+
operations: [],
|
|
350
|
+
}));
|
|
351
|
+
return {
|
|
352
|
+
contractVersion: 'core/v2',
|
|
353
|
+
generatedAt: null,
|
|
354
|
+
toolCount: tools.length,
|
|
355
|
+
tools,
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* Drop the per-action documentation lines for excluded actions. Entries render
|
|
360
|
+
* as single "- name: ..." lines (the drift-guard test enforces the format), so
|
|
361
|
+
* line-level filtering is deterministic. Prose cross-references elsewhere in
|
|
362
|
+
* the prompt are left alone — a mention costs a few tokens; a full per-action
|
|
363
|
+
* manual for an uncallable action teaches the model to call it.
|
|
364
|
+
*/
|
|
365
|
+
function stripExcludedActionLines(prompt, excludedActions) {
|
|
366
|
+
if (excludedActions.size === 0)
|
|
367
|
+
return prompt;
|
|
368
|
+
return prompt
|
|
369
|
+
.split('\n')
|
|
370
|
+
.filter((line) => {
|
|
371
|
+
const match = /^- ([a-z_]+)(?: \/ ([a-z_]+))?:/.exec(line);
|
|
372
|
+
if (!match)
|
|
373
|
+
return true;
|
|
374
|
+
const names = [match[1], match[2]].filter((n) => Boolean(n));
|
|
375
|
+
// Drop the line only when EVERY action it documents is excluded (the
|
|
376
|
+
// paired accept/reject line survives if one side remains callable).
|
|
377
|
+
return !names.every((name) => excludedActions.has(name));
|
|
378
|
+
})
|
|
379
|
+
.join('\n');
|
|
380
|
+
}
|
|
381
|
+
async function coreGetSystemPrompt(options) {
|
|
382
|
+
const { excludedActions } = validateExclusions({ excludeActions: options?.excludeActions });
|
|
383
|
+
// The core preset is ACTIONS-ONLY: superdoc_execute_code is WIP and not
|
|
384
|
+
// advertised, and the prompt documents only the action surface (this exact
|
|
385
|
+
// prompt is what the eval suite validates). Code-execution guidance will be
|
|
386
|
+
// added when the safety-flag work ships that tool.
|
|
387
|
+
if (_actionsOnlyPromptCache == null) {
|
|
388
|
+
_actionsOnlyPromptCache = await readPromptFile('system-prompt.md', 'Core system prompt');
|
|
389
|
+
}
|
|
390
|
+
return stripExcludedActionLines(_actionsOnlyPromptCache, excludedActions);
|
|
391
|
+
}
|
|
392
|
+
async function coreGetMcpPrompt() {
|
|
393
|
+
if (_mcpPromptCache == null) {
|
|
394
|
+
_mcpPromptCache = await readPromptFile('mcp-prompt.md', 'MCP system prompt');
|
|
395
|
+
}
|
|
396
|
+
return _mcpPromptCache;
|
|
397
|
+
}
|
|
398
|
+
async function coreDispatch(documentHandle, toolName, args, invokeOptions) {
|
|
399
|
+
if (!isRecord(args)) {
|
|
400
|
+
throw new SuperDocCliError(`Tool arguments for ${toolName} must be an object.`, {
|
|
401
|
+
code: 'INVALID_ARGUMENT',
|
|
402
|
+
details: { toolName },
|
|
403
|
+
});
|
|
404
|
+
}
|
|
405
|
+
const sanitizedArgs = stripCorruptedToolArgKeys(args);
|
|
406
|
+
if (!isRecord(sanitizedArgs)) {
|
|
407
|
+
throw new SuperDocCliError(`Tool arguments for ${toolName} must be an object.`, {
|
|
408
|
+
code: 'INVALID_ARGUMENT',
|
|
409
|
+
details: { toolName },
|
|
410
|
+
});
|
|
411
|
+
}
|
|
412
|
+
// Defense-in-depth for exclusion configs: a host that narrowed the advertised
|
|
413
|
+
// surface (getTools excludeActions) can pass the same list here so a
|
|
414
|
+
// guessed/injected call to an excluded action is refused, not run.
|
|
415
|
+
const exclusionOptions = invokeOptions;
|
|
416
|
+
if (toolName === 'superdoc_perform_action' &&
|
|
417
|
+
typeof sanitizedArgs.action === 'string' &&
|
|
418
|
+
exclusionOptions?.excludeActions?.includes(sanitizedArgs.action)) {
|
|
419
|
+
throw new SuperDocCliError(`Action ${sanitizedArgs.action} is excluded by configuration.`, {
|
|
420
|
+
code: 'INVALID_ARGUMENT',
|
|
421
|
+
details: { toolName, action: sanitizedArgs.action, excluded: true },
|
|
422
|
+
});
|
|
423
|
+
}
|
|
424
|
+
let forwardOptions = invokeOptions;
|
|
425
|
+
if (exclusionOptions && 'excludeActions' in exclusionOptions) {
|
|
426
|
+
const { excludeActions: _ea, ...rest } = exclusionOptions;
|
|
427
|
+
forwardOptions = rest;
|
|
428
|
+
}
|
|
429
|
+
if (isAgentToolName(toolName)) {
|
|
430
|
+
validateAgentToolArgs(toolName, sanitizedArgs);
|
|
431
|
+
return dispatchAgentTool(documentHandle, toolName, sanitizedArgs, forwardOptions);
|
|
432
|
+
}
|
|
433
|
+
throw new SuperDocCliError(`Unknown tool: ${toolName}`, {
|
|
434
|
+
code: 'TOOL_DISPATCH_NOT_FOUND',
|
|
435
|
+
details: { toolName, preset: 'core' },
|
|
436
|
+
});
|
|
437
|
+
}
|
|
438
|
+
export const corePreset = {
|
|
439
|
+
id: 'core',
|
|
440
|
+
description: 'Actions-only LLM surface: superdoc_inspect (reads) and superdoc_perform_action (named, deterministic edit verbs). superdoc_execute_code exists but is WIP — dispatchable, not advertised.',
|
|
441
|
+
supportsCacheControl: true,
|
|
442
|
+
getTools: coreGetTools,
|
|
443
|
+
getCatalog: coreGetCatalog,
|
|
444
|
+
getSystemPrompt: coreGetSystemPrompt,
|
|
445
|
+
getMcpPrompt: coreGetMcpPrompt,
|
|
446
|
+
dispatch: coreDispatch,
|
|
447
|
+
};
|
package/dist/presets.cjs
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var errors = require('./runtime/errors.cjs');
|
|
4
4
|
var legacy = require('./presets/legacy.cjs');
|
|
5
|
+
var core = require('./presets/core.cjs');
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Preset registry for SuperDoc LLM tools.
|
|
@@ -13,10 +14,10 @@ var legacy = require('./presets/legacy.cjs');
|
|
|
13
14
|
*
|
|
14
15
|
* const { tools, meta } = await chooseTools({ provider: 'vercel', preset: 'legacy' });
|
|
15
16
|
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* The default may move once
|
|
19
|
-
* a coordinated change in this file alone.
|
|
17
|
+
* Two presets ship built-in: `'legacy'` (codegen-emitted intent tools; the
|
|
18
|
+
* default when callers omit `preset`) and `'core'` (the actions-only LLM
|
|
19
|
+
* surface). The default may move once core fully replaces legacy; bumping it
|
|
20
|
+
* is a coordinated change in this file alone.
|
|
20
21
|
*
|
|
21
22
|
* Presets are NOT versioned. The preset id encodes the variant; a new shape
|
|
22
23
|
* ships as a new id, not a new version of an existing one.
|
|
@@ -27,18 +28,62 @@ var legacy = require('./presets/legacy.cjs');
|
|
|
27
28
|
// Registry
|
|
28
29
|
// ---------------------------------------------------------------------------
|
|
29
30
|
/**
|
|
30
|
-
* The default preset returned when callers omit `preset`.
|
|
31
|
-
*
|
|
32
|
-
* working without changes.
|
|
31
|
+
* The default preset returned when callers omit `preset`. Stays as `'legacy'`
|
|
32
|
+
* for backward compatibility — consumers built before presets existed (today's
|
|
33
|
+
* intent-tool path) keep working without changes. To exercise the `core`
|
|
34
|
+
* preset, callers pass `preset: 'core'` explicitly.
|
|
33
35
|
*/
|
|
34
36
|
const DEFAULT_PRESET = 'legacy';
|
|
35
|
-
const
|
|
37
|
+
const BUILTIN_PRESETS = {
|
|
36
38
|
legacy: legacy.legacyPreset,
|
|
39
|
+
core: core.corePreset,
|
|
37
40
|
};
|
|
41
|
+
/**
|
|
42
|
+
* Mutable registry, seeded with the built-ins. Customers add their own presets
|
|
43
|
+
* via {@link registerPreset} (e.g. one produced by `extendPreset` /
|
|
44
|
+
* `composePreset`) so `getPreset`/`chooseTools` can resolve them by id.
|
|
45
|
+
*/
|
|
46
|
+
const PRESETS = { ...BUILTIN_PRESETS };
|
|
38
47
|
/** List the IDs of all registered presets. */
|
|
39
48
|
function listPresets() {
|
|
40
49
|
return Object.keys(PRESETS);
|
|
41
50
|
}
|
|
51
|
+
/**
|
|
52
|
+
* Register one or more presets so they resolve by id through `getPreset` and
|
|
53
|
+
* the `chooseTools`/`dispatchSuperDocTool` plumbing. Re-registering a custom id
|
|
54
|
+
* replaces the previously registered preset for that id (tests / hot-reload
|
|
55
|
+
* rely on this). Built-in ids (legacy / core) cannot
|
|
56
|
+
* be overwritten.
|
|
57
|
+
*/
|
|
58
|
+
function registerPreset(...presets) {
|
|
59
|
+
for (const preset of presets) {
|
|
60
|
+
if (preset == null || typeof preset.id !== 'string' || preset.id.length === 0) {
|
|
61
|
+
throw new errors.SuperDocCliError('registerPreset requires a preset with a non-empty string id.', {
|
|
62
|
+
code: 'INVALID_ARGUMENT',
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
if (preset.id in BUILTIN_PRESETS) {
|
|
66
|
+
throw new errors.SuperDocCliError(`Cannot overwrite built-in preset "${preset.id}".`, {
|
|
67
|
+
code: 'INVALID_ARGUMENT',
|
|
68
|
+
details: { id: preset.id },
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
PRESETS[preset.id] = preset;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Unregister a customer-registered preset. Idempotent (no-op if absent).
|
|
76
|
+
* Rejects unregistering a built-in preset id.
|
|
77
|
+
*/
|
|
78
|
+
function unregisterPreset(id) {
|
|
79
|
+
if (id in BUILTIN_PRESETS) {
|
|
80
|
+
throw new errors.SuperDocCliError(`Cannot unregister built-in preset "${id}".`, {
|
|
81
|
+
code: 'INVALID_ARGUMENT',
|
|
82
|
+
details: { id },
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
delete PRESETS[id];
|
|
86
|
+
}
|
|
42
87
|
/**
|
|
43
88
|
* Resolve a preset by ID. Throws {@link SuperDocCliError} with code
|
|
44
89
|
* `PRESET_NOT_FOUND` if the ID is not registered. Omit the argument to
|
|
@@ -58,3 +103,5 @@ function getPreset(id = DEFAULT_PRESET) {
|
|
|
58
103
|
exports.DEFAULT_PRESET = DEFAULT_PRESET;
|
|
59
104
|
exports.getPreset = getPreset;
|
|
60
105
|
exports.listPresets = listPresets;
|
|
106
|
+
exports.registerPreset = registerPreset;
|
|
107
|
+
exports.unregisterPreset = unregisterPreset;
|
package/dist/presets.d.ts
CHANGED
|
@@ -8,10 +8,10 @@
|
|
|
8
8
|
*
|
|
9
9
|
* const { tools, meta } = await chooseTools({ provider: 'vercel', preset: 'legacy' });
|
|
10
10
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* The default may move once
|
|
14
|
-
* a coordinated change in this file alone.
|
|
11
|
+
* Two presets ship built-in: `'legacy'` (codegen-emitted intent tools; the
|
|
12
|
+
* default when callers omit `preset`) and `'core'` (the actions-only LLM
|
|
13
|
+
* surface). The default may move once core fully replaces legacy; bumping it
|
|
14
|
+
* is a coordinated change in this file alone.
|
|
15
15
|
*
|
|
16
16
|
* Presets are NOT versioned. The preset id encodes the variant; a new shape
|
|
17
17
|
* ships as a new id, not a new version of an existing one.
|
|
@@ -80,6 +80,23 @@ export interface GetToolsOptions {
|
|
|
80
80
|
* for example). When omitted or `false`, no markers are added.
|
|
81
81
|
*/
|
|
82
82
|
cache?: boolean;
|
|
83
|
+
/**
|
|
84
|
+
* Action names to REMOVE from the advertised action surface (the `core`
|
|
85
|
+
* preset's `superdoc_perform_action` enum/description/args shrink together).
|
|
86
|
+
* Unknown names throw. Presets without an action surface (e.g. `legacy`)
|
|
87
|
+
* ignore this option.
|
|
88
|
+
*/
|
|
89
|
+
excludeActions?: readonly string[];
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Options for {@link PresetDescriptor.getSystemPrompt}. Mirrors the exclusion
|
|
93
|
+
* options on getTools so the prompt and the advertised tool surface can be
|
|
94
|
+
* narrowed TOGETHER — a prompt that documents an uncallable action teaches the
|
|
95
|
+
* model to call it.
|
|
96
|
+
*/
|
|
97
|
+
export interface GetSystemPromptOptions {
|
|
98
|
+
/** Drop the per-action documentation lines for these actions (core preset). */
|
|
99
|
+
excludeActions?: readonly string[];
|
|
83
100
|
}
|
|
84
101
|
export interface GetToolsResult {
|
|
85
102
|
tools: unknown[];
|
|
@@ -113,7 +130,7 @@ export interface PresetDescriptor {
|
|
|
113
130
|
/** Full tool catalog with metadata (contract version, tool count, etc.). */
|
|
114
131
|
getCatalog(): Promise<ToolCatalog>;
|
|
115
132
|
/** System prompt for embedded LLM usage (OpenAI/Anthropic/Vercel APIs). */
|
|
116
|
-
getSystemPrompt(): Promise<string>;
|
|
133
|
+
getSystemPrompt(options?: GetSystemPromptOptions): Promise<string>;
|
|
117
134
|
/** System prompt for MCP server `instructions`. */
|
|
118
135
|
getMcpPrompt(): Promise<string>;
|
|
119
136
|
/**
|
|
@@ -125,13 +142,27 @@ export interface PresetDescriptor {
|
|
|
125
142
|
dispatch(documentHandle: BoundDocApi, toolName: string, args: Record<string, unknown>, invokeOptions?: InvokeOptions): Promise<unknown>;
|
|
126
143
|
}
|
|
127
144
|
/**
|
|
128
|
-
* The default preset returned when callers omit `preset`.
|
|
129
|
-
*
|
|
130
|
-
* working without changes.
|
|
145
|
+
* The default preset returned when callers omit `preset`. Stays as `'legacy'`
|
|
146
|
+
* for backward compatibility — consumers built before presets existed (today's
|
|
147
|
+
* intent-tool path) keep working without changes. To exercise the `core`
|
|
148
|
+
* preset, callers pass `preset: 'core'` explicitly.
|
|
131
149
|
*/
|
|
132
150
|
export declare const DEFAULT_PRESET = "legacy";
|
|
133
151
|
/** List the IDs of all registered presets. */
|
|
134
152
|
export declare function listPresets(): readonly string[];
|
|
153
|
+
/**
|
|
154
|
+
* Register one or more presets so they resolve by id through `getPreset` and
|
|
155
|
+
* the `chooseTools`/`dispatchSuperDocTool` plumbing. Re-registering a custom id
|
|
156
|
+
* replaces the previously registered preset for that id (tests / hot-reload
|
|
157
|
+
* rely on this). Built-in ids (legacy / core) cannot
|
|
158
|
+
* be overwritten.
|
|
159
|
+
*/
|
|
160
|
+
export declare function registerPreset(...presets: PresetDescriptor[]): void;
|
|
161
|
+
/**
|
|
162
|
+
* Unregister a customer-registered preset. Idempotent (no-op if absent).
|
|
163
|
+
* Rejects unregistering a built-in preset id.
|
|
164
|
+
*/
|
|
165
|
+
export declare function unregisterPreset(id: string): void;
|
|
135
166
|
/**
|
|
136
167
|
* Resolve a preset by ID. Throws {@link SuperDocCliError} with code
|
|
137
168
|
* `PRESET_NOT_FOUND` if the ID is not registered. Omit the argument to
|
package/dist/presets.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"presets.d.ts","sourceRoot":"","sources":["../src/presets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"presets.d.ts","sourceRoot":"","sources":["../src/presets.ts"],"names":[],"mappings":"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"}
|