@superdoc-dev/sdk 1.0.0-next.72 → 1.0.0-next.74
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/README.md +50 -35
- package/dist/generated/client.cjs +734 -6
- package/dist/generated/client.d.ts +20380 -2887
- package/dist/generated/client.d.ts.map +1 -1
- package/dist/generated/client.js +733 -6
- package/dist/generated/contract.cjs +115396 -33890
- package/dist/generated/contract.d.ts +30 -46113
- package/dist/generated/contract.d.ts.map +1 -1
- package/dist/generated/contract.js +115396 -33890
- package/dist/generated/intent-dispatch.generated.cjs +94 -0
- package/dist/generated/intent-dispatch.generated.d.ts +2 -0
- package/dist/generated/intent-dispatch.generated.d.ts.map +1 -0
- package/dist/generated/intent-dispatch.generated.js +90 -0
- package/dist/helpers/format.d.ts +6 -8
- package/dist/helpers/format.d.ts.map +1 -1
- package/dist/helpers/format.js +5 -8
- package/dist/index.cjs +133 -10
- package/dist/index.d.ts +76 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +132 -9
- package/dist/runtime/process.d.ts +2 -2
- package/dist/runtime/process.d.ts.map +1 -1
- package/dist/runtime/transport-common.cjs +10 -0
- package/dist/runtime/transport-common.d.ts +7 -0
- package/dist/runtime/transport-common.d.ts.map +1 -1
- package/dist/runtime/transport-common.js +10 -0
- package/dist/tools.cjs +148 -286
- package/dist/tools.d.ts +37 -93
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +147 -284
- package/package.json +7 -6
- package/tools/__pycache__/__init__.cpython-312.pyc +0 -0
- package/tools/__pycache__/intent_dispatch_generated.cpython-312.pyc +0 -0
- package/tools/catalog.json +4288 -66383
- package/tools/intent_dispatch_generated.py +122 -0
- package/tools/system-prompt.md +113 -0
- package/tools/tools-policy.json +37 -94
- package/tools/tools.anthropic.json +4290 -27847
- package/tools/tools.generic.json +4357 -64146
- package/tools/tools.openai.json +4309 -28991
- package/tools/tools.vercel.json +4309 -28991
- package/tools/tool-name-map.json +0 -386
package/dist/tools.cjs
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var promises = require('node:fs/promises');
|
|
4
|
-
var node_fs = require('node:fs');
|
|
5
4
|
var path = require('node:path');
|
|
6
5
|
var node_url = require('node:url');
|
|
7
|
-
var contract = require('./generated/contract.cjs');
|
|
8
6
|
var errors = require('./runtime/errors.cjs');
|
|
7
|
+
var intentDispatch_generated = require('./generated/intent-dispatch.generated.cjs');
|
|
9
8
|
|
|
10
9
|
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
11
10
|
// Resolve tools directory relative to package root (works from both src/ and dist/)
|
|
@@ -16,37 +15,9 @@ const providerFileByName = {
|
|
|
16
15
|
vercel: 'tools.vercel.json',
|
|
17
16
|
generic: 'tools.generic.json',
|
|
18
17
|
};
|
|
19
|
-
let _policyCache = null;
|
|
20
|
-
function loadPolicy() {
|
|
21
|
-
if (_policyCache)
|
|
22
|
-
return _policyCache;
|
|
23
|
-
const raw = node_fs.readFileSync(path.join(toolsDir, 'tools-policy.json'), 'utf8');
|
|
24
|
-
_policyCache = JSON.parse(raw);
|
|
25
|
-
return _policyCache;
|
|
26
|
-
}
|
|
27
18
|
function isRecord(value) {
|
|
28
19
|
return typeof value === 'object' && value != null && !Array.isArray(value);
|
|
29
20
|
}
|
|
30
|
-
function isPresent(value) {
|
|
31
|
-
if (value == null)
|
|
32
|
-
return false;
|
|
33
|
-
if (Array.isArray(value))
|
|
34
|
-
return value.length > 0;
|
|
35
|
-
return true;
|
|
36
|
-
}
|
|
37
|
-
function extractProviderToolName(tool) {
|
|
38
|
-
// Anthropic / Generic: top-level name
|
|
39
|
-
if (typeof tool.name === 'string')
|
|
40
|
-
return tool.name;
|
|
41
|
-
// OpenAI / Vercel: nested under function.name
|
|
42
|
-
if (isRecord(tool.function) && typeof tool.function.name === 'string') {
|
|
43
|
-
return tool.function.name;
|
|
44
|
-
}
|
|
45
|
-
return null;
|
|
46
|
-
}
|
|
47
|
-
function invalidArgument(message, details) {
|
|
48
|
-
throw new errors.SuperDocCliError(message, { code: 'INVALID_ARGUMENT', details });
|
|
49
|
-
}
|
|
50
21
|
async function readJson(fileName) {
|
|
51
22
|
const filePath = path.join(toolsDir, fileName);
|
|
52
23
|
let raw = '';
|
|
@@ -78,105 +49,47 @@ async function readJson(fileName) {
|
|
|
78
49
|
async function loadProviderBundle(provider) {
|
|
79
50
|
return readJson(providerFileByName[provider]);
|
|
80
51
|
}
|
|
81
|
-
async function loadToolNameMap() {
|
|
82
|
-
return readJson('tool-name-map.json');
|
|
83
|
-
}
|
|
84
52
|
async function loadCatalog() {
|
|
85
53
|
return readJson('catalog.json');
|
|
86
54
|
}
|
|
87
|
-
function
|
|
88
|
-
return
|
|
89
|
-
hasTables: Boolean(features?.hasTables),
|
|
90
|
-
hasLists: Boolean(features?.hasLists),
|
|
91
|
-
hasComments: Boolean(features?.hasComments),
|
|
92
|
-
hasTrackedChanges: Boolean(features?.hasTrackedChanges),
|
|
93
|
-
isEmptyDocument: Boolean(features?.isEmptyDocument),
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
function stableSortByPhasePriority(entries, priorityOrder) {
|
|
97
|
-
const priority = new Map(priorityOrder.map((category, index) => [category, index]));
|
|
98
|
-
return [...entries].sort((a, b) => {
|
|
99
|
-
const aPriority = priority.get(a.category) ?? Number.MAX_SAFE_INTEGER;
|
|
100
|
-
const bPriority = priority.get(b.category) ?? Number.MAX_SAFE_INTEGER;
|
|
101
|
-
if (aPriority !== bPriority)
|
|
102
|
-
return aPriority - bPriority;
|
|
103
|
-
return a.toolName.localeCompare(b.toolName);
|
|
104
|
-
});
|
|
55
|
+
async function getToolCatalog() {
|
|
56
|
+
return loadCatalog();
|
|
105
57
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
const
|
|
109
|
-
if (!
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
for (const key of Object.keys(args)) {
|
|
115
|
-
if (!allowedParams.has(key)) {
|
|
116
|
-
invalidArgument(`Unexpected parameter ${key} for ${operationId}.`);
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
// Required-param enforcement
|
|
120
|
-
for (const param of operation.params) {
|
|
121
|
-
if ('required' in param && Boolean(param.required) && args[param.name] == null) {
|
|
122
|
-
invalidArgument(`Missing required parameter ${param.name} for ${operationId}.`);
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
// Constraint validation (CLI handles schema-level type validation authoritatively)
|
|
126
|
-
const constraints = 'constraints' in operation ? operation.constraints : undefined;
|
|
127
|
-
if (!constraints || !isRecord(constraints))
|
|
128
|
-
return;
|
|
129
|
-
const mutuallyExclusive = Array.isArray(constraints.mutuallyExclusive) ? constraints.mutuallyExclusive : [];
|
|
130
|
-
const requiresOneOf = Array.isArray(constraints.requiresOneOf) ? constraints.requiresOneOf : [];
|
|
131
|
-
const requiredWhen = Array.isArray(constraints.requiredWhen) ? constraints.requiredWhen : [];
|
|
132
|
-
for (const group of mutuallyExclusive) {
|
|
133
|
-
if (!Array.isArray(group))
|
|
134
|
-
continue;
|
|
135
|
-
const present = group.filter((name) => isPresent(args[name]));
|
|
136
|
-
if (present.length > 1) {
|
|
137
|
-
invalidArgument(`Arguments are mutually exclusive for ${operationId}: ${group.join(', ')}`, {
|
|
138
|
-
operationId,
|
|
139
|
-
group,
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
for (const group of requiresOneOf) {
|
|
144
|
-
if (!Array.isArray(group))
|
|
145
|
-
continue;
|
|
146
|
-
const hasAny = group.some((name) => isPresent(args[name]));
|
|
147
|
-
if (!hasAny) {
|
|
148
|
-
invalidArgument(`One of the following arguments is required for ${operationId}: ${group.join(', ')}`, {
|
|
149
|
-
operationId,
|
|
150
|
-
group,
|
|
151
|
-
});
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
for (const rule of requiredWhen) {
|
|
155
|
-
if (!isRecord(rule))
|
|
156
|
-
continue;
|
|
157
|
-
const whenValue = args[rule.whenParam];
|
|
158
|
-
let shouldRequire = false;
|
|
159
|
-
if (Object.prototype.hasOwnProperty.call(rule, 'equals')) {
|
|
160
|
-
shouldRequire = whenValue === rule.equals;
|
|
161
|
-
}
|
|
162
|
-
else if (Object.prototype.hasOwnProperty.call(rule, 'present')) {
|
|
163
|
-
const present = rule.present === true;
|
|
164
|
-
shouldRequire = present ? isPresent(whenValue) : !isPresent(whenValue);
|
|
165
|
-
}
|
|
166
|
-
else {
|
|
167
|
-
shouldRequire = isPresent(whenValue);
|
|
168
|
-
}
|
|
169
|
-
if (shouldRequire && !isPresent(args[rule.param])) {
|
|
170
|
-
invalidArgument(`Argument ${rule.param} is required by constraints for ${operationId}.`, {
|
|
171
|
-
operationId,
|
|
172
|
-
rule,
|
|
173
|
-
});
|
|
174
|
-
}
|
|
58
|
+
async function listTools(provider) {
|
|
59
|
+
const bundle = await loadProviderBundle(provider);
|
|
60
|
+
const tools = bundle.tools;
|
|
61
|
+
if (!Array.isArray(tools)) {
|
|
62
|
+
throw new errors.SuperDocCliError('Tool provider bundle is missing tools array.', {
|
|
63
|
+
code: 'TOOLS_ASSET_INVALID',
|
|
64
|
+
details: { provider },
|
|
65
|
+
});
|
|
175
66
|
}
|
|
67
|
+
return tools;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Select all intent tools for a specific provider.
|
|
71
|
+
*
|
|
72
|
+
* Returns all intent tools in the requested provider format.
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* ```ts
|
|
76
|
+
* const { tools } = await chooseTools({ provider: 'openai' });
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
79
|
+
async function chooseTools(input) {
|
|
80
|
+
const bundle = await loadProviderBundle(input.provider);
|
|
81
|
+
const tools = Array.isArray(bundle.tools) ? bundle.tools : [];
|
|
82
|
+
return {
|
|
83
|
+
tools,
|
|
84
|
+
meta: {
|
|
85
|
+
provider: input.provider,
|
|
86
|
+
toolCount: tools.length,
|
|
87
|
+
},
|
|
88
|
+
};
|
|
176
89
|
}
|
|
177
|
-
function resolveDocApiMethod(
|
|
90
|
+
function resolveDocApiMethod(documentHandle, operationId) {
|
|
178
91
|
const tokens = operationId.split('.').slice(1);
|
|
179
|
-
let cursor =
|
|
92
|
+
let cursor = documentHandle;
|
|
180
93
|
for (const token of tokens) {
|
|
181
94
|
if (!isRecord(cursor) || !(token in cursor)) {
|
|
182
95
|
throw new errors.SuperDocCliError(`No SDK doc method found for operation ${operationId}.`, {
|
|
@@ -194,185 +107,134 @@ function resolveDocApiMethod(client, operationId) {
|
|
|
194
107
|
}
|
|
195
108
|
return cursor;
|
|
196
109
|
}
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
110
|
+
// Cached catalog instance — loaded once per process.
|
|
111
|
+
let _catalogCache = null;
|
|
112
|
+
async function getCachedCatalog() {
|
|
113
|
+
if (_catalogCache == null) {
|
|
114
|
+
_catalogCache = await loadCatalog();
|
|
115
|
+
}
|
|
116
|
+
return _catalogCache;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Validate tool arguments against the catalog schema.
|
|
120
|
+
*
|
|
121
|
+
* Checks three things in order:
|
|
122
|
+
* 1. No unknown keys (additionalProperties: false in merged schema)
|
|
123
|
+
* 2. All universally-required keys present (merged schema `required`)
|
|
124
|
+
* 3. All action-specific required keys present (per-operation `required`)
|
|
125
|
+
*/
|
|
126
|
+
function validateToolArgs(toolName, args, tool) {
|
|
127
|
+
const schema = tool.inputSchema;
|
|
128
|
+
const properties = isRecord(schema.properties) ? schema.properties : {};
|
|
129
|
+
const required = Array.isArray(schema.required) ? schema.required : [];
|
|
130
|
+
// 1. Reject unknown keys
|
|
131
|
+
const knownKeys = new Set(Object.keys(properties));
|
|
132
|
+
const unknownKeys = Object.keys(args).filter((k) => !knownKeys.has(k));
|
|
133
|
+
if (unknownKeys.length > 0) {
|
|
134
|
+
throw new errors.SuperDocCliError(`Unknown argument(s) for ${toolName}: ${unknownKeys.join(', ')}`, {
|
|
135
|
+
code: 'INVALID_ARGUMENT',
|
|
136
|
+
details: { toolName, unknownKeys, knownKeys: [...knownKeys] },
|
|
217
137
|
});
|
|
218
138
|
}
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
if (!isRecord(infoResult)) {
|
|
227
|
-
return {
|
|
228
|
-
hasTables: false,
|
|
229
|
-
hasLists: false,
|
|
230
|
-
hasComments: false,
|
|
231
|
-
hasTrackedChanges: false,
|
|
232
|
-
isEmptyDocument: false,
|
|
233
|
-
};
|
|
139
|
+
// 2. Reject missing universally-required keys
|
|
140
|
+
const missingKeys = required.filter((k) => args[k] == null);
|
|
141
|
+
if (missingKeys.length > 0) {
|
|
142
|
+
throw new errors.SuperDocCliError(`Missing required argument(s) for ${toolName}: ${missingKeys.join(', ')}`, {
|
|
143
|
+
code: 'INVALID_ARGUMENT',
|
|
144
|
+
details: { toolName, missingKeys },
|
|
145
|
+
});
|
|
234
146
|
}
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
const
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
const
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
const indexByToolName = new Map(profileTools.map((tool) => [tool.toolName, tool]));
|
|
269
|
-
let candidates = profileTools.filter((tool) => {
|
|
270
|
-
if (tool.requiredCapabilities.some((capability) => !featureMap[capability])) {
|
|
271
|
-
excluded.push({ toolName: tool.toolName, reason: 'missing-required-capability' });
|
|
272
|
-
return false;
|
|
273
|
-
}
|
|
274
|
-
if (!allowMutatingTools && tool.mutates) {
|
|
275
|
-
excluded.push({ toolName: tool.toolName, reason: 'mutations-disabled' });
|
|
276
|
-
return false;
|
|
277
|
-
}
|
|
278
|
-
if (includeCategories.size > 0 && !includeCategories.has(tool.category)) {
|
|
279
|
-
excluded.push({ toolName: tool.toolName, reason: 'category-not-included' });
|
|
280
|
-
return false;
|
|
281
|
-
}
|
|
282
|
-
if (excludeCategories.has(tool.category)) {
|
|
283
|
-
excluded.push({ toolName: tool.toolName, reason: 'phase-category-excluded' });
|
|
284
|
-
return false;
|
|
285
|
-
}
|
|
286
|
-
return true;
|
|
287
|
-
});
|
|
288
|
-
const forceExclude = new Set(input.policy?.forceExclude ?? []);
|
|
289
|
-
candidates = candidates.filter((tool) => {
|
|
290
|
-
if (!forceExclude.has(tool.toolName))
|
|
291
|
-
return true;
|
|
292
|
-
excluded.push({ toolName: tool.toolName, reason: 'force-excluded' });
|
|
293
|
-
return false;
|
|
294
|
-
});
|
|
295
|
-
// Resolve forceInclude tools — these are guaranteed slots exempt from budget trimming.
|
|
296
|
-
const forcedToolNames = new Set(input.policy?.forceInclude ?? []);
|
|
297
|
-
const forcedTools = [];
|
|
298
|
-
for (const forcedToolName of forcedToolNames) {
|
|
299
|
-
const forced = indexByToolName.get(forcedToolName);
|
|
300
|
-
if (!forced) {
|
|
301
|
-
excluded.push({ toolName: forcedToolName, reason: 'not-in-profile' });
|
|
302
|
-
continue;
|
|
147
|
+
// 3. Reject missing per-operation required keys.
|
|
148
|
+
// For multi-action tools, resolve the operation by action; for single-op
|
|
149
|
+
// tools, use the sole operation entry.
|
|
150
|
+
const action = args.action;
|
|
151
|
+
let op;
|
|
152
|
+
if (typeof action === 'string' && tool.operations.length > 1) {
|
|
153
|
+
op = tool.operations.find((o) => o.intentAction === action);
|
|
154
|
+
}
|
|
155
|
+
else if (tool.operations.length === 1) {
|
|
156
|
+
op = tool.operations[0];
|
|
157
|
+
}
|
|
158
|
+
if (op) {
|
|
159
|
+
validateOperationRequired(toolName, action, args, op);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Check per-operation required constraints.
|
|
164
|
+
*
|
|
165
|
+
* Handles two shapes emitted by the codegen:
|
|
166
|
+
* - `required: string[]` — all listed keys must be present
|
|
167
|
+
* - `requiredOneOf: string[][]` — at least one branch must be fully satisfied
|
|
168
|
+
* (mirrors JSON Schema `oneOf` with per-branch `required` arrays)
|
|
169
|
+
*/
|
|
170
|
+
function validateOperationRequired(toolName, action, args, op) {
|
|
171
|
+
const actionLabel = typeof action === 'string' ? ` action "${action}"` : '';
|
|
172
|
+
if (op.requiredOneOf && op.requiredOneOf.length > 0) {
|
|
173
|
+
const satisfied = op.requiredOneOf.some((branch) => branch.every((k) => args[k] != null));
|
|
174
|
+
if (!satisfied) {
|
|
175
|
+
const options = op.requiredOneOf.map((b) => b.join(' + ')).join(' | ');
|
|
176
|
+
throw new errors.SuperDocCliError(`Missing required argument(s) for ${toolName}${actionLabel}: must provide one of: ${options}`, {
|
|
177
|
+
code: 'INVALID_ARGUMENT',
|
|
178
|
+
details: { toolName, action, requiredOneOf: op.requiredOneOf },
|
|
179
|
+
});
|
|
303
180
|
}
|
|
304
|
-
candidates.push(forced);
|
|
305
|
-
forcedTools.push(forced);
|
|
306
181
|
}
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
if (selected.length >= minReadTools || selected.length >= maxTools)
|
|
315
|
-
break;
|
|
316
|
-
selected.push(tool);
|
|
317
|
-
selectedNames.add(tool.toolName);
|
|
318
|
-
}
|
|
319
|
-
const remaining = stableSortByPhasePriority(candidates.filter((tool) => !selectedNames.has(tool.toolName)), phasePolicy.priority);
|
|
320
|
-
for (const tool of remaining) {
|
|
321
|
-
if (selected.length >= maxTools) {
|
|
322
|
-
excluded.push({ toolName: tool.toolName, reason: 'budget-trim' });
|
|
323
|
-
continue;
|
|
182
|
+
else if (op.required && op.required.length > 0) {
|
|
183
|
+
const missingActionKeys = op.required.filter((k) => args[k] == null);
|
|
184
|
+
if (missingActionKeys.length > 0) {
|
|
185
|
+
throw new errors.SuperDocCliError(`Missing required argument(s) for ${toolName}${actionLabel}: ${missingActionKeys.join(', ')}`, {
|
|
186
|
+
code: 'INVALID_ARGUMENT',
|
|
187
|
+
details: { toolName, action, missingKeys: missingActionKeys },
|
|
188
|
+
});
|
|
324
189
|
}
|
|
325
|
-
selected.push(tool);
|
|
326
190
|
}
|
|
327
|
-
const bundle = await loadProviderBundle(input.provider);
|
|
328
|
-
const providerTools = Array.isArray(bundle.profiles[profile]) ? bundle.profiles[profile] : [];
|
|
329
|
-
const providerIndex = new Map(providerTools
|
|
330
|
-
.filter((tool) => isRecord(tool))
|
|
331
|
-
.map((tool) => [extractProviderToolName(tool), tool])
|
|
332
|
-
.filter((entry) => entry[0] !== null));
|
|
333
|
-
const selectedProviderTools = selected
|
|
334
|
-
.map((tool) => providerIndex.get(tool.toolName))
|
|
335
|
-
.filter((tool) => Boolean(tool));
|
|
336
|
-
return {
|
|
337
|
-
tools: selectedProviderTools,
|
|
338
|
-
selected: selected.map((tool) => ({
|
|
339
|
-
operationId: tool.operationId,
|
|
340
|
-
toolName: tool.toolName,
|
|
341
|
-
category: tool.category,
|
|
342
|
-
mutates: tool.mutates,
|
|
343
|
-
profile: tool.profile,
|
|
344
|
-
})),
|
|
345
|
-
excluded,
|
|
346
|
-
selectionMeta: {
|
|
347
|
-
profile,
|
|
348
|
-
phase,
|
|
349
|
-
maxTools,
|
|
350
|
-
minReadTools,
|
|
351
|
-
selectedCount: selected.length,
|
|
352
|
-
decisionVersion: policy.defaults.chooserDecisionVersion,
|
|
353
|
-
provider: input.provider,
|
|
354
|
-
},
|
|
355
|
-
};
|
|
356
191
|
}
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
192
|
+
/**
|
|
193
|
+
* Dispatch a tool call against a bound document handle.
|
|
194
|
+
*
|
|
195
|
+
* The document handle injects session targeting automatically.
|
|
196
|
+
* Tool arguments should not contain `doc` or `sessionId`.
|
|
197
|
+
*/
|
|
198
|
+
async function dispatchSuperDocTool(documentHandle, toolName, args = {}, invokeOptions) {
|
|
199
|
+
if (!isRecord(args)) {
|
|
200
|
+
throw new errors.SuperDocCliError(`Tool arguments for ${toolName} must be an object.`, {
|
|
201
|
+
code: 'INVALID_ARGUMENT',
|
|
362
202
|
details: { toolName },
|
|
363
203
|
});
|
|
364
204
|
}
|
|
365
|
-
|
|
366
|
-
|
|
205
|
+
// Validate against the tool schema before dispatch.
|
|
206
|
+
const catalog = await getCachedCatalog();
|
|
207
|
+
const tool = catalog.tools.find((t) => t.toolName === toolName);
|
|
208
|
+
if (tool == null) {
|
|
209
|
+
throw new errors.SuperDocCliError(`Unknown tool: ${toolName}`, {
|
|
210
|
+
code: 'TOOL_DISPATCH_NOT_FOUND',
|
|
211
|
+
details: { toolName },
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
validateToolArgs(toolName, args, tool);
|
|
215
|
+
return intentDispatch_generated.dispatchIntentTool(toolName, args, (operationId, input) => {
|
|
216
|
+
const method = resolveDocApiMethod(documentHandle, operationId);
|
|
217
|
+
return method(input, invokeOptions);
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Read the bundled system prompt for intent tools.
|
|
222
|
+
*/
|
|
223
|
+
async function getSystemPrompt() {
|
|
224
|
+
const promptPath = path.join(toolsDir, 'system-prompt.md');
|
|
225
|
+
try {
|
|
226
|
+
return await promises.readFile(promptPath, 'utf8');
|
|
227
|
+
}
|
|
228
|
+
catch {
|
|
229
|
+
throw new errors.SuperDocCliError('System prompt not found.', {
|
|
230
|
+
code: 'TOOLS_ASSET_NOT_FOUND',
|
|
231
|
+
details: { filePath: promptPath },
|
|
232
|
+
});
|
|
367
233
|
}
|
|
368
|
-
validateDispatchArgs(operationId, args);
|
|
369
|
-
const method = resolveDocApiMethod(client, operationId);
|
|
370
|
-
return method(args, invokeOptions);
|
|
371
234
|
}
|
|
372
235
|
|
|
373
236
|
exports.chooseTools = chooseTools;
|
|
374
237
|
exports.dispatchSuperDocTool = dispatchSuperDocTool;
|
|
238
|
+
exports.getSystemPrompt = getSystemPrompt;
|
|
375
239
|
exports.getToolCatalog = getToolCatalog;
|
|
376
|
-
exports.inferDocumentFeatures = inferDocumentFeatures;
|
|
377
240
|
exports.listTools = listTools;
|
|
378
|
-
exports.resolveToolOperation = resolveToolOperation;
|
package/dist/tools.d.ts
CHANGED
|
@@ -1,113 +1,57 @@
|
|
|
1
|
+
import type { BoundDocApi } from './generated/client.js';
|
|
1
2
|
import type { InvokeOptions } from './runtime/process.js';
|
|
2
3
|
export type ToolProvider = 'openai' | 'anthropic' | 'vercel' | 'generic';
|
|
3
|
-
export type ToolProfile = 'intent' | 'operation';
|
|
4
|
-
export type ToolPhase = 'read' | 'locate' | 'mutate' | 'review';
|
|
5
|
-
export type DocumentFeatures = {
|
|
6
|
-
hasTables: boolean;
|
|
7
|
-
hasLists: boolean;
|
|
8
|
-
hasComments: boolean;
|
|
9
|
-
hasTrackedChanges: boolean;
|
|
10
|
-
isEmptyDocument: boolean;
|
|
11
|
-
};
|
|
12
|
-
export type ToolChooserInput = {
|
|
13
|
-
provider: ToolProvider;
|
|
14
|
-
profile?: ToolProfile;
|
|
15
|
-
documentFeatures?: Partial<DocumentFeatures>;
|
|
16
|
-
taskContext?: {
|
|
17
|
-
phase?: ToolPhase;
|
|
18
|
-
previousToolCalls?: Array<{
|
|
19
|
-
toolName: string;
|
|
20
|
-
ok: boolean;
|
|
21
|
-
}>;
|
|
22
|
-
};
|
|
23
|
-
budget?: {
|
|
24
|
-
maxTools?: number;
|
|
25
|
-
minReadTools?: number;
|
|
26
|
-
};
|
|
27
|
-
policy?: {
|
|
28
|
-
includeCategories?: string[];
|
|
29
|
-
excludeCategories?: string[];
|
|
30
|
-
allowMutatingTools?: boolean;
|
|
31
|
-
forceInclude?: string[];
|
|
32
|
-
forceExclude?: string[];
|
|
33
|
-
};
|
|
34
|
-
};
|
|
35
4
|
export type ToolCatalog = {
|
|
36
5
|
contractVersion: string;
|
|
37
6
|
generatedAt: string | null;
|
|
38
|
-
namePolicyVersion: string;
|
|
39
|
-
exposureVersion: string;
|
|
40
7
|
toolCount: number;
|
|
41
|
-
|
|
42
|
-
intent: {
|
|
43
|
-
name: 'intent';
|
|
44
|
-
tools: ToolCatalogEntry[];
|
|
45
|
-
};
|
|
46
|
-
operation: {
|
|
47
|
-
name: 'operation';
|
|
48
|
-
tools: ToolCatalogEntry[];
|
|
49
|
-
};
|
|
50
|
-
};
|
|
8
|
+
tools: ToolCatalogEntry[];
|
|
51
9
|
};
|
|
52
|
-
type
|
|
10
|
+
type OperationEntry = {
|
|
53
11
|
operationId: string;
|
|
12
|
+
intentAction: string;
|
|
13
|
+
required?: string[];
|
|
14
|
+
requiredOneOf?: string[][];
|
|
15
|
+
};
|
|
16
|
+
type ToolCatalogEntry = {
|
|
54
17
|
toolName: string;
|
|
55
|
-
profile: ToolProfile;
|
|
56
|
-
source: 'operation' | 'intent';
|
|
57
18
|
description: string;
|
|
58
19
|
inputSchema: Record<string, unknown>;
|
|
59
|
-
outputSchema: Record<string, unknown>;
|
|
60
20
|
mutates: boolean;
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
args: Record<string, unknown>;
|
|
68
|
-
}>;
|
|
69
|
-
commandTokens: string[];
|
|
70
|
-
profileTags: string[];
|
|
71
|
-
requiredCapabilities: Array<keyof DocumentFeatures>;
|
|
72
|
-
sessionRequirements: {
|
|
73
|
-
requiresOpenContext: boolean;
|
|
74
|
-
supportsSessionTargeting: boolean;
|
|
75
|
-
};
|
|
76
|
-
intentId?: string;
|
|
21
|
+
operations: OperationEntry[];
|
|
22
|
+
};
|
|
23
|
+
export declare function getToolCatalog(): Promise<ToolCatalog>;
|
|
24
|
+
export declare function listTools(provider: ToolProvider): Promise<unknown[]>;
|
|
25
|
+
export type ToolChooserInput = {
|
|
26
|
+
provider: ToolProvider;
|
|
77
27
|
};
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
28
|
+
/**
|
|
29
|
+
* Select all intent tools for a specific provider.
|
|
30
|
+
*
|
|
31
|
+
* Returns all intent tools in the requested provider format.
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```ts
|
|
35
|
+
* const { tools } = await chooseTools({ provider: 'openai' });
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
86
38
|
export declare function chooseTools(input: ToolChooserInput): Promise<{
|
|
87
39
|
tools: unknown[];
|
|
88
|
-
|
|
89
|
-
operationId: string;
|
|
90
|
-
toolName: string;
|
|
91
|
-
category: string;
|
|
92
|
-
mutates: boolean;
|
|
93
|
-
profile: ToolProfile;
|
|
94
|
-
}>;
|
|
95
|
-
excluded: Array<{
|
|
96
|
-
toolName: string;
|
|
97
|
-
reason: string;
|
|
98
|
-
}>;
|
|
99
|
-
selectionMeta: {
|
|
100
|
-
profile: ToolProfile;
|
|
101
|
-
phase: ToolPhase;
|
|
102
|
-
maxTools: number;
|
|
103
|
-
minReadTools: number;
|
|
104
|
-
selectedCount: number;
|
|
105
|
-
decisionVersion: string;
|
|
40
|
+
meta: {
|
|
106
41
|
provider: ToolProvider;
|
|
42
|
+
toolCount: number;
|
|
107
43
|
};
|
|
108
44
|
}>;
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
45
|
+
/**
|
|
46
|
+
* Dispatch a tool call against a bound document handle.
|
|
47
|
+
*
|
|
48
|
+
* The document handle injects session targeting automatically.
|
|
49
|
+
* Tool arguments should not contain `doc` or `sessionId`.
|
|
50
|
+
*/
|
|
51
|
+
export declare function dispatchSuperDocTool(documentHandle: BoundDocApi, toolName: string, args?: Record<string, unknown>, invokeOptions?: InvokeOptions): Promise<unknown>;
|
|
52
|
+
/**
|
|
53
|
+
* Read the bundled system prompt for intent tools.
|
|
54
|
+
*/
|
|
55
|
+
export declare function getSystemPrompt(): Promise<string>;
|
|
112
56
|
export {};
|
|
113
57
|
//# sourceMappingURL=tools.d.ts.map
|
package/dist/tools.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAI1D,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,WAAW,GAAG,QAAQ,GAAG,SAAS,CAAC;AAWzE,MAAM,MAAM,WAAW,GAAG;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,gBAAgB,EAAE,CAAC;CAC3B,CAAC;AAEF,KAAK,cAAc,GAAG;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC;CAC5B,CAAC;AAEF,KAAK,gBAAgB,GAAG;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,cAAc,EAAE,CAAC;CAC9B,CAAC;AA6CF,wBAAsB,cAAc,IAAI,OAAO,CAAC,WAAW,CAAC,CAE3D;AAED,wBAAsB,SAAS,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAU1E;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,EAAE,YAAY,CAAC;CACxB,CAAC;AAEF;;;;;;;;;GASG;AACH,wBAAsB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC;IAClE,KAAK,EAAE,OAAO,EAAE,CAAC;IACjB,IAAI,EAAE;QACJ,QAAQ,EAAE,YAAY,CAAC;QACvB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH,CAAC,CAWD;AAiID;;;;;GAKG;AACH,wBAAsB,oBAAoB,CACxC,cAAc,EAAE,WAAW,EAC3B,QAAQ,EAAE,MAAM,EAChB,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EAClC,aAAa,CAAC,EAAE,aAAa,GAC5B,OAAO,CAAC,OAAO,CAAC,CAuBlB;AAED;;GAEG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,MAAM,CAAC,CAUvD"}
|