ChatScript System Variables and Engine-defined Concepts

May 30, 2020 · View on GitHub

Copyright Bruce Wilcox, gowilcox@gmail.com www.brilligunderstanding.com
Revision 5/30/2020 cs10.4

Engine-defined concepts

In addition to concepts defined in script files, the system automatically defines a bunch of dictionary-based sets as well as dynamically computed concept members.

setdescription
~web_urlword is a web url
~email_urlword is an email address
~kindergartenword learned early in life
~grade1_2word learned in these grades
~grade3_4word learned in these grades
~grade_5-6word learned in these grades. Unmarked words are learned even later
~utf8word has nonascii characters
~daynumberword could be a number of a day in a month
~yearnumberword could be the number of a recent year
~dateinfophrase is month day year of some kind
~kelvintemperature marker
~celciustemperature marker
~fahrenheittemperature marker
~twitter_nametwitter user name
~hashtag_labeltwitter topic reference

Interjections, "discourse acts", and concept sets

Some words and phrases have interpretations based on whether they are at sentence start or not. E.g., good day, mate and It is a good day are different for good day.

Likewise sure and I am sure are different.

Words that have a different meaning at the start of a sentence are commonly called interjections.

In ChatScript these are defined by the livedata/interjections.txt file. In addition, the file augments this concept with "discourse acts", phrases that are like an interjection. All interjections and discourse acts map to concept sets, which come thru as the user input instead of what they wrote.

For example yes and sure and of course are all treated as meaning the discourse act of agreement in the interjections file. So you don’t see yes, I will go coming out of the engine.

The interjections file will remap that to the sentence ~yes, breaking off that into its own sentence, followed by I will go as a new sentence.

These generic interjections (which are open to author control via interjections.txt) are:

interjectiondescription
~yes
~no
~emomaybe
~emohello
~emogoodbye
~emohowzit
~emothanks
~emolaugh
~emohappy
~emosad
~emosurprise
~emomisunderstand
~emoskeptic
~emoignorance
~emobeg
~emobored
~emopain
~emoangry
~emocurse
~emodisgust
~emoprotest
~emoapology
~emomutual

Because all interjections at the start of a sentence are broken off into their own sentence, this kind of pattern does not work:

u: (~yes _*)

You cannot capture the rest of the sentence here, because it will be part of the next sentence instead. This means interjections act somewhat differently from other concepts.

If you use a word in a pattern which may get remapped on input, the script compiler will issue a warning. Likely you should use the remapped name instead.

The following concepts are triggered by exactly repeating either the chatbot or oneself (to a repeat count of how often repeated). Repeats are within a recency window of about 20 volleys.

conceptdescription
~repeatme
~repeatinput1
~repeatinput2
~repeatinput3
~repeatinput4
~repeatinput5
~repeatinput6

POS (Part of Speech) Tags

Words will have pos-tags attached, specififying both generic and specific tag attributes, eg., ~noun, ~noun_singular.

Generic Specifics

nounsdescription
~noun
~noun_singular
~noun_plural
~noun_proper_singular
~noun_proper_plural
~noun_gerund
~noun_number
~noun_infinitive
~noun_omitted_adjective
verbsdescription
~verb
~verb_present
~verb_present_3ps
~verb_infinitive
~verb_present_participle
~verb_past
~verb_past_participle
~aux_verb
~aux_verb_present
~aux_verb_past
~aux_verb_future
~aux_verb_tenses
~aux_be
~aux_have
~aux_do

Auxilliary verbs are segmented into normal ones and special ones. Normal ones give their tense directly. Special ones give their root word. The tense of the be/have/do verbs can be had via ^properties() and testing for verb tenses

adjectivesdescription
~adjective
~adjective_normal
~adjective_number
~adjective_noun
~adjective_participle
adjectives in comparative formdescription
~more_form
~most_form
~adverb
~adverb_normal
adverbs in comparative formdescription
~more_form
~most_form
~pronoun
~pronoun_subject
~pronoun_object
~conjunction_bits
~conjunction_coordinate
~conjunction_subordinate
~determiner_bits
~determiner
~pronoun_possessive
~predeterminer
~possessivecovers ' and 's at end of word
~to_infinitive"to" when used before a noun infinitive
~preposition
~particle
free-floating preposition tied to idiomatic verb
~comma
~quotecovers ' and " when not embedded in a word
~parencovers opening and closing parens
~foreign_wordsome unknown word
~there_existentialthe word there used existentially

In addition to normal generic kinds of pos tags, words which are serving a pos-tag role different from their putative word type are marked as members of the major tag they act as part of. E.g,

description
~noun_gerundverb used as a ~noun
~noun_infinitiveverb used as a ~noun
~noun_omitted_adjectivean adjective used as a collective noun (eg the beautiful are kind)
~adjectival_nounnoun used as adjective like bank "bank teller"
~adjective_participleverb participle used as an adjective

For ~noun_gerund in I like swimming the verb gerund swimming is treated as a noun (hence called noun-gerund) but retains verb sense when matching keywords tagged with part-of-speech (i.e., it would match swim~v as well as swim~n).

Additionally, there is

description
~numberis not a part of speech, but is comprise of ~noun_number (a normal number value like 17 or seventeen)
~adjective_numberalso a normal numeral value and also ~placenumber) like first.
~integer
~float
~positiveinteger
~negativeinteger
~modelnumbernot a true number, but a word with both alpha and numeric
~filenamelooks like a filename with extension

To can be a preposition or it can be special. When used in the infinitive phrase To go, it is marked ~to_infinitive and is followed by ~noun_infinitive.

description
~verb_infinitiverefers to a match on the infinitive form of the verb (I hear John sing or I will sing).
~There_existentialrefers to the use of where not involving location, meaning the existence of, as in There is no future.
~Particlerefers to a preposition piece of a compound verb idiom which allows being separated from the verb. If you say I will call off the meeting, call_off is the composite verb and is a single token. But if you split it as in I will call the meeting off, then there are two tokens. The original form of the verb will be call and the canonical form of the verb will be call_off, while the free-standing off will be labeled ~particle.
~verb_presentwill be used for normal present verbs not in third person singular like I walk and
~verb_present_3pswill be used for things like he walks
~possesiverefers to ‘s and that indicate possession, while possessive pronouns get their own labeling ~pronoun_possessive.
~pronoun_subjectis a pronoun used as a subject (like he)
~pronoun_objectrefers to objective form like him

Individual words serve roles in the parse of a sentence, which are retrievable. These include:

description
~mainsubject
~mainverb
~mainindirect
~maindirect
~subject2
~verb2
~indirectobject2
~object2
~subject_complementadjective object of sentence involving linking verb
~object_complement2ndary noun or infinitive verb filling modifying mainobject or object2
~conjunct_noun
~conjunct_verb
~conjunct_adjective
~conjunct_adverb
~conjunct_phrase
~conjunct_clause
~conjunct_sentence
~postnominalAdjectiveadjective occuring AFTER the noun it modified
~reflexivereflexive pronouns
~not
~addressnoun used as addressee of sentence
~appositivenoun restating and modifying prior noun
~absolutephrasespecial phrase describing whole sentence
~omittedtimeprepmodified time word used as phrase but lacking preposition (Next tuesday I will go)
~phrasea prepositional phrase start (except
~clausea subordinate clause start
~verbala verb phrase

and special concepts: | ~capacronym | word is in all caps (and &) and is likely an acronym | ~emoji | word starts and end with : and represents an emoji

System Variables

The system has some predefined variables which you can generally test and use but not normally assign to. These all begin with % . Ones that are reasonable to set are written in bold underline. Boolean values are always 1 or null on returns. 1 or 0 if you are setting them.

Date & Time & Numbers

variabledescription
%dateone or two digit day of the month
%daySunday, etc
%daynumber1-7 where 1 = Sunday
%fulltimeseconds representing the current time and date (Unix epoch time)
%hour0-23
%timenumberscompletely consistent full time info in numbers that you can do
_0 = ^burst(%timenumbers)to get _0 =seconds (2digit)
_1=minutes (2digit)
_2=hours (2digit)
_3=dayinweek(0-6 Sunday=0)
_4=dateinmonth (1-31)
_5=month(0-11 January=0)
_6=year.
You need to get it simultaneously if you want to do accurate things with current time, since retrieving %hour %minute separately allows time to change between calls
%leapyearboolean if current year is a leap year
%daylightsavingsboolean if current within daylight savings
%minute0-59
%month1-12 (January = 1)
%monthnameJanuary, etc
%second0-59
%volleytimenumber of seconds of computation since volley input started
%timehh:mm in military 24-hour time
%zulutime2016-07-27T11:38:35.253Z
%week1-5 (week of the month)
%yeare.g., 2011
%randget a random number from 1 to 100 inclusive

Time and date information are normally local, relative to the system clock of the machine CS is running on. See $cs_utcoffset for adjusting time based on relationship to utc (e.g your server is in Virginia and you are in Colorado).

User Input

variabledescription
%botcurrent bot responding
%revisedinputBoolean is current input from ^input not direct from user
%commandBoolean was the user input a command
%foreignBoolean is bulk of the sentence composed of foreign words
%impliedyouBoolean was the user input having you as implied subject
%inputthe count of the number of volleys this user has made ever
%ipip address supplied
%languagecurrent dictionary language
%lengththe length in tokens of the current sentence
%moreBoolean is there another sentence after this
%morequestionBoolean is there a ? or question word in the pending sentences
%originalinputall sentences user passed into volley, before adjusted in any way except OOB data is stripped off
%originalsentencethe current sentence after tokenization but before any adjustments
%parsedBoolean was current input parsed successfully
%questionBoolean was the user input a question - same as ? in a pattern
%quotationBoolean is current input a quotation
%sentenceBoolean does it seem like a sentence (subject/verb or command)
%tableinputcurrent line being executed in a table expansion during script compilation
%tensepast , present, or future simple tense (present perfect is a past tense)
%useruser login name supplied
%userfirstlinevalue of %input that is at the start of this conversation start
%userinputBoolean is the current input from the user (vs the chatbot)
%voiceactive or passive on current input

Chatbot Output

variabledescription
%inputrejoinderrule tag of any pending rejoinder for input or null if none pending
%lastoutputthe text of the last generated response for the current volley - always null across volleys
%lastquestionBoolean did last output end in a ?
%outputrejoinderrule tag if system set a rejoinder for its current output or 0
%responsenumber of committed responses that have been generated for this sentence (see Advanced User- Advanced Output: Committed Responses

System variables

variabledescription
%allBoolean is the :all flag on? (:all to set)
%documentBoolean is :document running
%factNumeric value most recent fact id
%freetextkb of available text space
%freedictnumber of unused dictionary words
%freefactnumber of unused facts
%maxmatchvariableshighest number of match variables, currently 20
%maxfactsetshighest number of @factsets, currently 20
%hostname of the current host machine or "local"
%regressionBoolean is the regression flag on
%serverBoolean is the system running in server mode
%ruleget a tag to the current executing rule. Can be used in place of a label
%topicname of the current "real" topic . if control is currently in a topic or called from a topic which is not system or nostay, then that is the topic. Otherwise the most recent pending topic is found
%actualtopicliterally the current topic being processed (system or not)
%traceNumeric value of the trace flag (:trace to set)
%httpresponsereturn code of most recent ^jsonopen call
%pidLinux process id or 0 for other systems
%restartYou can set and retrieve a value here across a system restart.
%timeoutBoolean tells if a timeout has happened, based on the timelimit command line parameter
%lastcurltimeTime Analysis: Name Look up: Host/proxy connect: App(SSL) connect: Pretransfer: Total Transfer:
%crosstalk4k buffer in server visible between users to pass data back and forth
%crosstalk14k buffer in server visible between users to pass data back and forth

Build data

variabledescription
%dictdate/time the dictionary was built
%enginedate/time the engine was compiled
%osos invovled (linux windows mac ios)
%scriptdate/time build1 was compiled
%versionengine version number

You actually can assign to any of them. This will override them and make them return what you tell them to and is a particularly BAD thing to do if this is running on a server since it affects all users (unless you reset the variable at the end of the volley. Assigning a period to a variable resets it).

Typically one does this as a temporary assignment in a #! comment line to set up conditions for testing using :verify.

Making them return a new value is NOT the same thing as making the engine have a different value. Unless the variable is marked as settable, setting a value affects only the value returned by a future call to the system variable. It does not change engine values the variable is meant to reflect.

Control Over Input

The system can do a number of standard processing on user input, including spell correction, proper-name merging, expanding contractions etc. This is managed by setting the user variable $cs_token.

The default one that comes with Harry is:

$cs_token = #DO_INTERJECTION_SPLITTING | 
            #DO_SUBSTITUTE_SYSTEM |
            #DO_NUMBER_MERGE | 
            #DO_PROPERNAME_MERGE | 
            #DO_SPELLCHECK |
            #DO_PARSE

The #signals a named constant from the dictionarySystem.h file. One can set the following:

These enable various LIVEDATA files to perform substitutions on input:

flagdescription
#DO_ESSENTIALSperform LIVEDATA/systemessentials which mostly strips off trailing punctuation and sets corresponding flags instead
#DO_SUBSTITUTESperform LIVEDATA/substitutes
#DO_CONTRACTIONSperform LIVEDATA/contractions, expanding contractions
#DO_INTERJECTIONSperform LIVEDATA/interjections, changing phrases to interjections
#DO_BRITISHperform LIVEDATA/british, respelling brit words to American
#DO_SPELLINGperforms the LIVEDATA/spelling file (manual spell correction)
#DO_TEXTINGperforms the LIVEDATA/texting file (expand texting notation)
#DO_SUBSTITUTE_SYSTEMdo all LIVEDATA file expansions
#DO_INTERJECTION_SPLITTINGbreak off leading interjections into own sentence
#$DO_NUMBER_MERGEmerge multiple word numbers into one (four and twenty)
#$DO_PROPERNAME_MERGEmerge multiple proper name into one (George Harrison)
#DO_DATE_MERGEmerge month day and/or year sequences (January 2, 1993)
#JSON_DIRECT_FROM_OOBasking the tokenizer to directly process OOB data. See ^jsonparse in JSON manual.

The contents of the files are pairs of tokens per line. Left is the word to replace and right is the replacement. When multiple words are involved, the left side uses underscores to represent this and the right side uses +. If the right side is missing, it means just delete.

If any of the above items affect the input, they will be echoed as values into %tokenFlags so you can detect they happened. The next changes do not echo into %tokenFlags and relate to grammar of input:

flagdescription
DO_POSTAGallow pos-tagging (labels like ~noun ~verb become marked)
DO_PARSEallow parser (labels for word roles like ~main_subject)
DO_CONDITIONAL_POSTAGperform pos-tagging only if all words are known. Avoids wasting time on foreign sentences in particular
NO_CONDITIONAL_IDIOMwill not perform substitutions in the dictionary which are considered conditional idioms
NO_ERASEwhere a substitution would delete a word entirely as junk, don't
DO_SPLIT_UNDERSCOREShappens after all other input tokenization and adjustments except number merge, and separates words that have been conjoined either because the dictionary has them (credit_card) or because they were merged by proper name merging, or by substitution. The result is only words without underscores (excluding number words like five_thousand_and_four
MARK_LOWERif a word is considered a proper name in CS and is marked as an upper case word, this will force it to perform any markings for its lower case form as well. Sometimes users type stuff in upper case that really should be lower

Normally the system tries to outguess the user, who cannot be trusted to use correct punctuation or casing or spelling. These block that:

flagdescription
STRICT_CASINGexcept for 1st word of a sentence, assume user uses correct casing on words
NO_INFER_QUESTIONthe system will not try to set the QUESTIONMARK flag if the user didn't input a ? and the structure of the input looks like a question
DO_SPELLCHECKperform internal spell checking
ONLY_LOWERCASEforce all input (except "I") to be lower case, refuse to recognize uppercase forms of anything
NO_IMPERATIVE
NO_WITHINdon't match fragments within a composite word
NO_SENTENCE_ENDdo not break input into sentences

Normally the tokenizer breaks apart some kinds of sentences into two. These prevent that:

flagdescription
NO_COLON_ENDdon't break apart a sentence after a colon
NO_SEMICOLON_ENDdon't break apart a sentence after a semi-colon
UNTOUCHED_INPUTif set to this alone, will tokenize only on spaces, leaving everything but spacing untouched
LEAVE_QUOTEif input is found within " " it will become a single token exactly as it is seen. W/o Leave_Quote, it is converted into a word without quotes and using underscores instead of spaces. So "My Fair Lady" becomes My_Fair_Lady, which would match a movie title if you had one, unlike My Fair Lady becoming the resulting token and unrecognized
SPLIT_QUOTEif input is found within " " the quotes will be removed.

Note

you can change $cs_token on the fly and force input to be reanalyzed via ^retry(SENTENCE). I do this when I detect the user is trying to give his name, and many foreign names might be spell-corrected into something wrong and the user is unlikely to misspell his own name.

Just remember to reset $cs_token back to normal after you are done. Here is one such way, assuming $stdtoken is set to your normal tokenflags in your bot definition outputmacro:

#! my name is Rogr
s: (name is _*)

    if ($cs_token == $stdtoken)
        {
        $cs_token = #DO_INTERJECTION_SPLITTING |
                    #DO_SUBSTITUTE_SYSTEM | #DO_NUMBER_MERGE |
                    #DO_PARSE
        retry(SENTENCE)
        }
    _0 is the name.
    $cs_token = $stdtoken

If you type my name is Rogr into a topic with this, the original input is spell-corrected to my name is Roger, but this will change the $cs_token over to one without spell correction and redo the sentence, which will now come back with my name is Rogr and be echoed correctly, and $cs_token reset.

That's assuming nothing else would run differently and trap the response elsewhere. If you were worried about that, it would be possible for the script to save where it is using ^getrule(tag) and modify your control script to return immediate control to here after input processing if you had changed $cs_token.

Private Substitutions

While in general, substitutions are defined in the LIVEDATA folder, you can define private substititions for your specific bot using the scripting language. You can say

replace: xxx yyyyy

which defines a substitution just like a livedata substitution file. It actually creates a substitution file called private0.txt or private1.txt in your TOPIC folder.

Even then, those substitutions will not be enacted unless you explicitly add to the $cs_token value #DO_PRIVATE, eg

$cs_token = #DO_INTERJECTION_SPLITTING | 
            #DO_SUBSTITUTE_SYSTEM |
            #DO_NUMBER_MERGE | 
            #DO_PROPERNAME_MERGE |
            #DO_SPELLCHECK | 
            #DO_PARSE | 
            #DO_PRIVATE

The left side of the substitution pair is case insensitive (matches either case on input) and can be placed in double-quotes (which converts spaces to underscores internally).

The right side of the substitution pair is case sensitive and can be placed in double-quotes (which converts spaces to plus signs internally).

Similarly while canonical values of words can be defined in LIVEDATA/SYSTEM/canonical.txt, you can define private canonical values for your bots by using the scripting language. You can say:

canon: oh 0 
canon: faster fast

which defines new canonical values for things and creates a file canon0.txt or canon1.txt in your TOPIC folder.

You can optionally add MORE_FORM or MOST_FORM as a 3rd argument, to set those flags for adjectives and adverbs.

If you want to set a canonical pair from a table during compilation, you can use a function to do the same thing (but only 1 pair at a time).

^canon(word canonicalform)

Numeric Substitutions

A special kind of private substitution (equally applicable in regular substitution files) is the numeric substitution.

replace: ?_km kilometers

The ?_ matches a digit number followed immediately by km, like 1.2km and will separate the number and replace the units with the given replacement. The input can be singular or have an 's' like 10.5dollars. And it can be with or without abbreviation periods, like 10kps or 10k.p.s

Apostrophe Substitutions replace

replace: 'xxx  yyy

allows you to split during tokenization any word followed by 'xxx into two words, original sans 'xxx and yyy. eg

replace: 've have

gives "companies've => "companies have".

Replacing to a word with + in it

Normally replace: x y+z will generate 2 words, y and z. If you need a plus in your word, you can escape your 2nd word:

    replace: "black and decker" \BLACK+DECKER

Interchange Variables

The following variables can be defined in a script and the engine will react to their contents.

interchange variabledescription
$cs_tokendescribed extensively above
$cs_responsecontrols automatic handling of outputs to user. By default it consists of `$cs_response = #Response_upperstart
$cs_jsontimeoutseconds before JsonOpen declares a time out failure. If unspecified the default is 300
$cs_crashmsgin server mode, what to say if the server crashes and we return a message to the user. By default the message is Hey, sorry. I forgot what I was thinking about.
$cs_abstractused with :abstract
$cs_looplimitloop() defaults to 1000 iterations before stopping. You can change this default with this
$cs_traceif this variable is defined, then whenever the user's volley is finished, the value of this variable is set to that of :trace and :trace is cleared to 0, but when the user is read back in, the :trace is set to this value. For a server, this means you can perform tracing on a user w/o making all user transactions dump trace data
$cs_control_prename of topic (flag it SYSTEM) to run in gambit mode on pre-pass, set by author. Runs before any sentences of the input volley are analyzed. Good for setting up initial values
$cs_usermessagelimitmax number of message pairs (user input & bot output) saved in topic file
$cs_externaltagname of a topic to use to replace existing internal English pos-parser. See bottom of ChatScript PosParser manual for details
$cs_prepassname of a topic (mark it SYSTEM) to run in responder mode on main volleys, which runs before $cs_control_main and after all of the above and pos-parsing is done. Used to amend preparation data coming from the engine. You can use it to add your own spin on input processing before going to your main control. I use it to, for example, label commands as questions, standardize sentence construction (like if you see me what will you think to assume you see me. What will you think?)
$cs_control_mainname of topic (flag it SYSTEM) to run in responder mode on main volleys, set by author
$cs_control_postname of topic (flag it SYSTEM) to run in gambit mode on post-pass, set by author
$botpromptmessage for console window to label bot output
$userpromptmessage for console window to label user input line
$cs_crashmsgmessage to use if a server crash occurs
$cs_languageif spanish, will adjust spell checking for spanish colloquial
$cs_tokenbits controlling how the tokenizer works. By default when null, you get all bits assumed on. The possible values are in src/dictionarySystem.h (hunt for $token) and you put a # in front of them to generate that named numeric constant
$cs_abstracttopic used by :abstract to display facts if you want them displayed
$cs_prepasstopic used between parsing and running user control script. Useful to supplement parsing, setting the question value, and revising input idioms
$cs_wildcardseparatorwhen a match variable covers multiple words, what should separate them- by default it's a space, but underscore is handy too. Initial system character is space, creating fidelity with what was typed. Useful if _ can be recognized in input (web addresses). Changing to _ is consistent with multi-word representation and keyword recognition for concepts. CS automatically converts _ to space on output, so internal use of _ is normal
$cs_userfactlimithow many of the most recent permanent facts created by the script in response to user inputs are kept for each user. Std default is 100. * means all.
$cs_outputchoicefor regression: forces specific one of a [] [] output choice block - base 0
$cs_responsecontrols some characteristics of how responses are formatted
$cs_randIndexthe random seed for this volley
$cs_utcoffsetif defined, then %time returns current utc time + timezone offset. The offset is usually a simple number, meaning hours, and can have + or - in front of it. It can also be a normal time reference like 02:30 which means plus 2 hours and 30 minutes beyond utc, or -01:30:20 which means 1 hour, 30 minutes, and 20 seconds before utc (as if anyone would use that). The following variables are generated by the system on behalf of scripts
$$db_errorerror message from a postgres failure $$findtext_start - ^findtext return the end normally, this is where it puts the start
$$tcpopen_errorerror message from a tcpopen error
$$documentname of the document being read in document mode
$cs_randindexcurrent value of the random generator value
$cs_botname of the bot currently in use
$cs_loginlogin name of the user
$$csmatch_startstart of found words from ^match
$$csmatch_endend of found words from ^match
$cs_fullfloatif defined, causes the system to generate full float 64-bit precision on outputs, otherwise you get 2 digit precision by default
$cs_botidwhen non-zero creates facts and functions restricted by this bitmask so facts and functions created by other masks cannot be seen. allows you to separate facts and functions per bot in a multi-bot environment. During compilation if this is set by a bot: command, then functions created and facts created by tables will be restricted to that owner.
$cs_numbersif defined, causes the system to output numbers in a different language style: french, indian. All other values are english.
$cs_topicretrylimitif defined changes how many times you can pass back RETRY_TOPIC before it fails (current limit is 30)
$$topic_retry_limit_exceededset if topic retry limit is encountered
$cs_topicretrylimitif defined changes how many times you can pass back RETRY_TOPIC before it fails (current limit is 30)
$cs_userhistorylimitif not null, indicates how many volleys back are tracked as what was said by both parties
$cs_saveusedJsonif not null, the only JSON facts CS will write into the user's topic files that are referred to (directly or indirectly) from user variables being saved. (see below)
$cs_proxycredentialsSee ^JSONOPEN in JSON manual
$cs_proxyserverSee ^JSONOPEN in JSON manual
$cs_proxymethodSee ^JSONOPEN in JSON manual
$cs_addresponseprovides a function name hook onto the output q to the user. See below.
$cs_tracepatternUsed by the ^testpattern call to let pattern code request a trace of pattern matching be returned.
$cs_indentlevelcontrols indenting when tracing in ^testpattern. 3 is a good number usually
`$cs_tracetestoutputset to 1 to force tracing in ^testoutput
`$cs_sentences_limitafter this many sentences in volley, cs ignores the rest (default 50)
`$cs_outputlimitGenerating more output than this will report a bug into LOGS/bugs.txt
$cs_summaryAfter volley prints to terminal milliseconds of time used in preparation, rules, postprocessing
$cs_showtimeAfter volley prints to terminal milliseconds of time used

$cs_saveusedJson exists as a kind of garbage collection. Nowadays most facts will come from JSON data either from a website or created in script. But keeping on top of deleting obsolete JSON may be overlooked. When this variable is non-null, ChatScript will automatically destroy any JSON fact that cannot trace a JSON fact path back to some user variable. Variables that have as values the name of a JSON object or array automatically protect all JSON facts underneath. JSON references merely within some text string will not protect anything, nor will references from some other non-JSON fact.

$cs_addresponse names a function of 2 arguments that will be called when CS wants put text into the output queue of the user. The first argument will be what CS wants to output. The second is the rule tag that generated this output. If the function returns a failure code, the message will be aborted and not put into the queue. If the function returns a text value (not null) then that message will replace what was intended to go to the user.