@superdoc-dev/sdk 1.0.0-alpha.4 → 1.0.0-alpha.41
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 +124 -0
- package/dist/generated/client.cjs +479 -0
- package/dist/generated/client.d.ts +11940 -1167
- package/dist/generated/client.d.ts.map +1 -1
- package/dist/generated/client.js +433 -25
- package/dist/generated/contract.cjs +123158 -0
- package/dist/generated/contract.d.ts +30 -13672
- package/dist/generated/contract.d.ts.map +1 -1
- package/dist/generated/contract.js +116698 -11334
- package/dist/helpers/format.d.ts +79 -0
- package/dist/helpers/format.d.ts.map +1 -0
- package/dist/helpers/format.js +121 -0
- package/dist/index.cjs +45 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/runtime/embedded-cli.cjs +100 -0
- package/dist/runtime/errors.cjs +22 -0
- package/dist/runtime/host.cjs +352 -0
- package/dist/runtime/host.d.ts +2 -1
- package/dist/runtime/host.d.ts.map +1 -1
- package/dist/runtime/host.js +3 -1
- package/dist/runtime/process.cjs +32 -0
- package/dist/runtime/process.d.ts +1 -1
- package/dist/runtime/process.d.ts.map +1 -1
- package/dist/runtime/transport-common.cjs +79 -0
- package/dist/runtime/transport-common.d.ts +6 -1
- package/dist/runtime/transport-common.d.ts.map +1 -1
- package/dist/runtime/transport-common.js +13 -4
- package/dist/skills.cjs +148 -0
- package/dist/tools.cjs +312 -0
- package/dist/tools.d.ts +42 -65
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +75 -134
- package/package.json +15 -14
- package/skills/editing-docx.md +31 -0
- package/tools/catalog.json +59826 -15216
- package/tools/tool-name-map.json +300 -71
- package/tools/tools-policy.json +79 -82
- package/tools/tools.anthropic.json +25742 -2983
- package/tools/tools.generic.json +58182 -15148
- package/tools/tools.openai.json +26715 -3266
- package/tools/tools.vercel.json +26715 -3266
package/dist/skills.cjs
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var node_fs = require('node:fs');
|
|
4
|
+
var os = require('node:os');
|
|
5
|
+
var path = require('node:path');
|
|
6
|
+
var node_url = require('node:url');
|
|
7
|
+
var errors = require('./runtime/errors.cjs');
|
|
8
|
+
|
|
9
|
+
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
10
|
+
// Resolve skills directory relative to package root (works from both src/ and dist/)
|
|
11
|
+
const skillsDir = path.resolve(path.dirname(node_url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('skills.cjs', document.baseURI).href)))), '..', 'skills');
|
|
12
|
+
const SKILL_NAME_RE = /^[A-Za-z0-9][A-Za-z0-9_-]*$/;
|
|
13
|
+
const SUPPORTED_SKILL_RUNTIMES = ['claude'];
|
|
14
|
+
const SUPPORTED_INSTALL_SCOPES = ['project', 'user'];
|
|
15
|
+
function resolveSkillFilePath(skillName) {
|
|
16
|
+
const filePath = path.resolve(skillsDir, `${skillName}.md`);
|
|
17
|
+
const root = `${skillsDir}${path.sep}`;
|
|
18
|
+
if (!filePath.startsWith(root)) {
|
|
19
|
+
throw new errors.SuperDocCliError('Skill name resolved outside SDK skill directory.', {
|
|
20
|
+
code: 'INVALID_ARGUMENT',
|
|
21
|
+
details: { skillName },
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
return filePath;
|
|
25
|
+
}
|
|
26
|
+
function normalizeSkillName(name) {
|
|
27
|
+
const normalized = name.trim();
|
|
28
|
+
if (!normalized || !SKILL_NAME_RE.test(normalized)) {
|
|
29
|
+
throw new errors.SuperDocCliError('Skill name is required.', {
|
|
30
|
+
code: 'INVALID_ARGUMENT',
|
|
31
|
+
details: { name },
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
return normalized;
|
|
35
|
+
}
|
|
36
|
+
function listSkills() {
|
|
37
|
+
try {
|
|
38
|
+
return node_fs.readdirSync(skillsDir)
|
|
39
|
+
.filter((entry) => path.extname(entry) === '.md')
|
|
40
|
+
.map((entry) => path.basename(entry, '.md'))
|
|
41
|
+
.sort();
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
throw new errors.SuperDocCliError('Unable to enumerate SDK skills.', {
|
|
45
|
+
code: 'SKILL_IO_ERROR',
|
|
46
|
+
details: {
|
|
47
|
+
skillsDir,
|
|
48
|
+
message: error instanceof Error ? error.message : String(error),
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function getSkill(name) {
|
|
54
|
+
const normalized = normalizeSkillName(name);
|
|
55
|
+
const filePath = resolveSkillFilePath(normalized);
|
|
56
|
+
try {
|
|
57
|
+
return node_fs.readFileSync(filePath, 'utf8');
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
const nodeError = error;
|
|
61
|
+
if (nodeError?.code === 'ENOENT') {
|
|
62
|
+
let available = [];
|
|
63
|
+
try {
|
|
64
|
+
available = listSkills();
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
// Keep available empty
|
|
68
|
+
}
|
|
69
|
+
throw new errors.SuperDocCliError('Requested SDK skill was not found.', {
|
|
70
|
+
code: 'SKILL_NOT_FOUND',
|
|
71
|
+
details: { name: normalized, available },
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
throw new errors.SuperDocCliError('Unable to read SDK skill file.', {
|
|
75
|
+
code: 'SKILL_IO_ERROR',
|
|
76
|
+
details: {
|
|
77
|
+
name: normalized,
|
|
78
|
+
message: error instanceof Error ? error.message : String(error),
|
|
79
|
+
},
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
function installSkill(name, options = {}) {
|
|
84
|
+
const normalizedName = normalizeSkillName(name);
|
|
85
|
+
const runtime = options.runtime ?? 'claude';
|
|
86
|
+
if (!SUPPORTED_SKILL_RUNTIMES.includes(runtime)) {
|
|
87
|
+
throw new errors.SuperDocCliError('Unsupported skill runtime.', {
|
|
88
|
+
code: 'INVALID_ARGUMENT',
|
|
89
|
+
details: { runtime, supportedRuntimes: [...SUPPORTED_SKILL_RUNTIMES] },
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
const scope = options.scope ?? 'project';
|
|
93
|
+
if (!SUPPORTED_INSTALL_SCOPES.includes(scope)) {
|
|
94
|
+
throw new errors.SuperDocCliError('Unsupported skill install scope.', {
|
|
95
|
+
code: 'INVALID_ARGUMENT',
|
|
96
|
+
details: { scope, supportedScopes: [...SUPPORTED_INSTALL_SCOPES] },
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
const skillsRoot = options.targetDir !== undefined
|
|
100
|
+
? path.resolve(options.targetDir)
|
|
101
|
+
: scope === 'user'
|
|
102
|
+
? path.resolve(options.homeDir ?? os.homedir(), '.claude', 'skills')
|
|
103
|
+
: path.resolve(options.cwd ?? process.cwd(), '.claude', 'skills');
|
|
104
|
+
const skillFile = path.join(skillsRoot, normalizedName, 'SKILL.md');
|
|
105
|
+
const overwrite = options.overwrite ?? true;
|
|
106
|
+
const alreadyExists = node_fs.existsSync(skillFile);
|
|
107
|
+
if (!overwrite && alreadyExists) {
|
|
108
|
+
return {
|
|
109
|
+
name: normalizedName,
|
|
110
|
+
runtime,
|
|
111
|
+
scope: options.targetDir !== undefined ? 'custom' : scope,
|
|
112
|
+
path: skillFile,
|
|
113
|
+
written: false,
|
|
114
|
+
overwritten: false,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
try {
|
|
118
|
+
const content = getSkill(name);
|
|
119
|
+
node_fs.mkdirSync(path.dirname(skillFile), { recursive: true });
|
|
120
|
+
node_fs.writeFileSync(skillFile, content, 'utf8');
|
|
121
|
+
}
|
|
122
|
+
catch (error) {
|
|
123
|
+
if (error instanceof errors.SuperDocCliError)
|
|
124
|
+
throw error;
|
|
125
|
+
throw new errors.SuperDocCliError('Unable to install SDK skill.', {
|
|
126
|
+
code: 'SKILL_IO_ERROR',
|
|
127
|
+
details: {
|
|
128
|
+
name: normalizedName,
|
|
129
|
+
runtime,
|
|
130
|
+
scope: options.targetDir !== undefined ? 'custom' : scope,
|
|
131
|
+
path: skillFile,
|
|
132
|
+
message: error instanceof Error ? error.message : String(error),
|
|
133
|
+
},
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
return {
|
|
137
|
+
name: normalizedName,
|
|
138
|
+
runtime,
|
|
139
|
+
scope: options.targetDir !== undefined ? 'custom' : scope,
|
|
140
|
+
path: skillFile,
|
|
141
|
+
written: true,
|
|
142
|
+
overwritten: alreadyExists,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
exports.getSkill = getSkill;
|
|
147
|
+
exports.installSkill = installSkill;
|
|
148
|
+
exports.listSkills = listSkills;
|
package/dist/tools.cjs
ADDED
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var promises = require('node:fs/promises');
|
|
4
|
+
var node_fs = require('node:fs');
|
|
5
|
+
var path = require('node:path');
|
|
6
|
+
var node_url = require('node:url');
|
|
7
|
+
var contract = require('./generated/contract.cjs');
|
|
8
|
+
var errors = require('./runtime/errors.cjs');
|
|
9
|
+
|
|
10
|
+
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
11
|
+
// Resolve tools directory relative to package root (works from both src/ and dist/)
|
|
12
|
+
const toolsDir = path.resolve(path.dirname(node_url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('tools.cjs', document.baseURI).href)))), '..', 'tools');
|
|
13
|
+
const providerFileByName = {
|
|
14
|
+
openai: 'tools.openai.json',
|
|
15
|
+
anthropic: 'tools.anthropic.json',
|
|
16
|
+
vercel: 'tools.vercel.json',
|
|
17
|
+
generic: 'tools.generic.json',
|
|
18
|
+
};
|
|
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
|
+
function isRecord(value) {
|
|
28
|
+
return typeof value === 'object' && value != null && !Array.isArray(value);
|
|
29
|
+
}
|
|
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
|
+
async function readJson(fileName) {
|
|
51
|
+
const filePath = path.join(toolsDir, fileName);
|
|
52
|
+
let raw = '';
|
|
53
|
+
try {
|
|
54
|
+
raw = await promises.readFile(filePath, 'utf8');
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
throw new errors.SuperDocCliError('Unable to load packaged tool artifact.', {
|
|
58
|
+
code: 'TOOLS_ASSET_NOT_FOUND',
|
|
59
|
+
details: {
|
|
60
|
+
filePath,
|
|
61
|
+
message: error instanceof Error ? error.message : String(error),
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
try {
|
|
66
|
+
return JSON.parse(raw);
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
throw new errors.SuperDocCliError('Packaged tool artifact is invalid JSON.', {
|
|
70
|
+
code: 'TOOLS_ASSET_INVALID',
|
|
71
|
+
details: {
|
|
72
|
+
filePath,
|
|
73
|
+
message: error instanceof Error ? error.message : String(error),
|
|
74
|
+
},
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
async function loadProviderBundle(provider) {
|
|
79
|
+
return readJson(providerFileByName[provider]);
|
|
80
|
+
}
|
|
81
|
+
async function loadToolNameMap() {
|
|
82
|
+
return readJson('tool-name-map.json');
|
|
83
|
+
}
|
|
84
|
+
async function loadCatalog() {
|
|
85
|
+
return readJson('catalog.json');
|
|
86
|
+
}
|
|
87
|
+
/** All available tool groups from the policy. */
|
|
88
|
+
function getAvailableGroups() {
|
|
89
|
+
const policy = loadPolicy();
|
|
90
|
+
return policy.groups;
|
|
91
|
+
}
|
|
92
|
+
const OPERATION_INDEX = Object.fromEntries(Object.entries(contract.CONTRACT.operations).map(([id, op]) => [id, op]));
|
|
93
|
+
function validateDispatchArgs(operationId, args) {
|
|
94
|
+
const operation = OPERATION_INDEX[operationId];
|
|
95
|
+
if (!operation) {
|
|
96
|
+
invalidArgument(`Unknown operation id ${operationId}.`);
|
|
97
|
+
}
|
|
98
|
+
// Unknown-param rejection
|
|
99
|
+
const allowedParams = new Set(operation.params.map((param) => String(param.name)));
|
|
100
|
+
for (const key of Object.keys(args)) {
|
|
101
|
+
if (!allowedParams.has(key)) {
|
|
102
|
+
invalidArgument(`Unexpected parameter ${key} for ${operationId}.`);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
// Required-param enforcement
|
|
106
|
+
for (const param of operation.params) {
|
|
107
|
+
if ('required' in param && Boolean(param.required) && args[param.name] == null) {
|
|
108
|
+
invalidArgument(`Missing required parameter ${param.name} for ${operationId}.`);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
// Constraint validation (CLI handles schema-level type validation authoritatively)
|
|
112
|
+
const constraints = 'constraints' in operation ? operation.constraints : undefined;
|
|
113
|
+
if (!constraints || !isRecord(constraints))
|
|
114
|
+
return;
|
|
115
|
+
const mutuallyExclusive = Array.isArray(constraints.mutuallyExclusive) ? constraints.mutuallyExclusive : [];
|
|
116
|
+
const requiresOneOf = Array.isArray(constraints.requiresOneOf) ? constraints.requiresOneOf : [];
|
|
117
|
+
const requiredWhen = Array.isArray(constraints.requiredWhen) ? constraints.requiredWhen : [];
|
|
118
|
+
for (const group of mutuallyExclusive) {
|
|
119
|
+
if (!Array.isArray(group))
|
|
120
|
+
continue;
|
|
121
|
+
const present = group.filter((name) => isPresent(args[name]));
|
|
122
|
+
if (present.length > 1) {
|
|
123
|
+
invalidArgument(`Arguments are mutually exclusive for ${operationId}: ${group.join(', ')}`, {
|
|
124
|
+
operationId,
|
|
125
|
+
group,
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
for (const group of requiresOneOf) {
|
|
130
|
+
if (!Array.isArray(group))
|
|
131
|
+
continue;
|
|
132
|
+
const hasAny = group.some((name) => isPresent(args[name]));
|
|
133
|
+
if (!hasAny) {
|
|
134
|
+
invalidArgument(`One of the following arguments is required for ${operationId}: ${group.join(', ')}`, {
|
|
135
|
+
operationId,
|
|
136
|
+
group,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
for (const rule of requiredWhen) {
|
|
141
|
+
if (!isRecord(rule))
|
|
142
|
+
continue;
|
|
143
|
+
const whenValue = args[rule.whenParam];
|
|
144
|
+
let shouldRequire = false;
|
|
145
|
+
if (Object.prototype.hasOwnProperty.call(rule, 'equals')) {
|
|
146
|
+
shouldRequire = whenValue === rule.equals;
|
|
147
|
+
}
|
|
148
|
+
else if (Object.prototype.hasOwnProperty.call(rule, 'present')) {
|
|
149
|
+
const present = rule.present === true;
|
|
150
|
+
shouldRequire = present ? isPresent(whenValue) : !isPresent(whenValue);
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
shouldRequire = isPresent(whenValue);
|
|
154
|
+
}
|
|
155
|
+
if (shouldRequire && !isPresent(args[rule.param])) {
|
|
156
|
+
invalidArgument(`Argument ${rule.param} is required by constraints for ${operationId}.`, {
|
|
157
|
+
operationId,
|
|
158
|
+
rule,
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
function resolveDocApiMethod(client, operationId) {
|
|
164
|
+
const tokens = operationId.split('.').slice(1);
|
|
165
|
+
let cursor = client.doc;
|
|
166
|
+
for (const token of tokens) {
|
|
167
|
+
if (!isRecord(cursor) || !(token in cursor)) {
|
|
168
|
+
throw new errors.SuperDocCliError(`No SDK doc method found for operation ${operationId}.`, {
|
|
169
|
+
code: 'TOOL_DISPATCH_NOT_FOUND',
|
|
170
|
+
details: { operationId, token },
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
cursor = cursor[token];
|
|
174
|
+
}
|
|
175
|
+
if (typeof cursor !== 'function') {
|
|
176
|
+
throw new errors.SuperDocCliError(`Resolved member for ${operationId} is not callable.`, {
|
|
177
|
+
code: 'TOOL_DISPATCH_NOT_FOUND',
|
|
178
|
+
details: { operationId },
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
return cursor;
|
|
182
|
+
}
|
|
183
|
+
async function getToolCatalog() {
|
|
184
|
+
return loadCatalog();
|
|
185
|
+
}
|
|
186
|
+
async function listTools(provider) {
|
|
187
|
+
const bundle = await loadProviderBundle(provider);
|
|
188
|
+
const tools = bundle.tools;
|
|
189
|
+
if (!Array.isArray(tools)) {
|
|
190
|
+
throw new errors.SuperDocCliError('Tool provider bundle is missing tools array.', {
|
|
191
|
+
code: 'TOOLS_ASSET_INVALID',
|
|
192
|
+
details: { provider },
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
return tools;
|
|
196
|
+
}
|
|
197
|
+
async function resolveToolOperation(toolName) {
|
|
198
|
+
const map = await loadToolNameMap();
|
|
199
|
+
return typeof map[toolName] === 'string' ? map[toolName] : null;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Select tools for a specific provider.
|
|
203
|
+
*
|
|
204
|
+
* **mode='essential'** (default): Returns only essential tools + discover_tools.
|
|
205
|
+
* Pass `groups` to additionally load all tools from those categories.
|
|
206
|
+
*
|
|
207
|
+
* **mode='all'**: Returns all tools from requested groups (or all groups if
|
|
208
|
+
* `groups` is omitted). No discover_tools included by default.
|
|
209
|
+
*
|
|
210
|
+
* @example
|
|
211
|
+
* ```ts
|
|
212
|
+
* // Default: 5 essential tools + discover_tools
|
|
213
|
+
* const { tools } = await chooseTools({ provider: 'openai' });
|
|
214
|
+
*
|
|
215
|
+
* // Essential + all comment tools
|
|
216
|
+
* const { tools } = await chooseTools({ provider: 'openai', groups: ['comments'] });
|
|
217
|
+
*
|
|
218
|
+
* // All tools (old behavior)
|
|
219
|
+
* const { tools } = await chooseTools({ provider: 'openai', mode: 'all' });
|
|
220
|
+
* ```
|
|
221
|
+
*/
|
|
222
|
+
async function chooseTools(input) {
|
|
223
|
+
const catalog = await loadCatalog();
|
|
224
|
+
const policy = loadPolicy();
|
|
225
|
+
const mode = input.mode ?? policy.defaults.mode ?? 'essential';
|
|
226
|
+
const includeDiscover = input.includeDiscoverTool ?? mode === 'essential';
|
|
227
|
+
let selected;
|
|
228
|
+
if (mode === 'essential') {
|
|
229
|
+
// Essential tools + any explicitly requested groups
|
|
230
|
+
const essentialNames = new Set(policy.essentialTools ?? []);
|
|
231
|
+
const requestedGroups = input.groups ? new Set(input.groups) : null;
|
|
232
|
+
selected = catalog.tools.filter((tool) => {
|
|
233
|
+
if (essentialNames.has(tool.toolName))
|
|
234
|
+
return true;
|
|
235
|
+
if (requestedGroups && requestedGroups.has(tool.category))
|
|
236
|
+
return true;
|
|
237
|
+
return false;
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
else {
|
|
241
|
+
// mode='all': original behavior — filter by groups
|
|
242
|
+
const alwaysInclude = new Set(policy.defaults.alwaysInclude ?? ['core']);
|
|
243
|
+
let groups;
|
|
244
|
+
if (input.groups) {
|
|
245
|
+
groups = new Set([...input.groups, ...alwaysInclude]);
|
|
246
|
+
}
|
|
247
|
+
else {
|
|
248
|
+
groups = new Set(policy.groups);
|
|
249
|
+
}
|
|
250
|
+
selected = catalog.tools.filter((tool) => groups.has(tool.category));
|
|
251
|
+
}
|
|
252
|
+
// Build provider-formatted tools from the provider bundle
|
|
253
|
+
const bundle = await loadProviderBundle(input.provider);
|
|
254
|
+
const providerTools = Array.isArray(bundle.tools) ? bundle.tools : [];
|
|
255
|
+
const providerIndex = new Map(providerTools
|
|
256
|
+
.filter((tool) => isRecord(tool))
|
|
257
|
+
.map((tool) => [extractProviderToolName(tool), tool])
|
|
258
|
+
.filter((entry) => entry[0] !== null));
|
|
259
|
+
const selectedProviderTools = selected
|
|
260
|
+
.map((tool) => providerIndex.get(tool.toolName))
|
|
261
|
+
.filter((tool) => Boolean(tool));
|
|
262
|
+
// Append discover_tools if requested
|
|
263
|
+
if (includeDiscover) {
|
|
264
|
+
const discoverTool = providerIndex.get('discover_tools');
|
|
265
|
+
if (discoverTool) {
|
|
266
|
+
selectedProviderTools.push(discoverTool);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
const resolvedGroups = mode === 'essential' ? (input.groups ?? []) : (input.groups ?? policy.groups);
|
|
270
|
+
return {
|
|
271
|
+
tools: selectedProviderTools,
|
|
272
|
+
selected: selected.map((tool) => ({
|
|
273
|
+
operationId: tool.operationId,
|
|
274
|
+
toolName: tool.toolName,
|
|
275
|
+
category: tool.category,
|
|
276
|
+
mutates: tool.mutates,
|
|
277
|
+
})),
|
|
278
|
+
meta: {
|
|
279
|
+
provider: input.provider,
|
|
280
|
+
mode,
|
|
281
|
+
groups: [...resolvedGroups],
|
|
282
|
+
selectedCount: selectedProviderTools.length,
|
|
283
|
+
},
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
async function dispatchSuperDocTool(client, toolName, args = {}, invokeOptions) {
|
|
287
|
+
const operationId = await resolveToolOperation(toolName);
|
|
288
|
+
if (!operationId) {
|
|
289
|
+
throw new errors.SuperDocCliError(`Unknown SuperDoc tool: ${toolName}`, {
|
|
290
|
+
code: 'TOOL_NOT_FOUND',
|
|
291
|
+
details: { toolName },
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
if (!isRecord(args)) {
|
|
295
|
+
invalidArgument(`Tool arguments for ${toolName} must be an object.`);
|
|
296
|
+
}
|
|
297
|
+
// Strip doc/sessionId — the SDK client manages session targeting after doc.open().
|
|
298
|
+
// Models fill these in because the tool schemas expose them, but passing them
|
|
299
|
+
// alongside an active session causes "stateless input.doc cannot be combined
|
|
300
|
+
// with a session target" errors.
|
|
301
|
+
const { doc: _doc, sessionId: _sid, ...cleanArgs } = args;
|
|
302
|
+
validateDispatchArgs(operationId, cleanArgs);
|
|
303
|
+
const method = resolveDocApiMethod(client, operationId);
|
|
304
|
+
return method(cleanArgs, invokeOptions);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
exports.chooseTools = chooseTools;
|
|
308
|
+
exports.dispatchSuperDocTool = dispatchSuperDocTool;
|
|
309
|
+
exports.getAvailableGroups = getAvailableGroups;
|
|
310
|
+
exports.getToolCatalog = getToolCatalog;
|
|
311
|
+
exports.listTools = listTools;
|
|
312
|
+
exports.resolveToolOperation = resolveToolOperation;
|
package/dist/tools.d.ts
CHANGED
|
@@ -1,36 +1,14 @@
|
|
|
1
1
|
import type { InvokeOptions } from './runtime/process.js';
|
|
2
2
|
export type ToolProvider = 'openai' | 'anthropic' | 'vercel' | 'generic';
|
|
3
|
-
export type
|
|
4
|
-
export type
|
|
5
|
-
export type DocumentFeatures = {
|
|
6
|
-
hasTables: boolean;
|
|
7
|
-
hasLists: boolean;
|
|
8
|
-
hasComments: boolean;
|
|
9
|
-
hasTrackedChanges: boolean;
|
|
10
|
-
isEmptyDocument: boolean;
|
|
11
|
-
};
|
|
3
|
+
export type ToolGroup = 'core' | 'format' | 'create' | 'tables' | 'sections' | 'lists' | 'comments' | 'trackChanges' | 'toc' | 'images' | 'history' | 'session';
|
|
4
|
+
export type ToolChooserMode = 'essential' | 'all';
|
|
12
5
|
export type ToolChooserInput = {
|
|
13
6
|
provider: ToolProvider;
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
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
|
-
};
|
|
7
|
+
groups?: ToolGroup[];
|
|
8
|
+
/** Default: 'essential'. When 'essential', only essential tools are returned (plus any from `groups`). */
|
|
9
|
+
mode?: ToolChooserMode;
|
|
10
|
+
/** Whether to include the discover_tools meta-tool. Default: true when mode='essential', false when mode='all'. */
|
|
11
|
+
includeDiscoverTool?: boolean;
|
|
34
12
|
};
|
|
35
13
|
export type ToolCatalog = {
|
|
36
14
|
contractVersion: string;
|
|
@@ -38,51 +16,58 @@ export type ToolCatalog = {
|
|
|
38
16
|
namePolicyVersion: string;
|
|
39
17
|
exposureVersion: string;
|
|
40
18
|
toolCount: number;
|
|
41
|
-
|
|
42
|
-
intent: {
|
|
43
|
-
name: 'intent';
|
|
44
|
-
tools: ToolCatalogEntry[];
|
|
45
|
-
};
|
|
46
|
-
operation: {
|
|
47
|
-
name: 'operation';
|
|
48
|
-
tools: ToolCatalogEntry[];
|
|
49
|
-
};
|
|
50
|
-
};
|
|
19
|
+
tools: ToolCatalogEntry[];
|
|
51
20
|
};
|
|
52
21
|
type ToolCatalogEntry = {
|
|
53
22
|
operationId: string;
|
|
54
23
|
toolName: string;
|
|
55
|
-
profile:
|
|
56
|
-
source:
|
|
24
|
+
profile: string;
|
|
25
|
+
source: string;
|
|
57
26
|
description: string;
|
|
58
27
|
inputSchema: Record<string, unknown>;
|
|
59
28
|
outputSchema: Record<string, unknown>;
|
|
60
29
|
mutates: boolean;
|
|
61
30
|
category: string;
|
|
31
|
+
essential?: boolean;
|
|
62
32
|
capabilities: string[];
|
|
63
33
|
constraints?: Record<string, unknown>;
|
|
64
34
|
errors: string[];
|
|
65
|
-
examples:
|
|
66
|
-
description: string;
|
|
67
|
-
args: Record<string, unknown>;
|
|
68
|
-
}>;
|
|
35
|
+
examples: unknown[];
|
|
69
36
|
commandTokens: string[];
|
|
70
37
|
profileTags: string[];
|
|
71
|
-
requiredCapabilities:
|
|
38
|
+
requiredCapabilities: string[];
|
|
72
39
|
sessionRequirements: {
|
|
73
40
|
requiresOpenContext: boolean;
|
|
74
41
|
supportsSessionTargeting: boolean;
|
|
75
42
|
};
|
|
76
43
|
intentId?: string;
|
|
77
44
|
};
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
export declare function listTools(provider: ToolProvider
|
|
82
|
-
profile?: ToolProfile;
|
|
83
|
-
}): Promise<unknown[]>;
|
|
45
|
+
/** All available tool groups from the policy. */
|
|
46
|
+
export declare function getAvailableGroups(): ToolGroup[];
|
|
47
|
+
export declare function getToolCatalog(): Promise<ToolCatalog>;
|
|
48
|
+
export declare function listTools(provider: ToolProvider): Promise<unknown[]>;
|
|
84
49
|
export declare function resolveToolOperation(toolName: string): Promise<string | null>;
|
|
85
|
-
|
|
50
|
+
/**
|
|
51
|
+
* Select tools for a specific provider.
|
|
52
|
+
*
|
|
53
|
+
* **mode='essential'** (default): Returns only essential tools + discover_tools.
|
|
54
|
+
* Pass `groups` to additionally load all tools from those categories.
|
|
55
|
+
*
|
|
56
|
+
* **mode='all'**: Returns all tools from requested groups (or all groups if
|
|
57
|
+
* `groups` is omitted). No discover_tools included by default.
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```ts
|
|
61
|
+
* // Default: 5 essential tools + discover_tools
|
|
62
|
+
* const { tools } = await chooseTools({ provider: 'openai' });
|
|
63
|
+
*
|
|
64
|
+
* // Essential + all comment tools
|
|
65
|
+
* const { tools } = await chooseTools({ provider: 'openai', groups: ['comments'] });
|
|
66
|
+
*
|
|
67
|
+
* // All tools (old behavior)
|
|
68
|
+
* const { tools } = await chooseTools({ provider: 'openai', mode: 'all' });
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
86
71
|
export declare function chooseTools(input: ToolChooserInput): Promise<{
|
|
87
72
|
tools: unknown[];
|
|
88
73
|
selected: Array<{
|
|
@@ -90,20 +75,12 @@ export declare function chooseTools(input: ToolChooserInput): Promise<{
|
|
|
90
75
|
toolName: string;
|
|
91
76
|
category: string;
|
|
92
77
|
mutates: boolean;
|
|
93
|
-
profile: ToolProfile;
|
|
94
|
-
}>;
|
|
95
|
-
excluded: Array<{
|
|
96
|
-
toolName: string;
|
|
97
|
-
reason: string;
|
|
98
78
|
}>;
|
|
99
|
-
|
|
100
|
-
profile: ToolProfile;
|
|
101
|
-
phase: ToolPhase;
|
|
102
|
-
maxTools: number;
|
|
103
|
-
minReadTools: number;
|
|
104
|
-
selectedCount: number;
|
|
105
|
-
decisionVersion: string;
|
|
79
|
+
meta: {
|
|
106
80
|
provider: ToolProvider;
|
|
81
|
+
mode: string;
|
|
82
|
+
groups: string[];
|
|
83
|
+
selectedCount: number;
|
|
107
84
|
};
|
|
108
85
|
}>;
|
|
109
86
|
export declare function dispatchSuperDocTool(client: {
|
package/dist/tools.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAG1D,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,WAAW,GAAG,QAAQ,GAAG,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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"}
|