@takeshape/schema 11.98.5 → 11.99.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 (44) hide show
  1. package/dist/agents.d.ts +13 -7
  2. package/dist/agents.js +78 -65
  3. package/dist/builtin-schema.js +12 -0
  4. package/dist/index.d.ts +1 -0
  5. package/dist/index.js +1 -0
  6. package/dist/models/agent.d.ts +3 -0
  7. package/dist/models/agent.js +29 -0
  8. package/dist/models/project-schema.d.ts +17 -0
  9. package/dist/models/project-schema.js +112 -0
  10. package/dist/models/query.d.ts +2 -8
  11. package/dist/models/query.js +16 -4
  12. package/dist/models/runtime-schema.d.ts +3 -7
  13. package/dist/models/runtime-schema.js +9 -86
  14. package/dist/models/shape.d.ts +2 -10
  15. package/dist/models/shape.js +7 -4
  16. package/dist/models/types.d.ts +28 -4
  17. package/dist/models/user-schema.d.ts +7 -0
  18. package/dist/models/user-schema.js +9 -0
  19. package/dist/project-schema/latest.d.ts +33 -38
  20. package/dist/project-schema/v3.48.0.d.ts +33 -38
  21. package/dist/project-schema/v3.49.0.d.ts +33 -38
  22. package/dist/project-schema/v3.50.0.d.ts +33 -38
  23. package/dist/project-schema/v3.51.0.d.ts +33 -38
  24. package/dist/project-schema/v3.52.0.d.ts +33 -38
  25. package/dist/project-schema/v3.53.0.d.ts +33 -38
  26. package/dist/project-schema/v3.54.0.d.ts +33 -38
  27. package/dist/project-schema/v3.55.0.d.ts +33 -38
  28. package/dist/resolvers/takeshape/assets/asset-image-params.d.ts +1 -1
  29. package/dist/schema-util.d.ts +5 -4
  30. package/dist/schema-util.js +43 -3
  31. package/dist/schemas/project-schema/experimental.json +101 -131
  32. package/dist/util/mcp.d.ts +1 -0
  33. package/dist/util/mcp.js +1 -1
  34. package/dist/validate/ai.d.ts +6 -0
  35. package/dist/validate/ai.js +183 -0
  36. package/dist/validate/types.d.ts +1 -0
  37. package/dist/validate/types.js +1 -0
  38. package/dist/validate/util.d.ts +3 -0
  39. package/dist/validate/util.js +28 -0
  40. package/dist/validate/validate.d.ts +1 -0
  41. package/dist/validate/validate.js +14 -164
  42. package/examples/latest/agent-schema.json +24 -10
  43. package/examples/source/agent-schema.json +23 -9
  44. package/package.json +5 -5
@@ -16,25 +16,27 @@ import coerce from 'semver/functions/coerce.js';
16
16
  import gte from 'semver/functions/gte.js';
17
17
  import lt from 'semver/functions/lt.js';
18
18
  import neq from 'semver/functions/neq.js';
19
- import { isGuardEnabled } from "../agents.js";
19
+ import { GUARDS_SCHEMA_PATH, getGuards, isGuardEnabled } from "../agents.js";
20
20
  import { builtInShapes } from "../builtin-schema.js";
21
21
  import { isEnumLikeSchema } from "../enum.js";
22
22
  import { isLatestProjectSchemaJSON } from "../project-schema/index.js";
23
23
  import { createGetNamespace, getRefShapeName, getToolRef, isValidServiceId, parsePropertyRef, parseRef, propertyRefItemToPath, propertyRefItemToResolverPath, refItemToNamespacedShapeName, refItemToShape, serializeRef } from "../refs.js";
24
24
  import { getRelationship } from "../relationships.js";
25
25
  import { scalars } from "../scalars.js";
26
- import { getAllRefs, isBuiltinMutation, isBuiltinQuery } from "../schema-util.js";
26
+ import { getAllRefs } from "../schema-util.js";
27
27
  import authSchemas from '../schemas/auth-schemas.json' with { type: 'json' };
28
28
  import { allProjectSchemas } from "../schemas/index.js";
29
29
  import { isValidTemplate } from "../template-shapes/index.js";
30
30
  import { legacyProjectSchemaImportOptionalProps, projectSchemaImportOptionalProps } from "../types/types.js";
31
31
  import { isAIResolver, isBasicResolver, isComposeResolver, isExtendsSchema, isObjectSchema } from "../types/utils.js";
32
32
  import { isUnionSchema } from "../unions.js";
33
- import { validateExpression } from "../util/expressions.js";
33
+ import { getMcpToolMap, TOOL_SCHEMA_PATH } from '../util/mcp.js';
34
34
  import { getShape } from "../util/shapes.js";
35
35
  import { CURRENT_SCHEMA_VERSION, LEGACY_API_VERSION, LEGACY_SCHEMA_VERSION } from "../versions.js";
36
36
  import { defaultWorkflow } from "../workflows.js";
37
+ import { validateAgents, validateAIToolConfig } from "./ai.js";
37
38
  import { formatError } from "./errors.js";
39
+ import { pushErrors } from './util.js';
38
40
  export const builtInShapeNames = new Set([...Object.keys(builtInShapes), ...scalars, 'object']);
39
41
  function findDuplicates(items) {
40
42
  const seen = {};
@@ -78,7 +80,7 @@ function checkToolNames(tools) {
78
80
  return Object.entries(tools)
79
81
  .filter(([name, tool]) => name !== tool.name)
80
82
  .map(([name, tool]) => ({
81
- path: ['ai-experimental', 'mcp', 'tools', name, 'name'],
83
+ path: [...TOOL_SCHEMA_PATH, name, 'name'],
82
84
  type: 'conflict',
83
85
  message: `Tool.name "${tool.name}" must match key "${name}".`
84
86
  }));
@@ -135,11 +137,6 @@ function validateWorkflows(projectSchema) {
135
137
  function getSemver(schemaVersion) {
136
138
  return coerce(schemaVersion) ?? LEGACY_SCHEMA_VERSION;
137
139
  }
138
- function pushErrors(errors, error) {
139
- if (error) {
140
- errors.push(error);
141
- }
142
- }
143
140
  function enumerateBasicResolvers(resolver, path) {
144
141
  const results = [];
145
142
  const visit = (resolver, path) => {
@@ -155,47 +152,6 @@ function enumerateBasicResolvers(resolver, path) {
155
152
  visit(resolver, path);
156
153
  return results;
157
154
  }
158
- const isValidAgentMutation = (projectSchema, mutationName) => {
159
- return Boolean(projectSchema['ai-experimental']?.agents?.[mutationName]);
160
- };
161
- const validateAIToolConfig = (projectSchema, getNamespace, tool, basePath) => {
162
- const toolRef = getToolRef(tool);
163
- const path = typeof tool === 'string' ? basePath : basePath.concat('ref');
164
- const parsed = parsePropertyRef(toolRef);
165
- if (!parsed) {
166
- return {
167
- type: 'conflict',
168
- path,
169
- message: `Unable to parse property ref "${toolRef}"`
170
- };
171
- }
172
- if (parsed.layerId !== 'local') {
173
- return;
174
- }
175
- if ((parsed.shapeName === 'Query' && isBuiltinQuery(parsed.propertyName)) ||
176
- (parsed.shapeName === 'Mutation' && isBuiltinMutation(parsed.propertyName))) {
177
- return;
178
- }
179
- const propertyPath = propertyRefItemToPath(getNamespace, parsed);
180
- if (propertyPath[0] !== 'queries' && propertyPath[0] !== 'mutations') {
181
- return {
182
- type: 'conflict',
183
- path,
184
- message: 'Tools must be a query or mutation'
185
- };
186
- }
187
- const property = get(projectSchema, propertyPath);
188
- if (propertyPath[0] === 'mutations' && isValidAgentMutation(projectSchema, propertyPath[1])) {
189
- return;
190
- }
191
- if (!property) {
192
- return {
193
- type: 'notFound',
194
- path,
195
- message: `Missing tool ${propertyPath[0] === 'queries' ? 'query' : 'mutation'} "${toolRef}"`
196
- };
197
- }
198
- };
199
155
  function validateResolver(projectSchema, basePath, baseResolver) {
200
156
  const errors = [];
201
157
  const isValidShapeName = (shapeName) => {
@@ -359,7 +315,7 @@ function isValidShapeReference(context, layerState, shapeName) {
359
315
  }
360
316
  return Boolean(layerState.schema.shapes[shapeName]);
361
317
  }
362
- async function validateResolverReferences(context, projectSchema, basePath, baseResolver) {
318
+ async function validateResolverReferences(context, basePath, baseResolver) {
363
319
  const errors = [];
364
320
  const isInvalidPropertyRef = async (refStr) => {
365
321
  const ref = parsePropertyRef(refStr);
@@ -415,9 +371,9 @@ async function validateResolverReferences(context, projectSchema, basePath, base
415
371
  });
416
372
  return errors;
417
373
  }
418
- async function validateQueryConfig(context, projectSchema, { query, name, operation }) {
374
+ async function validateQueryConfig(context, { query, name, operation }) {
419
375
  const location = operation === 'query' ? 'queries' : 'mutations';
420
- return validateResolverReferences(context, projectSchema, [location, name, 'resolver'], query.resolver);
376
+ return validateResolverReferences(context, [location, name, 'resolver'], query.resolver);
421
377
  }
422
378
  async function validateQueryConfigs(context, projectSchema) {
423
379
  const isLessThanV3_9_0 = lt(getSemver(projectSchema.schemaVersion), '3.9.0');
@@ -427,7 +383,7 @@ async function validateQueryConfigs(context, projectSchema) {
427
383
  const promises = [];
428
384
  for (const [operation, prop] of operationProps) {
429
385
  for (const name of Object.keys(projectSchema[prop])) {
430
- promises.push(validateQueryConfig(context, projectSchema, {
386
+ promises.push(validateQueryConfig(context, {
431
387
  query: projectSchema[prop][name],
432
388
  operation,
433
389
  name
@@ -492,7 +448,7 @@ async function validateShapeJoinRef(context, projectSchema, item) {
492
448
  async function validateShapeJoins(context, projectSchema) {
493
449
  const promises = [];
494
450
  for (const item of listShapeJoins(projectSchema)) {
495
- promises.push(validateShapeJoinRef(context, projectSchema, item), validateResolverReferences(context, projectSchema, item.path, item.join.resolver));
451
+ promises.push(validateShapeJoinRef(context, projectSchema, item), validateResolverReferences(context, item.path, item.join.resolver));
496
452
  }
497
453
  return flatten(await Promise.all(promises));
498
454
  }
@@ -829,112 +785,6 @@ function validateInterfaceImplementations(projectSchema) {
829
785
  }
830
786
  return errors;
831
787
  }
832
- function validateAgents(projectSchema) {
833
- const getNamespace = createGetNamespace(projectSchema);
834
- const errors = [];
835
- const guards = projectSchema['ai-experimental']?.guards;
836
- const agents = projectSchema['ai-experimental']?.agents;
837
- if (!agents) {
838
- return errors;
839
- }
840
- for (const [agentName, agent] of Object.entries(agents)) {
841
- const stateNames = new Set();
842
- const agentPath = ['ai-experimental', 'agents', agentName];
843
- for (const [stateId, state] of Object.entries(agent.states)) {
844
- const statePath = [...agentPath, 'states', stateId];
845
- if (stateNames.has(state.name)) {
846
- errors.push({
847
- path: [...statePath, 'name'],
848
- type: 'conflict',
849
- message: `Duplicate state name "${state.name}"`
850
- });
851
- }
852
- else {
853
- stateNames.add(state.name);
854
- }
855
- if (state.variables) {
856
- state.variables.forEach((variable, variableIndex) => {
857
- variable.steps.forEach((step, stepIndex) => {
858
- const stepPath = [...statePath, 'variables', variableIndex, 'steps', stepIndex];
859
- if (step.condition) {
860
- const conditionValidation = validateExpression(step.condition);
861
- if (!conditionValidation.valid) {
862
- const common = {
863
- path: [...stepPath, 'condition'],
864
- type: 'conflict'
865
- };
866
- errors.push(...conditionValidation.errors.map((message) => ({ ...common, message })));
867
- }
868
- }
869
- const exprValidation = validateExpression(step.expression);
870
- if (!exprValidation.valid) {
871
- const common = {
872
- path: [...stepPath, 'expression'],
873
- type: 'conflict'
874
- };
875
- errors.push(...exprValidation.errors.map((message) => ({ ...common, message })));
876
- }
877
- });
878
- });
879
- }
880
- if (state.transition) {
881
- state.transition.forEach((transition, transitionIndex) => {
882
- if (transition.condition) {
883
- const conditionValidation = validateExpression(transition.condition);
884
- if (!conditionValidation.valid) {
885
- const common = {
886
- path: [...statePath, 'transition', transitionIndex, 'expression'],
887
- type: 'conflict'
888
- };
889
- errors.push(...conditionValidation.errors.map((message) => ({ ...common, message })));
890
- }
891
- }
892
- });
893
- }
894
- if (state.execution.type === 'generate' || state.execution.type === 'chat') {
895
- if (!state.execution.tools) {
896
- continue;
897
- }
898
- state.execution.tools.forEach((tool, toolIndex) => {
899
- pushErrors(errors, validateAIToolConfig(projectSchema, getNamespace, tool, [
900
- ...statePath,
901
- 'execution',
902
- 'tools',
903
- toolIndex,
904
- 'ref'
905
- ]));
906
- });
907
- }
908
- }
909
- if (agent.guards) {
910
- const invalidGuards = agent.guards.filter(({ guardId }) => !guards?.[guardId]);
911
- if (invalidGuards.length) {
912
- const guardPath = [...agentPath, 'guards'];
913
- errors.push(...invalidGuards.map(({ guardId }, index) => ({
914
- path: [...guardPath, index, 'guardId'],
915
- type: 'notFound',
916
- message: `Invalid guardId "${guardId}"`
917
- })));
918
- }
919
- }
920
- if (agent.historyStrategies) {
921
- const seenStrategyNames = new Set();
922
- for (const [historyStrategyId, historyStrategy] of Object.entries(agent.historyStrategies)) {
923
- if (seenStrategyNames.has(historyStrategy.name)) {
924
- errors.push({
925
- path: [...agentPath, 'historyStrategies', historyStrategyId, 'name'],
926
- type: 'conflict',
927
- message: `Duplicate history strategy name "${historyStrategy.name}"`
928
- });
929
- }
930
- else {
931
- seenStrategyNames.add(historyStrategy.name);
932
- }
933
- }
934
- }
935
- }
936
- return errors;
937
- }
938
788
  function validateInterfaces(projectSchema) {
939
789
  const errors = [];
940
790
  // Validate interface shapes must be an object schema with at least one property
@@ -1007,13 +857,13 @@ function validateGuards(context, schema) {
1007
857
  if (context.ignoreEntitlements) {
1008
858
  return errors;
1009
859
  }
1010
- const numGuards = Object.values(schema['ai-experimental']?.guards ?? {}).filter((guard) => isGuardEnabled(guard)).length;
860
+ const numGuards = getGuards(schema).filter(isGuardEnabled).length;
1011
861
  const entitledGuards = context.entitlements.guards ?? 0;
1012
862
  if (numGuards > entitledGuards) {
1013
863
  errors.push({
1014
864
  type: 'entitlement',
1015
865
  message: `Number of enabled guards exceeds your entitled limit of ${entitledGuards}`,
1016
- path: ['ai-experimental', 'guards']
866
+ path: [...GUARDS_SCHEMA_PATH]
1017
867
  });
1018
868
  }
1019
869
  return errors;
@@ -1046,7 +896,7 @@ function validateSyntax(context, schema) {
1046
896
  .concat(validateInterfaceImplementations(schema))
1047
897
  .concat(validateAgents(schema))
1048
898
  .concat(validateGuards(context, schema));
1049
- const mcpTools = schema['ai-experimental']?.mcp?.tools;
899
+ const mcpTools = getMcpToolMap(schema);
1050
900
  if (mcpTools) {
1051
901
  errors = errors.concat(checkToolNames(mcpTools ?? {}));
1052
902
  }
@@ -187,18 +187,19 @@
187
187
  "findDogColor": {
188
188
  "description": "AI Agent finds a dog's color based on its name",
189
189
  "api": {
190
- "type": "generate",
191
- "arguments": [
190
+ "inputs": [
192
191
  {
193
- "argName": "input",
194
- "argType": "string",
195
- "required": true
192
+ "name": "findDogColor",
193
+ "type": "mutation",
194
+ "args": "TSGenerateArgs"
196
195
  }
197
196
  ]
198
197
  },
199
198
  "start": {
200
199
  "transition": [
201
200
  {
201
+ "type": "suspend",
202
+ "input": "findDogColor",
202
203
  "destination": "bbb"
203
204
  }
204
205
  ]
@@ -229,6 +230,7 @@
229
230
  },
230
231
  "transition": [
231
232
  {
233
+ "type": "immediate",
232
234
  "destination": "ccc"
233
235
  }
234
236
  ]
@@ -265,14 +267,17 @@
265
267
  },
266
268
  "transition": [
267
269
  {
270
+ "type": "immediate",
268
271
  "condition": "stateOutputs['ccc'].answered",
269
272
  "destination": "ddd"
270
273
  },
271
274
  {
275
+ "type": "immediate",
272
276
  "limit": 3,
273
277
  "destination": "bbb"
274
278
  },
275
279
  {
280
+ "type": "immediate",
276
281
  "destination": "eee"
277
282
  }
278
283
  ]
@@ -328,12 +333,19 @@
328
333
  },
329
334
  "chat": {
330
335
  "api": {
331
- "type": "chat",
332
- "arguments": []
336
+ "inputs": [
337
+ {
338
+ "name": "chat",
339
+ "type": "mutation",
340
+ "args": "TSChatArgs"
341
+ }
342
+ ]
333
343
  },
334
344
  "start": {
335
345
  "transition": [
336
346
  {
347
+ "type": "suspend",
348
+ "input": "chat",
337
349
  "destination": "3pjuyB47X"
338
350
  }
339
351
  ]
@@ -352,12 +364,14 @@
352
364
  },
353
365
  "transition": [
354
366
  {
367
+ "type": "immediate",
355
368
  "condition": "contains(currentStateOutput.content, 'ALL_DONE')",
356
- "destination": "endAgentExecution"
369
+ "destination": "END"
357
370
  },
358
371
  {
372
+ "type": "suspend",
359
373
  "destination": "3pjuyB47X",
360
- "suspend": true
374
+ "input": "chat"
361
375
  }
362
376
  ]
363
377
  }
@@ -366,4 +380,4 @@
366
380
  }
367
381
  }
368
382
  }
369
- }
383
+ }
@@ -169,18 +169,19 @@
169
169
  "findDogColor": {
170
170
  "description": "AI Agent finds a dog's color based on its name",
171
171
  "api": {
172
- "type": "generate",
173
- "arguments": [
172
+ "inputs": [
174
173
  {
175
- "argName": "input",
176
- "argType": "string",
177
- "required": true
174
+ "name": "findDogColor",
175
+ "type": "mutation",
176
+ "args": "TSGenerateArgs"
178
177
  }
179
178
  ]
180
179
  },
181
180
  "start": {
182
181
  "transition": [
183
182
  {
183
+ "type": "suspend",
184
+ "input": "findDogColor",
184
185
  "destination": "bbb"
185
186
  }
186
187
  ]
@@ -211,6 +212,7 @@
211
212
  },
212
213
  "transition": [
213
214
  {
215
+ "type": "immediate",
214
216
  "destination": "ccc"
215
217
  }
216
218
  ]
@@ -247,14 +249,17 @@
247
249
  },
248
250
  "transition": [
249
251
  {
252
+ "type": "immediate",
250
253
  "condition": "stateOutputs['ccc'].answered",
251
254
  "destination": "ddd"
252
255
  },
253
256
  {
257
+ "type": "immediate",
254
258
  "limit": 3,
255
259
  "destination": "bbb"
256
260
  },
257
261
  {
262
+ "type": "immediate",
258
263
  "destination": "eee"
259
264
  }
260
265
  ]
@@ -310,12 +315,19 @@
310
315
  },
311
316
  "chat": {
312
317
  "api": {
313
- "type": "chat",
314
- "arguments": []
318
+ "inputs": [
319
+ {
320
+ "name": "chat",
321
+ "type": "mutation",
322
+ "args": "TSChatArgs"
323
+ }
324
+ ]
315
325
  },
316
326
  "start": {
317
327
  "transition": [
318
328
  {
329
+ "type": "suspend",
330
+ "input": "chat",
319
331
  "destination": "3pjuyB47X"
320
332
  }
321
333
  ]
@@ -334,12 +346,14 @@
334
346
  },
335
347
  "transition": [
336
348
  {
349
+ "type": "immediate",
337
350
  "condition": "contains(currentStateOutput.content, 'ALL_DONE')",
338
- "destination": "endAgentExecution"
351
+ "destination": "END"
339
352
  },
340
353
  {
354
+ "type": "suspend",
341
355
  "destination": "3pjuyB47X",
342
- "suspend": true
356
+ "input": "chat"
343
357
  }
344
358
  ]
345
359
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@takeshape/schema",
3
- "version": "11.98.5",
3
+ "version": "11.99.0",
4
4
  "description": "TakeShape Schema",
5
5
  "homepage": "https://www.takeshape.io",
6
6
  "repository": {
@@ -58,9 +58,9 @@
58
58
  "p-reduce": "^2.1.0",
59
59
  "semver": "^7.3.2",
60
60
  "tiny-invariant": "^1.2.0",
61
- "@takeshape/errors": "11.98.5",
62
- "@takeshape/util": "11.98.5",
63
- "@takeshape/json-schema": "11.98.5"
61
+ "@takeshape/errors": "11.99.0",
62
+ "@takeshape/json-schema": "11.99.0",
63
+ "@takeshape/util": "11.99.0"
64
64
  },
65
65
  "devDependencies": {
66
66
  "@takeshape/json-schema-to-typescript": "^11.0.0",
@@ -76,7 +76,7 @@
76
76
  "glob": "^7.1.6",
77
77
  "json-schema-to-ts": "^3.1.1",
78
78
  "shortid": "^2.2.15",
79
- "@takeshape/infra": "11.98.5"
79
+ "@takeshape/infra": "11.99.0"
80
80
  },
81
81
  "engines": {
82
82
  "node": ">=20"