@superdoc/sdk 2.23.0-next.8 → 2.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/dist/action-primitives/tools/structure-insert.cjs +3 -5
  2. package/dist/action-primitives/tools/structure-insert.js +3 -5
  3. package/dist/action-primitives/tools/text-transform.cjs +3 -5
  4. package/dist/action-primitives/tools/text-transform.js +3 -5
  5. package/dist/actions/define.cjs +15 -17
  6. package/dist/actions/define.js +1 -3
  7. package/dist/agent/actions.cjs +438 -52
  8. package/dist/agent/actions.d.ts +13 -0
  9. package/dist/agent/actions.js +394 -11
  10. package/dist/agent/runtime.cjs +7 -9
  11. package/dist/agent/runtime.js +1 -3
  12. package/dist/agent/v2-preset-compat.cjs +5 -7
  13. package/dist/agent/v2-preset-compat.js +1 -3
  14. package/dist/embedded-prompts.generated.cjs +1 -1
  15. package/dist/embedded-prompts.generated.js +1 -1
  16. package/dist/embedded-tools.generated.cjs +5 -5
  17. package/dist/embedded-tools.generated.js +5 -5
  18. package/dist/generated/client.d.ts +193 -177
  19. package/dist/generated/contract.cjs +1 -1
  20. package/dist/generated/contract.js +1 -1
  21. package/dist/guards.cjs +7 -0
  22. package/dist/guards.d.ts +1 -0
  23. package/dist/guards.js +3 -0
  24. package/dist/presets/core.cjs +10 -12
  25. package/dist/presets/core.js +1 -3
  26. package/dist/presets/legacy.cjs +6 -8
  27. package/dist/presets/legacy.js +1 -3
  28. package/dist/prompts/system-prompt.md +6 -6
  29. package/dist/runtime/sdk-version.generated.cjs +1 -1
  30. package/dist/runtime/sdk-version.generated.d.ts +1 -1
  31. package/dist/runtime/sdk-version.generated.js +1 -1
  32. package/package.json +6 -6
  33. package/tools/catalog.json +8 -0
  34. package/tools/generation-receipt.json +18 -18
  35. package/tools/tools-policy.json +1 -1
  36. package/tools/tools.anthropic.json +8 -0
  37. package/tools/tools.generic.json +8 -0
  38. package/tools/tools.openai.json +8 -0
  39. package/tools/tools.vercel.json +8 -0
@@ -3,6 +3,7 @@
3
3
  var docIndex = require('../doc-index.cjs');
4
4
  var engine = require('../engine.cjs');
5
5
  var resolve = require('../resolve.cjs');
6
+ var guards = require('../../guards.cjs');
6
7
 
7
8
  const STRUCTURE_INSERT_ACTIONS = [
8
9
  'insert_toc',
@@ -22,9 +23,6 @@ const DEFAULT_TOC_CONFIG = {
22
23
  rightAlignPageNumbers: true,
23
24
  tabLeader: 'dot',
24
25
  };
25
- function isObjectRecord(value) {
26
- return value != null && typeof value === 'object' && !Array.isArray(value);
27
- }
28
26
  function parseAction(raw) {
29
27
  if (typeof raw !== 'string') {
30
28
  return undefined;
@@ -166,7 +164,7 @@ function resolvePlacement(context, action) {
166
164
  source: 'provided',
167
165
  });
168
166
  }
169
- if (!isObjectRecord(rawPlacement)) {
167
+ if (!guards.isRecord(rawPlacement)) {
170
168
  return engine.workflowStepFailure({
171
169
  status: 'failed',
172
170
  phase: 'resolve',
@@ -960,7 +958,7 @@ async function executeStep(context, _resolved, plan) {
960
958
  sectionId: 'section-break-fallback',
961
959
  });
962
960
  }
963
- const sectionId = isObjectRecord(sectionResult.section) && typeof sectionResult.section.sectionId === 'string'
961
+ const sectionId = guards.isRecord(sectionResult.section) && typeof sectionResult.section.sectionId === 'string'
964
962
  ? sectionResult.section.sectionId
965
963
  : undefined;
966
964
  const afterInfo = await context.documentHandle.info({}, context.invokeOptions);
@@ -1,6 +1,7 @@
1
1
  import { buildWorkflowDocIndex } from '../doc-index.js';
2
2
  import { runWorkflowEngine, workflowStepFailure, workflowStepSuccess, } from '../engine.js';
3
3
  import { resolveWorkflowTargetFromUnknown, } from '../resolve.js';
4
+ import { isRecord } from '../../guards.js';
4
5
  const STRUCTURE_INSERT_ACTIONS = [
5
6
  'insert_toc',
6
7
  'insert_section_break',
@@ -19,9 +20,6 @@ const DEFAULT_TOC_CONFIG = {
19
20
  rightAlignPageNumbers: true,
20
21
  tabLeader: 'dot',
21
22
  };
22
- function isObjectRecord(value) {
23
- return value != null && typeof value === 'object' && !Array.isArray(value);
24
- }
25
23
  function parseAction(raw) {
26
24
  if (typeof raw !== 'string') {
27
25
  return undefined;
@@ -163,7 +161,7 @@ function resolvePlacement(context, action) {
163
161
  source: 'provided',
164
162
  });
165
163
  }
166
- if (!isObjectRecord(rawPlacement)) {
164
+ if (!isRecord(rawPlacement)) {
167
165
  return workflowStepFailure({
168
166
  status: 'failed',
169
167
  phase: 'resolve',
@@ -957,7 +955,7 @@ async function executeStep(context, _resolved, plan) {
957
955
  sectionId: 'section-break-fallback',
958
956
  });
959
957
  }
960
- const sectionId = isObjectRecord(sectionResult.section) && typeof sectionResult.section.sectionId === 'string'
958
+ const sectionId = isRecord(sectionResult.section) && typeof sectionResult.section.sectionId === 'string'
961
959
  ? sectionResult.section.sectionId
962
960
  : undefined;
963
961
  const afterInfo = await context.documentHandle.info({}, context.invokeOptions);
@@ -2,13 +2,11 @@
2
2
 
3
3
  var engine = require('../engine.cjs');
4
4
  var resolve = require('../resolve.cjs');
5
+ var guards = require('../../guards.cjs');
5
6
 
6
7
  const TEXT_TRANSFORM_ACTIONS = ['replace_all', 'delete_all', 'rewrite_block', 'fill_placeholders'];
7
8
  const CHANGE_MODES = ['direct', 'tracked'];
8
9
  const REWRITE_BLOCK_SUPPORTED_NODE_TYPES = ['paragraph', 'heading', 'listItem'];
9
- function isObjectRecord(value) {
10
- return value != null && typeof value === 'object' && !Array.isArray(value);
11
- }
12
10
  function coerceBoolean(raw, fallback) {
13
11
  if (typeof raw === 'boolean') {
14
12
  return raw;
@@ -155,7 +153,7 @@ function parseEdits(raw) {
155
153
  }
156
154
  const edits = [];
157
155
  for (const entry of raw) {
158
- if (!isObjectRecord(entry)) {
156
+ if (!guards.isRecord(entry)) {
159
157
  return undefined;
160
158
  }
161
159
  const find = entry.find;
@@ -184,7 +182,7 @@ function parsePlaceholderValues(raw) {
184
182
  values.push(entry);
185
183
  continue;
186
184
  }
187
- if (isObjectRecord(entry) && typeof entry.value === 'string' && entry.value.length > 0) {
185
+ if (guards.isRecord(entry) && typeof entry.value === 'string' && entry.value.length > 0) {
188
186
  values.push(entry.value);
189
187
  continue;
190
188
  }
@@ -1,11 +1,9 @@
1
1
  import { runWorkflowEngine, workflowStepFailure, workflowStepSuccess, } from '../engine.js';
2
2
  import { resolveWorkflowTargetFromUnknown, } from '../resolve.js';
3
+ import { isRecord } from '../../guards.js';
3
4
  const TEXT_TRANSFORM_ACTIONS = ['replace_all', 'delete_all', 'rewrite_block', 'fill_placeholders'];
4
5
  const CHANGE_MODES = ['direct', 'tracked'];
5
6
  const REWRITE_BLOCK_SUPPORTED_NODE_TYPES = ['paragraph', 'heading', 'listItem'];
6
- function isObjectRecord(value) {
7
- return value != null && typeof value === 'object' && !Array.isArray(value);
8
- }
9
7
  function coerceBoolean(raw, fallback) {
10
8
  if (typeof raw === 'boolean') {
11
9
  return raw;
@@ -152,7 +150,7 @@ function parseEdits(raw) {
152
150
  }
153
151
  const edits = [];
154
152
  for (const entry of raw) {
155
- if (!isObjectRecord(entry)) {
153
+ if (!isRecord(entry)) {
156
154
  return undefined;
157
155
  }
158
156
  const find = entry.find;
@@ -181,7 +179,7 @@ function parsePlaceholderValues(raw) {
181
179
  values.push(entry);
182
180
  continue;
183
181
  }
184
- if (isObjectRecord(entry) && typeof entry.value === 'string' && entry.value.length > 0) {
182
+ if (isRecord(entry) && typeof entry.value === 'string' && entry.value.length > 0) {
185
183
  values.push(entry.value);
186
184
  continue;
187
185
  }
@@ -4,6 +4,7 @@ var errors = require('../runtime/errors.cjs');
4
4
  var presets = require('../presets.cjs');
5
5
  var actions = require('../agent/actions.cjs');
6
6
  var catalog = require('../agent/catalog.cjs');
7
+ var guards = require('../guards.cjs');
7
8
 
8
9
  /**
9
10
  * Customer-extensible **custom actions** for the SuperDoc LLM-tools SDK. The
@@ -71,7 +72,7 @@ function coerceInputSchema(input) {
71
72
  // `{ type: 'object', additionalProperties: true }`). The declared type makes
72
73
  // `properties` required and every consumer (and the Python mirror) assumes
73
74
  // it exists, so normalize a missing/non-object bag to {}.
74
- return isRecord(input.properties) ? input : { ...input, properties: {} };
75
+ return guards.isRecord(input.properties) ? input : { ...input, properties: {} };
75
76
  }
76
77
  // A bare properties bag — wrap it.
77
78
  return { type: 'object', properties: input, additionalProperties: true };
@@ -121,7 +122,7 @@ function defineAction(input) {
121
122
  if (!BUILTIN_ACTION_NAMES.has(step.action)) {
122
123
  throw new errors.SuperDocCliError(`defineAction "${input.name}": steps[${index}].action "${step.action}" is not a built-in core action. Steps compose built-in actions only; use the \`run\` tier for anything else.`, { code: 'INVALID_ARGUMENT', details: { name: input.name, index, action: step.action } });
123
124
  }
124
- if (step.args != null && !isRecord(step.args)) {
125
+ if (step.args != null && !guards.isRecord(step.args)) {
125
126
  throw new errors.SuperDocCliError(`defineAction "${input.name}": steps[${index}].args must be an object.`, {
126
127
  code: 'INVALID_ARGUMENT',
127
128
  details: { name: input.name, index },
@@ -240,9 +241,6 @@ function assertActionsValid(actions, presetId, standalone = false) {
240
241
  // ---------------------------------------------------------------------------
241
242
  // runCustomAction — validate, codegen, dispatch via superdoc_execute_code, map receipt
242
243
  // ---------------------------------------------------------------------------
243
- function isRecord(value) {
244
- return value != null && typeof value === 'object' && !Array.isArray(value);
245
- }
246
244
  /** Kit-level args every custom action accepts without declaring them. */
247
245
  const IMPLICIT_ACTION_ARGS = new Set(['changeMode', 'rationale']);
248
246
  function validateAgainstSchema(action, args) {
@@ -254,7 +252,7 @@ function validateAgainstSchema(action, args) {
254
252
  details: { action: action.name, missingKeys: missing },
255
253
  });
256
254
  }
257
- const properties = isRecord(action.inputSchema.properties) ? action.inputSchema.properties : {};
255
+ const properties = guards.isRecord(action.inputSchema.properties) ? action.inputSchema.properties : {};
258
256
  if (action.inputSchema.additionalProperties === false) {
259
257
  const unknown = Object.keys(args).filter((key) => !(key in properties) && !IMPLICIT_ACTION_ARGS.has(key));
260
258
  if (unknown.length > 0) {
@@ -266,7 +264,7 @@ function validateAgainstSchema(action, args) {
266
264
  }
267
265
  for (const [key, prop] of Object.entries(properties)) {
268
266
  const value = args[key];
269
- if (value !== undefined && isRecord(prop) && Array.isArray(prop.enum) && !prop.enum.includes(value)) {
267
+ if (value !== undefined && guards.isRecord(prop) && Array.isArray(prop.enum) && !prop.enum.includes(value)) {
270
268
  throw new errors.SuperDocCliError(`Invalid value for ${action.name}.${key}: ${JSON.stringify(value)} (allowed: ${prop.enum.map((entry) => JSON.stringify(entry)).join(', ')})`, { code: 'INVALID_ARGUMENT', details: { action: action.name, key, allowed: prop.enum } });
271
269
  }
272
270
  }
@@ -275,7 +273,7 @@ function validateAgainstSchema(action, args) {
275
273
  function applyInputDefaults(action, args) {
276
274
  const out = { ...args };
277
275
  for (const [key, prop] of Object.entries(action.inputSchema.properties ?? {})) {
278
- if (out[key] === undefined && isRecord(prop) && 'default' in prop)
276
+ if (out[key] === undefined && guards.isRecord(prop) && 'default' in prop)
279
277
  out[key] = prop.default;
280
278
  }
281
279
  return out;
@@ -309,7 +307,7 @@ function substituteTemplates(node, vars) {
309
307
  // would crash the transport).
310
308
  return node.map((item) => substituteTemplates(item, vars)).filter((item) => item !== undefined);
311
309
  }
312
- if (isRecord(node)) {
310
+ if (guards.isRecord(node)) {
313
311
  const out = {};
314
312
  for (const [key, value] of Object.entries(node)) {
315
313
  const substituted = substituteTemplates(value, vars);
@@ -341,7 +339,7 @@ async function runStepsAction(base, action, documentHandle, args, invokeOptions)
341
339
  let receipt;
342
340
  try {
343
341
  const dispatched = await base.dispatch(documentHandle, 'superdoc_perform_action', { action: step.action, ...stepArgs }, stepOptions);
344
- receipt = isRecord(dispatched) ? dispatched : { status: 'ok', result: dispatched };
342
+ receipt = guards.isRecord(dispatched) ? dispatched : { status: 'ok', result: dispatched };
345
343
  }
346
344
  catch (error) {
347
345
  // Validation errors THROW from dispatch; runtime failures come back as
@@ -458,13 +456,13 @@ function renormalizeAnthropicCacheMarker(tools, provider, cacheRequested) {
458
456
  if (provider !== 'anthropic' || !cacheRequested || tools.length === 0)
459
457
  return tools;
460
458
  const stripped = tools.map((tool) => {
461
- if (!isRecord(tool) || !('cache_control' in tool))
459
+ if (!guards.isRecord(tool) || !('cache_control' in tool))
462
460
  return tool;
463
461
  const { cache_control: _drop, ...rest } = tool;
464
462
  return rest;
465
463
  });
466
464
  const last = stripped[stripped.length - 1];
467
- stripped[stripped.length - 1] = isRecord(last) ? { ...last, cache_control: { type: 'ephemeral' } } : last;
465
+ stripped[stripped.length - 1] = guards.isRecord(last) ? { ...last, cache_control: { type: 'ephemeral' } } : last;
468
466
  return stripped;
469
467
  }
470
468
  function customActionsDescription(actions) {
@@ -535,16 +533,16 @@ function mergeIntoAgentAction(tools, actions) {
535
533
  // Provider dialects: openai nests under `function` (`parameters`);
536
534
  // anthropic is flat with `input_schema`; the core agent dialect for
537
535
  // vercel is flat with `inputSchema`; generic is flat with `parameters`.
538
- const fn = isRecord(t.function) ? t.function : null;
536
+ const fn = guards.isRecord(t.function) ? t.function : null;
539
537
  const schemaContainer = fn ?? t;
540
538
  const schemaKey = 'input_schema' in schemaContainer
541
539
  ? 'input_schema'
542
540
  : 'inputSchema' in schemaContainer
543
541
  ? 'inputSchema'
544
542
  : 'parameters';
545
- const schema = isRecord(schemaContainer[schemaKey]) ? schemaContainer[schemaKey] : {};
546
- const properties = isRecord(schema.properties) ? { ...schema.properties } : {};
547
- const actionProp = isRecord(properties.action) ? { ...properties.action } : {};
543
+ const schema = guards.isRecord(schemaContainer[schemaKey]) ? schemaContainer[schemaKey] : {};
544
+ const properties = guards.isRecord(schema.properties) ? { ...schema.properties } : {};
545
+ const actionProp = guards.isRecord(properties.action) ? { ...properties.action } : {};
548
546
  const enumValues = Array.isArray(actionProp.enum) ? [...actionProp.enum] : [];
549
547
  for (const action of actions) {
550
548
  if (!enumValues.includes(action.name))
@@ -748,7 +746,7 @@ function extendPreset(baseId, options) {
748
746
  // must be refused before it runs (the base can only refuse built-ins).
749
747
  const exclusionOptions = invokeOptions;
750
748
  const excluded = new Set(exclusionOptions?.excludeActions ?? []);
751
- if (toolName === 'superdoc_perform_action' && isRecord(args) && typeof args.action === 'string') {
749
+ if (toolName === 'superdoc_perform_action' && guards.isRecord(args) && typeof args.action === 'string') {
752
750
  // Advertised surface == dispatchable surface: in standalone mode custom
753
751
  // actions are advertised as their own tools, so the (unadvertised)
754
752
  // perform_action route must not execute them — it falls through to the
@@ -32,6 +32,7 @@ import { SuperDocCliError } from '../runtime/errors.js';
32
32
  import { getPreset, } from '../presets.js';
33
33
  import { ACTION_NAMES_LIST } from '../agent/actions.js';
34
34
  import { AGENT_TOOL_NAMES, buildPerformActionDefinition } from '../agent/catalog.js';
35
+ import { isRecord } from '../guards.js';
35
36
  /** Which execution tier a spec uses. */
36
37
  export function executionKindOf(spec) {
37
38
  return Array.isArray(spec.steps) ? 'steps' : 'run';
@@ -237,9 +238,6 @@ function assertActionsValid(actions, presetId, standalone = false) {
237
238
  // ---------------------------------------------------------------------------
238
239
  // runCustomAction — validate, codegen, dispatch via superdoc_execute_code, map receipt
239
240
  // ---------------------------------------------------------------------------
240
- function isRecord(value) {
241
- return value != null && typeof value === 'object' && !Array.isArray(value);
242
- }
243
241
  /** Kit-level args every custom action accepts without declaring them. */
244
242
  const IMPLICIT_ACTION_ARGS = new Set(['changeMode', 'rationale']);
245
243
  function validateAgainstSchema(action, args) {