From 7ef296d43ab7727ec12d2eee3a9aba7fce53ea68 Mon Sep 17 00:00:00 2001 From: Rebecca Turner Date: Mon, 2 Jun 2025 03:54:10 -0400 Subject: [PATCH] Feature: Allow tools to accept arrays of values as an array (#4085) Previously, a tool that that registered itself as having an array parameter had each element of the array registered as a variable, but it did not register the array parameter itself. This meant that it was only really useful with fixed length arrays. This patch adds a variable for the array itself that lives alongside the existing args. I don't expect this to have any backward compatiblity concerns. Repro: ```stscript // this requires lalib to function | /let key=schema { "$schema": "http://json-schema.org/draft-04/schema#", "type": "string", "properties": { "example": { "type": "array", "contains": { "type": "string" } } }, "required": [ "example" ] } || /tools-register name=YourFunc description="filler" parameters={{var::schema}} {: /let ex {: /try {: /return {{var::arg.example}} :} :}() | /= ex.isException | /if rule=not left={{pipe}} else={: /console-log {{var::ex}} :} {: /console-log "arg.example: {{var::arg.example}}" | /foreach {{var::arg.example}} {: /console-log "#{{var::index}}: {{var::item}}" :} :} | /try {: /return {{var::arg.example.0}} :} | /console-log "arg.example.0: {{pipe}}" | /try {: /return {{var::arg.example.1}} :} | /console-log "arg.example.1: {{pipe}}" | /try {: /return {{var::arg.example.2}} :} | /console-log "arg.example.2: {{pipe}}" | /try {: /return {{var::arg.example.3}} :} | /console-log "arg.example.3: {{pipe}}" | :} || /let key=params { "example": [ "test1", "test2", "test3" ] } | /tools-invoke parameters={{var::params}} YourFunc ``` Currently produces: ``` [/console-log] arg.example: {"isException":true,"exception":"No such variable: \"arg.example\""} [/console-log] arg.example.0: {"isException":false,"result":"test1"} [/console-log] arg.example.1: {"isException":false,"result":"test2"} [/console-log] arg.example.2: {"isException":false,"result":"test3"} [/console-log] arg.example.3: {"isException":true,"exception":"No such variable: \"arg.example.3\""} ``` With this patch it produces: ``` [/console-log] arg.example: ["test1","test2","test3"] [/console-log] #0: test1 [/console-log] #1: test2 [/console-log] #2: test3 [/console-log] arg.example.0: {"isException":false,"result":"test1"} [/console-log] arg.example.1: {"isException":false,"result":"test2"} [/console-log] arg.example.2: {"isException":false,"result":"test3"} [/console-log] arg.example.3: {"isException":true,"exception":"No such variable: \"arg.example.3\""} ``` --- public/scripts/tool-calling.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/public/scripts/tool-calling.js b/public/scripts/tool-calling.js index b19f6496e..0e7bc4a17 100644 --- a/public/scripts/tool-calling.js +++ b/public/scripts/tool-calling.js @@ -60,6 +60,9 @@ function assignNestedVariables(scope, arg, prefix) { Object.entries(arg).forEach(([key, value]) => { const newPrefix = `${prefix}.${key}`; if (typeof value === 'object' && value !== null) { + if (Array.isArray(value)) { + scope.letVariable(newPrefix, JSON.stringify(value)); + } assignNestedVariables(scope, value, newPrefix); } else { scope.letVariable(newPrefix, value);