AI Zone Admin Forum Add your forum

NEWS: survey on 3000 US and UK consumers shows it is time for chatbot integration in customer service!read more..

outputmacro with argument as Array


I’m trying to override the random function of ChatScript.
To do that, I thought to do something like that :

s: (shuffle)
$response [sortie 1] [sortie 2] [sortie 3] [sortie 4]

outputmacro: ^order_output($_arg)
^log(OUTPUT_ECHO $_arg)

But it looks like $$response is already one randomed output.
If I send the randomed selection as below, I have a compilation error:
  *** Error- Function ^order_output wrong argument count 1 expected 4 given

s: (shuffle)
order_output([sortie 1] [sortie 2] [sortie 3] [sortie 4]

So, how can i send the multiple responses available to the function.
I can’t set a fix number of argument because there will be multiple rules using this function.



  [ # 1 ]

I would use a JSON array as the argument.
If the various items are single words or could be easily separated by a single character then you could join them into a single string and then use ^burst() to split it apart.
Alternatively you can use fact sets, but care should be taken over them because there is a limited set of them. You can also pass the criteria (e.g. the subject) to the function that would do the ^query().

You can use ^pick() to randomly select an item from an array or fact set.

Or the solution that requires the least amount of coding is to put your output as members of a concept and pass that concept name. ^pick() can randomly select a member from a concept.

A more obscure solution would be to pass just a single parameter to your function, this would be the label of a rule


and that rule definition would have a set of rejoinders with each of the various outputs.

s: TOUT_SORTIE (1=2)
  a: () sortie 1
  a: () sortie 2
  a: () sortie 3
  a: () sortie 4

You can build a list of the rejoinder tags through the ^getrule() function, then pick one and use ^reuse() to generate the output. This has the advantage of being able to handle complex and dynamic output.


  [ # 2 ]

Thanks @Andy.

It works.
I still have a trouble saving a JSON.

Each time I come back in my function, my JSON var ($order) has no key.
I saw in doc that, to save transient var, I have to us ^jsongather, but it just blows up my code, and FAIL the rule.

Any idea?

My Code:

outputmacro: ^order_output($_arg)
^log(OUTPUT_ECHO order_output)
log(OUTPUT_ECHO saved $saved)
$_tag = ^getRULE(TAG ~)
^log(OUTPUT_ECHO creating)
$order = ^jsoncreate(object)

^log(OUTPUT_ECHO creating tag)
jsonobjectinsert($order $_tag 0)
^log(OUTPUT_ECHO tag $order.$_tag )
$order.$_tag += 1
#^jsonobjectinsert($order $_tag $_i)
log(OUTPUT_ECHO tag $order.$_tag )
$saved = ^jsongather($order)



  [ # 3 ]

I updated the jsongather part to

@10 = ^jsongather($order)
enable(write @10

And it works.


  [ # 4 ]

One thing to take care over is the mix of permanent variables and transient JSON facts.

Single dollar variables, e.g. $order, are permanent variables and are saved in the topic file at the end of the volley and initialized with that value at the start of the volley. When that variable references a JSON object then the contents of that variable is a string like jo-1.

Transient facts are deleted at the end of the volley. JSON is managed as facts with a special naming convention, like jo-tnn and ja-tnn (t for transient), but when those facts are automatically deleted it doesn’t mean that any variables that reference those JSON objects are cleared.

The upshot is that $order can be saved to your topic file with a string that looks like a JSON object reference, but that underlying object doesn’t exist, or worse, it exists but points to something else.

During code reviews of my team then any-one mixing up permanent variables/transient facts or transient variables/permanent facts is a red flag.


  [ # 5 ]

you can also use ^jsoncopy to make a permanent copy of a transient structure. THen you dont have to use ^jsongather


  login or register to react