@minded-ai/mindedjs 3.1.43 → 3.1.44

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 (45) hide show
  1. package/dist/cli/cliUtils.d.ts +4 -2
  2. package/dist/cli/cliUtils.d.ts.map +1 -1
  3. package/dist/cli/cliUtils.js +12 -5
  4. package/dist/cli/cliUtils.js.map +1 -1
  5. package/dist/nodes/addAppToolNode.d.ts.map +1 -1
  6. package/dist/nodes/addAppToolNode.js +59 -13
  7. package/dist/nodes/addAppToolNode.js.map +1 -1
  8. package/dist/nodes/addBrowserTaskNode.d.ts.map +1 -1
  9. package/dist/nodes/addBrowserTaskNode.js +13 -3
  10. package/dist/nodes/addBrowserTaskNode.js.map +1 -1
  11. package/dist/nodes/addToolNode.d.ts.map +1 -1
  12. package/dist/nodes/addToolNode.js +22 -40
  13. package/dist/nodes/addToolNode.js.map +1 -1
  14. package/dist/nodes/addToolRunNode.d.ts.map +1 -1
  15. package/dist/nodes/addToolRunNode.js +93 -82
  16. package/dist/nodes/addToolRunNode.js.map +1 -1
  17. package/dist/nodes/utils/getSchemaForToolInference.d.ts +13 -0
  18. package/dist/nodes/utils/getSchemaForToolInference.d.ts.map +1 -0
  19. package/dist/nodes/utils/getSchemaForToolInference.js +34 -0
  20. package/dist/nodes/utils/getSchemaForToolInference.js.map +1 -0
  21. package/dist/nodes/utils/inferToolCallWithRetry.d.ts +18 -0
  22. package/dist/nodes/utils/inferToolCallWithRetry.d.ts.map +1 -0
  23. package/dist/nodes/utils/inferToolCallWithRetry.js +58 -0
  24. package/dist/nodes/utils/inferToolCallWithRetry.js.map +1 -0
  25. package/dist/types/Flows.types.d.ts +1 -0
  26. package/dist/types/Flows.types.d.ts.map +1 -1
  27. package/dist/types/Flows.types.js +1 -0
  28. package/dist/types/Flows.types.js.map +1 -1
  29. package/dist/utils/flowSchema.d.ts.map +1 -1
  30. package/dist/utils/flowSchema.js +20 -4
  31. package/dist/utils/flowSchema.js.map +1 -1
  32. package/dist/utils/schemaUtils.d.ts.map +1 -1
  33. package/dist/utils/schemaUtils.js +2 -0
  34. package/dist/utils/schemaUtils.js.map +1 -1
  35. package/package.json +1 -1
  36. package/src/cli/cliUtils.ts +12 -5
  37. package/src/nodes/addAppToolNode.ts +61 -15
  38. package/src/nodes/addBrowserTaskNode.ts +13 -3
  39. package/src/nodes/addToolNode.ts +24 -46
  40. package/src/nodes/addToolRunNode.ts +114 -97
  41. package/src/nodes/utils/getSchemaForToolInference.ts +48 -0
  42. package/src/nodes/utils/inferToolCallWithRetry.ts +89 -0
  43. package/src/types/Flows.types.ts +1 -0
  44. package/src/utils/flowSchema.ts +21 -4
  45. package/src/utils/schemaUtils.ts +2 -0
@@ -0,0 +1,89 @@
1
+ import { AIMessage, BaseMessage, SystemMessage } from '@langchain/core/messages';
2
+ import { z } from 'zod';
3
+ import { logger } from '../../utils/logger';
4
+
5
+ interface InferToolCallWithRetryParams {
6
+ llm: any;
7
+ tool: { name: string };
8
+ inputSchema: z.ZodTypeAny;
9
+ messages: BaseMessage[];
10
+ sessionId: string;
11
+ mergeArgs?: (args: Record<string, any>) => Record<string, any>;
12
+ onAfterAttempt?: () => Promise<void>;
13
+ maxAttempts?: number;
14
+ toolNameForLogs: string;
15
+ }
16
+
17
+ export const inferToolCallWithRetry = async ({
18
+ llm,
19
+ tool,
20
+ inputSchema,
21
+ messages,
22
+ sessionId,
23
+ mergeArgs,
24
+ onAfterAttempt,
25
+ maxAttempts = 2,
26
+ toolNameForLogs,
27
+ }: InferToolCallWithRetryParams): Promise<AIMessage> => {
28
+ let inferenceMessages = [...messages];
29
+ let aiToolCallMessage: AIMessage = new AIMessage({ content: '', tool_calls: [] });
30
+
31
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
32
+ aiToolCallMessage = await llm.bindTools([tool], { tool_choice: tool.name }).invoke(inferenceMessages);
33
+ if (onAfterAttempt) {
34
+ await onAfterAttempt();
35
+ }
36
+
37
+ if (!aiToolCallMessage.tool_calls || aiToolCallMessage.tool_calls.length === 0) {
38
+ throw new Error('No tool calls generated by LLM');
39
+ }
40
+
41
+ const inferredArgs = (aiToolCallMessage.tool_calls[0].args || {}) as Record<string, any>;
42
+ const mergedArgs = mergeArgs ? mergeArgs(inferredArgs) : inferredArgs;
43
+ const parseResult = inputSchema.safeParse(mergedArgs);
44
+
45
+ if (parseResult.success) {
46
+ aiToolCallMessage.tool_calls[0].args = parseResult.data;
47
+ return aiToolCallMessage;
48
+ }
49
+
50
+ if (attempt < maxAttempts) {
51
+ const validationIssues = parseResult.error.issues
52
+ .map((issue: z.ZodIssue) => `${issue.path.join('.') || '<root>'}: ${issue.message}`)
53
+ .join('; ');
54
+
55
+ logger.error({
56
+ msg: '[Tool] Retrying parameter inference due to schema mismatch',
57
+ tool: toolNameForLogs,
58
+ sessionId,
59
+ attempt,
60
+ validationIssues,
61
+ });
62
+
63
+ inferenceMessages = [
64
+ ...inferenceMessages,
65
+ new SystemMessage(
66
+ `Your previous tool arguments were invalid for tool "${tool.name}".
67
+ Validation issues: ${validationIssues}
68
+ Return arguments that strictly match the tool schema types. Do not wrap scalar values in arrays.`,
69
+ ),
70
+ ];
71
+ continue;
72
+ }
73
+
74
+ logger.error({
75
+ msg: '[Tool] Inferred parameters remain schema-invalid after retries',
76
+ tool: toolNameForLogs,
77
+ sessionId,
78
+ validationIssues: parseResult.error.issues.map((issue: z.ZodIssue) => ({
79
+ path: issue.path.join('.') || '<root>',
80
+ message: issue.message,
81
+ })),
82
+ });
83
+
84
+ aiToolCallMessage.tool_calls[0].args = mergedArgs;
85
+ return aiToolCallMessage;
86
+ }
87
+
88
+ return aiToolCallMessage;
89
+ };
@@ -315,6 +315,7 @@ export type ActionInputParam = {
315
315
  export enum ActionInputParamType {
316
316
  String = 'string',
317
317
  Number = 'number',
318
+ Integer = 'integer',
318
319
  Boolean = 'boolean',
319
320
  Array = 'array',
320
321
  Object = 'object',
@@ -373,9 +373,13 @@ export function safeParseFlow(flow: unknown): z.ZodSafeParseResult<FlowTypes.Flo
373
373
  return `Invalid ${subjectLabel}: "${toDotPath(issuePath)}" must be ${issue.expected}, received ${parsedType(issue.input)}`;
374
374
  }
375
375
  } else if (issue.code === 'invalid_value') {
376
- const { subjectLabel } = getErrorSubject(issuePath, flow);
376
+ const { subjectLabel, fieldHint } = getErrorSubject(issuePath, flow);
377
377
  const allowedValues = `[${issue.values.join(', ')}]`;
378
- return `Invalid ${subjectLabel}: "${toDotPath(issuePath)}" must be one of ${allowedValues}, received ${parsedType(issue.input)}`;
378
+ const receivedValue = typeof issue.input === 'string' ? `"${issue.input}"` : parsedType(issue.input);
379
+ if (fieldHint) {
380
+ return `Invalid ${subjectLabel}: ${fieldHint} must be one of ${allowedValues}, received ${receivedValue}`;
381
+ }
382
+ return `Invalid ${subjectLabel}: "${toDotPath(issuePath)}" must be one of ${allowedValues}, received ${receivedValue}`;
379
383
  } else if (issue.code === 'unrecognized_keys') {
380
384
  const { subjectLabel } = getErrorSubject(issuePath, flow);
381
385
  return `Invalid ${subjectLabel}: "${toDotPath(issuePath)}" unrecognized key "${issue.keys.join(', ')}"`;
@@ -430,16 +434,28 @@ export function safeParseFlow(flow: unknown): z.ZodSafeParseResult<FlowTypes.Flo
430
434
  function getErrorSubject(issuePath: PropertyKey[], flow: any) {
431
435
  let subject = 'flow';
432
436
  let subjectLabel: string | undefined;
437
+ let fieldHint: string | undefined;
433
438
  if (issuePath.length === 1) {
434
439
  subject = 'flow';
435
440
  } else if (issuePath.length >= 3 && issuePath[0] === 'nodes') {
436
441
  subject = 'node';
437
442
  const node = _.get(flow, issuePath.slice(0, 2));
438
443
  if (node && 'type' in node) {
444
+ const nodeName = node.name ? ` "${node.name}"` : '';
439
445
  if ('triggerType' in node) {
440
- subjectLabel = `${node.triggerType} ${node.type} node`;
446
+ subjectLabel = `${node.triggerType} ${node.type} node${nodeName}`;
441
447
  } else {
442
- subjectLabel = `${node.type} node`;
448
+ subjectLabel = `${node.type} node${nodeName}`;
449
+ }
450
+ }
451
+
452
+ // Provide human-readable hints for paths deep into metadata.schema[n]
453
+ if (issuePath.length >= 5 && issuePath[2] === 'metadata' && issuePath[3] === 'schema') {
454
+ const fieldIndex = issuePath[4] as number;
455
+ const schemaField = _.get(flow, ['nodes', issuePath[1], 'metadata', 'schema', fieldIndex]);
456
+ if (schemaField && 'name' in schemaField) {
457
+ const prop = issuePath.length > 5 ? `, property "${String(issuePath[issuePath.length - 1])}"` : '';
458
+ fieldHint = `schema field "${schemaField.name}"${prop}`;
443
459
  }
444
460
  }
445
461
  } else if (issuePath.length > 2 && issuePath[0] === 'edges') {
@@ -457,5 +473,6 @@ function getErrorSubject(issuePath: PropertyKey[], flow: any) {
457
473
  return {
458
474
  subject,
459
475
  subjectLabel,
476
+ fieldHint,
460
477
  };
461
478
  }
@@ -25,6 +25,8 @@ export const mapItemTypeToZod = (
25
25
  return z.string();
26
26
  case 'number':
27
27
  return z.number();
28
+ case 'integer':
29
+ return z.number().int();
28
30
  case 'boolean':
29
31
  return z.boolean();
30
32
  case 'any':