Find a file
Ivan Kolos 35a8e28523
Treat a missing or unrecognised story image mode as Text Only (#554)
## Summary

A story with no saved image mode was shown as **Text Only** in Story
Settings, but the turn pipeline read the same missing value as Agent
Mode (`?? 'agentic'` in `ActionInput`). So a story whose settings said
"No images will be generated" generated images on every turn, which
matches a report of a story "set to Text Only" still producing them.

The missing value is historical data. Stories created before the setting
existed carry none, stories created while the agentic mode was still
called `'auto'` carry a value that no reader recognises (generation
skipped it and Story Settings selected no option), and imports and syncs
carry either one unchanged. Every story either wizard creates today
stores one of the three current modes.

## Changes

- **The mode is checked once, when a story is read.** `mapStory` passes
settings through `readStorySettings` (`utils/storySettings.ts`), which
drops an `imageGenerationMode` that is not `'none'`, `'agentic'` or
`'inline'`, so the story reads as having no mode chosen.
`StorySettings.imageGenerationMode` is then true to its type for every
story in memory. Nothing is written back, so an older export or sync
payload is handled the same way whenever it arrives. Documented in
`persistence.md`.
- **Generation treats no mode as Text Only.** Readers that act on the
mode use `storyImageMode(settings)` (`?? 'none'`), replacing `??
'agentic'` in the pipeline. `ActionInput` reads it once per turn, and
the image step gets it from `ImagePhase` rather than re-reading the
store. The image context and both image phases take a required
`ImageGenerationMode`, so the phase's unreachable `!== 'agentic'` branch
and its skip reason are gone. `generateImagesForNarrative` returns early
for `'none'`, so the service enforces Text Only itself. The older inline
flag is not consulted. Background images keep their own switch.
- **Story Settings stops presenting a default as a choice.** With no
mode, `WritingStyleFields` selects no option and shows: "This story has
no image mode set, or its saved mode isn't recognized. It runs as Text
Only until you choose one." Choosing any option saves it and clears the
hint. The wizards always hold a valid mode and never show it. The option
list is built from `IMAGE_GENERATION_MODES`.

## Behaviour change

Stories with no saved mode that were silently getting automatic images
stop getting them, including stories from before the setting whose only
image field is the old inline flag. Their settings now say so, and
choosing Agent Mode or Inline Mode brings images back.

## Testing

- `utils/storySettings.test.ts`: each valid mode is kept; `'auto'`, an
unknown string, a non-string and `null` are dropped with the rest of the
settings intact; the old inline flag and `null` settings pass through.
`utils/image.test.ts` and `imageUtils.test.ts` cover the no-mode case,
and the slot-agreement tests pass `{ imageGenerationMode: 'agentic' }`
explicitly, since `{}` now means Text Only.
- `npm run check` (0 errors), `npm run lint` (0 errors), `npm test`
(1947 passed).
- Checked in the running app on the first commit, with an image profile
configured: stories with no mode and with `'auto'` show no selection and
the hint, generate no scene images, report the image step as skipped,
and offer no manual image action; choosing Agent Mode generates images
and shows it selected; choosing Text Only selects it and clears the
hint; both wizards show a selected mode and never the hint; a wizard
story created with Text Only stores `"none"`. The review restructure has
not been run in the app yet.

🤖 Generated with [Claude Code](https://claude.com/claude-code)


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Stories with a missing or unrecognized image-generation setting now
run in Text Only mode until a valid mode is selected. The settings panel
shows no preselected option and explains that image generation is off.
* Image generation now consistently respects the story’s saved mode
across writing, streaming, and image requests. Background image
generation remains available even when standard image generation is off.
* Invalid saved image-generation values are ignored, while valid saved
modes are preserved.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 15:07:55 -04:00
.cargo Add Incognito Keyboard option for Android (#467) 2026-08-26 20:45:30 -04:00
.github Add iOS as a build target (#541) 2026-09-27 18:27:49 -04:00
docs Treat a missing or unrecognised story image mode as Text Only (#554) 2026-09-28 15:07:55 -04:00
scripts Route dev/build/release scripts through aube when it installed node_modules (#552) 2026-09-28 14:34:27 -04:00
src Treat a missing or unrecognised story image mode as Text Only (#554) 2026-09-28 15:07:55 -04:00
src-tauri Route dev/build/release scripts through aube when it installed node_modules (#552) 2026-09-28 14:34:27 -04:00
static switched font for logo 2026-01-19 14:48:22 -06:00
third-party-licenses Added harper 2026-01-02 05:08:39 -07:00
.gitattributes Fix CRLF Migrations (#162) 2026-02-22 15:46:59 -05:00
.gitignore Overhaul CI/CD: Node 24, shared release workflows, faster cached builds (#518) 2026-09-16 22:38:32 -04:00
.nvmrc Overhaul CI/CD: Node 24, shared release workflows, faster cached builds (#518) 2026-09-16 22:38:32 -04:00
.prettierrc fix: prettier, eslint, pipeline (#71) 2026-02-06 00:49:36 +01:00
CLAUDE.md Add iOS as a build target (#541) 2026-09-27 18:27:49 -04:00
compileApk.sh Android build hygiene: minSdk 26, lint in CI, resource cleanup (#468) 2026-08-29 21:52:01 -04:00
components.json fix: prettier, eslint, pipeline (#71) 2026-02-06 00:49:36 +01:00
eslint.config.js Validated release script, extracted version arithmetic, lint config fixes (#416) 2026-08-08 19:55:23 +02:00
lefthook.yml Route dev/build/release scripts through aube when it installed node_modules (#552) 2026-09-28 14:34:27 -04:00
LICENSE.md Db rework (#140) (#141) 2026-02-13 17:37:27 +05:30
logo.png switched font for logo 2026-01-19 14:48:22 -06:00
package-lock.json chore: bump version to 0.7.11 2026-09-17 08:23:14 -04:00
package.json chore: bump version to 0.7.11 2026-09-17 08:23:14 -04:00
README.md Add iOS as a build target (#541) 2026-09-27 18:27:49 -04:00
sun4.jpg Use custom icon for android 2026-01-03 07:08:45 -07:00
sun17.jpg Use custom icon for android 2026-01-03 07:08:45 -07:00
sun2022.png Use custom icon for android 2026-01-03 07:08:45 -07:00
svelte.config.js fix: prettier, eslint, pipeline (#71) 2026-02-06 00:49:36 +01:00
tsconfig.json Initial commit 2025-12-30 16:08:22 -07:00
vite.config.js fix: prettier, eslint, pipeline (#71) 2026-02-06 00:49:36 +01:00
vitest.config.ts Validated release script, extracted version arithmetic, lint config fixes (#416) 2026-08-08 19:55:23 +02:00

Aventuras

Interactive fiction with an AI that remembers. Play a text adventure or write collaboratively, on desktop and Android, with any LLM provider you like — cloud or running on your own machine.

Aventuras keeps the story straight: chapters are summarized as you play, a lorebook feeds the right entries into the right scene, an agent tidies that lorebook behind you, and the world state — who is present, where you are, what you carry — is tracked turn by turn.

Highlights

  • Two modes — Adventure, with multiple-choice actions and world tracking; Creative Writing, freeform with AI suggestions. First/second/third person, past or present tense.
  • Any provider — OpenRouter, OpenAI, Anthropic, Google, xAI, Groq, DeepSeek, Mistral, Z.AI, NanoGPT, Chutes, Pollinations, NVIDIA NIM, plus local llama.cpp, LM Studio and Ollama. Streaming, extended thinking, and per-subsystem Agent Profiles so retrieval, classification and narration can each use a different model.
  • Memory that scales — automatic chapter summarization, and a retrieval step that goes and finds what the current scene needs from everything that came before.
  • Lorebook — characters, locations, items, factions, concepts and events, with aliases, secrets, keyword and relevance-based injection, SillyTavern import, and an autonomous agent that consolidates duplicates and fills gaps.
  • The Vault — a cross-story library of reusable characters, lorebooks and scenarios, with a tool-calling assistant that edits them and shows you a diff before anything lands.
  • Every prompt is editable — they are Liquid templates, all of them, in an in-app editor.
  • Images — inline <pic> illustrations, scene backgrounds and character portraits, across nine backends including local ComfyUI and A1111.
  • Writing tools — local grammar checking (Harper/WASM), style analysis for repetition, suggestions that match how you write.
  • Yours to keep — SQLite on your machine, full backup/restore, .avt story export, LAN sync between devices over QR pairing, and an optional translation layer over the whole app.
  • 26 themes, adjustable text size, dialogue highlighting.

Install

Pre-built binaries are on the Releases page:

Platform Download
Windows Aventuras_vX.Y.Z_x64-setup.exe
macOS Aventuras_vX.Y.Z_x64.dmg / _aarch64.dmg
Linux Aventuras_vX.Y.Z_amd64.deb / .AppImage, or _x86_64.rpm
Android Aventuras_vX.Y.Z.apk
iOS Aventuras_vX.Y.Z_ios-arm64-unsigned.ipa (sideload; unsigned)

No API keys in config files — providers are set up in the app, under Settings → API Settings.

Build from source

Requires the Node.js version in .nvmrc, the latest stable Rust, (for Android) the Android SDK, NDK r27d and JDK 21–24, and (for iOS) a Mac with Xcode.

git clone https://github.com/AventurasTeam/Aventuras.git
cd Aventuras
npm install
npx tauri dev
Script Does
npm run dev Vite dev server (frontend only)
npx tauri dev full app, with hot reload
npm run build production build
npm run check type checking (svelte-check)
npm test test suite (Vitest)
npm run lint ESLint — lint:fix to fix
npm run format Prettier
npm run release version bump, tag and push

Desktop builds are npx tauri build; Android and iOS are documented in docs/development/release.md. iOS produces an unsigned device .ipa (no Apple certificates or signing secrets — see docs/development/ios-build-target.md for the full account of how the target was added and how the unsigned CI pipeline works).

Tech stack

TypeScript (strict) · SvelteKit 2 · Svelte 5 runes · Tauri 2 (Rust) · Tailwind + shadcn-svelte · SQLite (tauri-plugin-sql / sqlx) · Vercel AI SDK · LiquidJS · CodeMirror 6 · Zod · Harper.js (WASM) · Vitest

Contributing

Start with docs/ — the architecture is documented per area, and CLAUDE.md has the conventions. CI runs lint, type-check, tests and a build on every PR against master, develop or dev.

Acknowledgments

Tauri · SvelteKit · OpenRouter · Harper · Lucide

License

AGPL-3.0