Initial commit: AI Dungeon clone (FastAPI backend + React frontend)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KFsGHju9szibJJa2YJcdbg
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
# Phase 4 — Scripting (AI Dungeon-compatible JavaScript)
|
||||
|
||||
**Goal:** real AI Dungeon scripts import and run: the three modifier hooks, persistent `state`,
|
||||
and the scripting API surface.
|
||||
|
||||
## JS runtime
|
||||
|
||||
- [x] Embed a JS engine in Python: **quickjs** (preferred; check Windows wheel availability at
|
||||
implementation time; fallback: py-mini-racer, or Node subprocess as last resort).
|
||||
- [x] Sandbox matching AI Dungeon's documented limits: each hook runs **isolated**, **16 MB
|
||||
memory cap**, **2-second timeout**; no filesystem/network/process access; script errors
|
||||
captured and surfaced in the UI, never crash a turn.
|
||||
|
||||
## AI Dungeon scripting model (compatibility target)
|
||||
|
||||
*(Per official docs: help.aidungeon.com/faq/how-do-i-write-scripts-and-use-scripting)*
|
||||
|
||||
Three lifecycle hooks — `onInput`, `onModelContext`, `onOutput`. Each script defines a modifier
|
||||
and **must call it as its last line**:
|
||||
|
||||
```javascript
|
||||
const modifier = (text) => {
|
||||
// script logic
|
||||
return { text, stop }
|
||||
}
|
||||
modifier(text)
|
||||
```
|
||||
|
||||
- **onInput** — modifies player input before context construction.
|
||||
- **onModelContext** — modifies the assembled text sent to the model.
|
||||
- **onOutput** — modifies the model output before it is shown/stored.
|
||||
- **Shared Library** — code prepended to all three slots.
|
||||
|
||||
Return contract:
|
||||
- [x] `{ text, stop }`; `stop: true` from onInput prevents the AI call.
|
||||
- [x] Empty-string `text` from onInput/onOutput → user-facing error (replicate this behavior).
|
||||
|
||||
Globals provided (exact names from docs):
|
||||
|
||||
- [x] `text` — hook input (player input / context / AI response respectively).
|
||||
- [x] `state` — persisted per adventure across turns (`Adventure.script_state`); includes
|
||||
`state.memory`, `state.message` (shown as a UI notice), `state.placeholders`.
|
||||
- [x] `state.memory` slots: `context` (prepended to context), `authorsNote` (near end, before
|
||||
latest response), `frontMemory` (inserted right after the player's input).
|
||||
- [x] `history` — array of recent actions: `{ text, rawText, type }`.
|
||||
- [x] `storyCards` — array of `{ id, keys, entry, type }`, backed by the adventure's story cards.
|
||||
- [x] Story card functions: `addStoryCard(keys, entry, type)` → index (or `false` on duplicate),
|
||||
`updateStoryCard(index, keys, entry, type)` and `removeStoryCard(index)` → throw if absent.
|
||||
- [x] Legacy aliases for older scripts: `worldInfo` / `worldEntries`, `addWorldEntry`,
|
||||
`updateWorldEntry`, `removeWorldEntry` mapped onto the storyCards implementation.
|
||||
- [x] `info` — `{ actionCount, characterNames, memoryLength, maxChars }`.
|
||||
- [x] `log(message)` / `console.log` — captured per turn, shown in a script log panel.
|
||||
|
||||
## Pipeline integration
|
||||
|
||||
```
|
||||
player input → INPUT modifier → format & store
|
||||
context build → CONTEXT modifier → (snapshot includes pre- and post-script versions in Insights)
|
||||
AI response → OUTPUT modifier → store & render
|
||||
```
|
||||
|
||||
- [x] Insights (Phase 3) extended: show context before vs after the context modifier (diff view),
|
||||
and script log output per turn.
|
||||
|
||||
## Script management UI
|
||||
|
||||
- [x] Scripts page: create/edit scripts with a code editor (CodeMirror), one tab per slot
|
||||
(Library / Input / Context / Output), description field.
|
||||
- [x] Attach scripts to scenarios; adventures inherit at creation. Enable/disable per adventure.
|
||||
- [x] Test-run a script against sample text without an AI call.
|
||||
|
||||
## Import / Export
|
||||
|
||||
- [x] **Scripts**: export/import as JSON bundle `{ name, library, input, context, output }` and
|
||||
as raw `.js` files per slot (matching how AI Dungeon scripts circulate — paste or file).
|
||||
- [x] **Scenarios**: export/import JSON including prompt, memory, author's note, story cards,
|
||||
and attached scripts. Accept AI Dungeon scenario export JSON where format is known;
|
||||
map fields best-effort and report anything unmapped.
|
||||
|
||||
## Exit criteria
|
||||
|
||||
Paste a real AI Dungeon script (e.g. a simple input modifier + state counter + world entry
|
||||
manipulation) and it runs unmodified across turns; state persists; export a scenario with scripts,
|
||||
re-import it into a fresh database, and play it.
|
||||
Reference in New Issue
Block a user