@compilr-dev/sdk 0.10.34 → 0.10.35
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.
|
@@ -489,6 +489,8 @@ function buildCompactSchema(tool) {
|
|
|
489
489
|
* Handles common LLM mistakes when calling tools without guided decoding:
|
|
490
490
|
* - Single object where array expected → wraps in array
|
|
491
491
|
* - JSON string where array expected → parses it
|
|
492
|
+
* - JSON string where object expected → parses it (covers e.g. Gemini Flash
|
|
493
|
+
* stringifying complex nested objects like build_interactive_flow.flow)
|
|
492
494
|
*/
|
|
493
495
|
function coerceArgs(schema, args) {
|
|
494
496
|
const properties = schema.properties;
|
|
@@ -497,27 +499,43 @@ function coerceArgs(schema, args) {
|
|
|
497
499
|
let changed = false;
|
|
498
500
|
const coerced = { ...args };
|
|
499
501
|
for (const [name, prop] of Object.entries(properties)) {
|
|
500
|
-
if (
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
// Leave as-is, will fail validation
|
|
502
|
+
if (!(name in coerced))
|
|
503
|
+
continue;
|
|
504
|
+
const value = coerced[name];
|
|
505
|
+
if (value === null || value === undefined)
|
|
506
|
+
continue;
|
|
507
|
+
if (prop.type === 'array' && !Array.isArray(value)) {
|
|
508
|
+
if (typeof value === 'object') {
|
|
509
|
+
// Single object → wrap in array
|
|
510
|
+
coerced[name] = [value];
|
|
511
|
+
changed = true;
|
|
512
|
+
}
|
|
513
|
+
else if (typeof value === 'string') {
|
|
514
|
+
// JSON string → try parsing
|
|
515
|
+
try {
|
|
516
|
+
const parsed = JSON.parse(value);
|
|
517
|
+
if (Array.isArray(parsed)) {
|
|
518
|
+
coerced[name] = parsed;
|
|
519
|
+
changed = true;
|
|
519
520
|
}
|
|
520
521
|
}
|
|
522
|
+
catch {
|
|
523
|
+
// Leave as-is, will fail validation
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
else if (prop.type === 'object' && typeof value === 'string') {
|
|
528
|
+
// JSON-stringified object → try parsing. Some providers (Gemini Flash
|
|
529
|
+
// via OpenAI compat, etc.) ship deeply-nested object args as strings.
|
|
530
|
+
try {
|
|
531
|
+
const parsed = JSON.parse(value);
|
|
532
|
+
if (parsed !== null && typeof parsed === 'object' && !Array.isArray(parsed)) {
|
|
533
|
+
coerced[name] = parsed;
|
|
534
|
+
changed = true;
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
catch {
|
|
538
|
+
// Leave as-is, will fail validation
|
|
521
539
|
}
|
|
522
540
|
}
|
|
523
541
|
}
|
|
@@ -706,29 +706,7 @@ export function createInteractiveFlowTool(handler) {
|
|
|
706
706
|
inputSchema: INTERACTIVE_FLOW_INPUT_SCHEMA,
|
|
707
707
|
execute: async (input) => {
|
|
708
708
|
try {
|
|
709
|
-
|
|
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);
|
|
709
|
+
const validation = validateFlow(input.flow);
|
|
732
710
|
if (!validation.ok) {
|
|
733
711
|
const summary = validation.errors
|
|
734
712
|
.map((e) => `[${e.code}]${e.nodeId ? ` (node '${e.nodeId}')` : ''} ${e.message}`)
|
|
@@ -738,11 +716,7 @@ export function createInteractiveFlowTool(handler) {
|
|
|
738
716
|
error: `Interactive flow validation failed:\n${summary}`,
|
|
739
717
|
};
|
|
740
718
|
}
|
|
741
|
-
|
|
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);
|
|
719
|
+
const result = await handler(input);
|
|
746
720
|
if (validation.warnings.length > 0) {
|
|
747
721
|
result.warnings = [...(result.warnings ?? []), ...validation.warnings];
|
|
748
722
|
}
|