Document Context Modifiers
This commit is contained in:
parent
4a4ccdb603
commit
1c60ccf14a
4 changed files with 111 additions and 0 deletions
|
@ -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.
|
7
examples/contextModifiers/dontBeNegative.js
Normal file
7
examples/contextModifiers/dontBeNegative.js
Normal 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)
|
72
examples/contextModifiers/notes.md
Normal file
72
examples/contextModifiers/notes.md
Normal 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.
|
23
examples/contextModifiers/reimplementAuthorsNote.js
Normal file
23
examples/contextModifiers/reimplementAuthorsNote.js
Normal 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)
|
Reference in a new issue