@compilr-dev/sdk 0.10.33 → 0.10.34
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.
|
@@ -86,13 +86,35 @@ export function createAskUserTool(handler) {
|
|
|
86
86
|
},
|
|
87
87
|
execute: async (input) => {
|
|
88
88
|
try {
|
|
89
|
-
|
|
89
|
+
// Defensive — some providers (Gemini Flash via OpenAI compat, etc.)
|
|
90
|
+
// ship nested object arguments as JSON-stringified strings. Parse
|
|
91
|
+
// before the length check so hosts always see a real array.
|
|
92
|
+
let questions = input.questions;
|
|
93
|
+
if (typeof questions === 'string') {
|
|
94
|
+
try {
|
|
95
|
+
questions = JSON.parse(questions);
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
return {
|
|
99
|
+
success: false,
|
|
100
|
+
error: 'questions must be an array (received a non-JSON string)',
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
if (!Array.isArray(questions)) {
|
|
105
|
+
return { success: false, error: 'questions must be an array' };
|
|
106
|
+
}
|
|
107
|
+
if (questions.length === 0) {
|
|
90
108
|
return { success: false, error: 'At least one question is required' };
|
|
91
109
|
}
|
|
92
|
-
if (
|
|
110
|
+
if (questions.length > 5) {
|
|
93
111
|
return { success: false, error: 'Maximum 5 questions allowed' };
|
|
94
112
|
}
|
|
95
|
-
const
|
|
113
|
+
const normalised = {
|
|
114
|
+
...input,
|
|
115
|
+
questions: questions,
|
|
116
|
+
};
|
|
117
|
+
const result = await handler(normalised);
|
|
96
118
|
return { success: true, result };
|
|
97
119
|
}
|
|
98
120
|
catch (err) {
|
|
@@ -706,7 +706,29 @@ export function createInteractiveFlowTool(handler) {
|
|
|
706
706
|
inputSchema: INTERACTIVE_FLOW_INPUT_SCHEMA,
|
|
707
707
|
execute: async (input) => {
|
|
708
708
|
try {
|
|
709
|
-
|
|
709
|
+
// Defensive — some providers (Gemini Flash via OpenAI compat,
|
|
710
|
+
// etc.) ship complex object arguments as JSON-stringified strings
|
|
711
|
+
// rather than parsed objects. The agents library does the outer
|
|
712
|
+
// parse but doesn't recurse into nested values. Parse here so the
|
|
713
|
+
// validator sees the proper object shape. Same quirk hit by
|
|
714
|
+
// ask_user.questions and propose_alternatives.alternatives —
|
|
715
|
+
// fixed at the CLI display layer for those, but here it must
|
|
716
|
+
// happen pre-validation since the validator rejects strings.
|
|
717
|
+
let flow = input.flow;
|
|
718
|
+
if (typeof flow === 'string') {
|
|
719
|
+
try {
|
|
720
|
+
flow = JSON.parse(flow);
|
|
721
|
+
}
|
|
722
|
+
catch {
|
|
723
|
+
return {
|
|
724
|
+
success: false,
|
|
725
|
+
error: 'Interactive flow validation failed:\n' +
|
|
726
|
+
"[INVALID_NODE_TYPE] Flow must be an object — received a string that wasn't valid JSON. " +
|
|
727
|
+
'Pass the flow as a parsed object, not as a JSON-stringified string.',
|
|
728
|
+
};
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
const validation = validateFlow(flow);
|
|
710
732
|
if (!validation.ok) {
|
|
711
733
|
const summary = validation.errors
|
|
712
734
|
.map((e) => `[${e.code}]${e.nodeId ? ` (node '${e.nodeId}')` : ''} ${e.message}`)
|
|
@@ -716,7 +738,11 @@ export function createInteractiveFlowTool(handler) {
|
|
|
716
738
|
error: `Interactive flow validation failed:\n${summary}`,
|
|
717
739
|
};
|
|
718
740
|
}
|
|
719
|
-
|
|
741
|
+
// Validation passed → flow is a well-formed Flow. Hand it to the
|
|
742
|
+
// handler with the (possibly-parsed) value so the host gets an
|
|
743
|
+
// object too.
|
|
744
|
+
const normalisedInput = { flow: flow };
|
|
745
|
+
const result = await handler(normalisedInput);
|
|
720
746
|
if (validation.warnings.length > 0) {
|
|
721
747
|
result.warnings = [...(result.warnings ?? []), ...validation.warnings];
|
|
722
748
|
}
|
|
@@ -88,13 +88,35 @@ export function createProposeAlternativesTool(handler) {
|
|
|
88
88
|
},
|
|
89
89
|
execute: async (input) => {
|
|
90
90
|
try {
|
|
91
|
-
|
|
91
|
+
// Defensive — some providers (Gemini Flash via OpenAI compat, etc.)
|
|
92
|
+
// ship nested object arguments as JSON-stringified strings. Parse
|
|
93
|
+
// before validation so hosts always see a real array.
|
|
94
|
+
let alternatives = input.alternatives;
|
|
95
|
+
if (typeof alternatives === 'string') {
|
|
96
|
+
try {
|
|
97
|
+
alternatives = JSON.parse(alternatives);
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
return {
|
|
101
|
+
success: false,
|
|
102
|
+
error: 'alternatives must be an array (received a non-JSON string)',
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
if (!Array.isArray(alternatives)) {
|
|
107
|
+
return { success: false, error: 'alternatives must be an array' };
|
|
108
|
+
}
|
|
109
|
+
if (alternatives.length < 2) {
|
|
92
110
|
return { success: false, error: 'At least 2 alternatives are required' };
|
|
93
111
|
}
|
|
94
|
-
if (
|
|
112
|
+
if (alternatives.length > 3) {
|
|
95
113
|
return { success: false, error: 'Maximum 3 alternatives allowed' };
|
|
96
114
|
}
|
|
97
|
-
const
|
|
115
|
+
const normalised = {
|
|
116
|
+
...input,
|
|
117
|
+
alternatives: alternatives,
|
|
118
|
+
};
|
|
119
|
+
const result = await handler(normalised);
|
|
98
120
|
if (result.rejected) {
|
|
99
121
|
return {
|
|
100
122
|
success: true,
|