Document Context Modifiers

This commit is contained in:
Andrew Cantino 2020-09-19 21:34:29 -07:00
parent 4a4ccdb603
commit 1c60ccf14a
4 changed files with 111 additions and 0 deletions

View file

@ -29,6 +29,9 @@ You can modify the quests property to change the quests of the adventure mid gam
### Input Modifier ### Input Modifier
Called each time the player gives an input and has the opportunity to modify that input. Called each time the player gives an input and has the opportunity to modify that input.
### Context Modifier
Called each time the AI model is about to receive input and has the opportunity to modify that input (by up to a 75% [edit distance](https://en.wikipedia.org/wiki/Levenshtein_distance) change).
### Output Modifier ### Output Modifier
Called each time the model generates an output and has the opportunity to modify that output. Called each time the model generates an output and has the opportunity to modify that output.
@ -48,3 +51,9 @@ The `state` variable can be used to store information that's persistent across f
### Console ### Console
`console.log("Some message")` will log messages that you can see in the scripting console `console.log("Some message")` will log messages that you can see in the scripting console
### Info
`info` contains some useful values, depending on which modifier you're in.
All modifiers have access to `info.actionCount`, the number of actions in the adventure so far.
When in a Context Modifier, `info.memoryLength` and `info.maxChars` are also set, indicating the length of the memory portion of text (if any), and the total allowed length of the context after which it will be truncated.

View file

@ -0,0 +1,7 @@
const modifier = (text) => {
// This will always result in a shorter string, so no need to truncate it.
return { text: text.replace(/ not /gi, ' ') }
}
// Don't modify this part
modifier(text)

View file

@ -0,0 +1,72 @@
# Notes
## Input Modifier
```js
const modifier = (text) => {
state.notes = state.notes || []
if (text.match(/> You note:/i)) {
const note = text.replace(/> You note: ?/i, '').trim()
state.notes.push({
pattern: history.map(({text}) => text).join('').split("\n").pop(),
note,
actionCount: info.actionCount,
})
state.message = `Noted: ${note}`
text = ''
} else {
delete state.message
}
return {text}
}
// Don't modify this part
modifier(text)
```
Set a note by typing `note: ` when in Do mode. It will be tagged to whatever the most recent line of text is, appearing below it to the AI, but not visible to the user.
## Content Modifier
```js
// info.memoryLength is the length of the memory section of text. text.slice(0, info.memoryLength) will be the memory.
// info.maxChars is the maximum length that text can be. The server will truncate text to this length.
// info.actionCount is the number of actions in this adventure.
const modifier = (text) => {
state.notes = state.notes || []
const memory = text.slice(0, info.memoryLength || 0)
let context = info.memoryLength ? text.slice(info.memoryLength + 1) : text
// Assumes that the notes are sorted from oldest to newest.
state.notes = state.notes.filter(({ pattern, note, actionCount }) => {
if (actionCount > info.actionCount) {
// The user must have hit undo, removing this note.
return false
}
const index = context.indexOf(pattern)
if (index >- 1) {
context = [context.slice(0, index + pattern.length), "\n", note, context.slice(index + pattern.length)].join('')
return true
} else {
// Only keep ones that were found, otherwise they must have moved out of the history window.
return false
}
})
// Make sure the new context isn't too long, or it will get truncated by the server.
context = context.slice(-(info.maxChars - info.memoryLength))
const finalText = [memory, context].join("\n")
return { text: finalText }
}
// Don't modify this part
modifier(text)
```
You can debug this by viewing what the model received in the Scenario Script page. It's the little brain icon in the upper-right.

View file

@ -0,0 +1,23 @@
// Checkout the repo examples to get an idea of other ways you can use scripting
// https://github.com/AIDungeon/Scripting/blob/master/examples
// info.memoryLength is the length of the memory section of text.
// info.maxChars is the maximum length that text can be. The server will truncate the text you return to this length.
// This modifier re-implements Author's Note as an example.
const modifier = (text) => {
const memory = info.memoryLength ? text.slice(0, info.memoryLength) : ''
const context = info.memoryLength ? text.slice(info.memoryLength + 1) : text
const lines = context.split("\n")
if (lines.length > 2) {
const authorsNote = "Everyone in this story is an AI programmer."
lines.splice(-3, 0, `[Author's note: ${authorsNote}]`)
}
// Make sure the new context isn't too long, or it will get truncated by the server.
const combinedLines = lines.join("\n").slice(-(info.maxChars - info.memoryLength))
const finalText = [memory, combinedLines].join("")
return { text: finalText }
}
// Don't modify this part
modifier(text)