Skip to content

perf: optimize Lua scripting runtime and lightweight chat access#1459

Open
SameDesu123 wants to merge 4 commits into
kwaroran:mainfrom
SameDesu123:feat/lua-runtime-optimizations
Open

perf: optimize Lua scripting runtime and lightweight chat access#1459
SameDesu123 wants to merge 4 commits into
kwaroran:mainfrom
SameDesu123:feat/lua-runtime-optimizations

Conversation

@SameDesu123
Copy link
Copy Markdown
Contributor

@SameDesu123 SameDesu123 commented May 21, 2026

PR Checklist

  • Required Checks
    • Have you added type definitions?
    • Have you tested your changes?
    • Have you checked that it won't break any existing features?
  • If your PR uses models1, check the following:
    • Have you checked if it works normally in all models?
    • Have you checked if it works normally in all web, local, and node-hosted versions? If it doesn't, have you blocked it in those versions?
  • If your PR is highly AI generated2, check the following:
    • Have you understood what the code does?
    • Have you cleaned up any unnecessary or redundant code?
    • Is it not a huge change?
      • We currently do not accept highly AI generated PRs that are large changes.

Summary

Optimize Lua scripting runtime behavior by reducing unnecessary engine re-creation, skipping redundant chat variable writes, and adding lightweight chat access APIs for scripts.

This should help Lua-heavy characters and modules avoid avoidable rendering and scripting overhead, especially when multiple Lua triggers or display-related scripts are used.

Related Issues

None.

Changes

  • Added per-script identity keys for Lua trigger runtime caches.

    • Character triggers are keyed by character id, trigger index, and mode.
    • Module triggers are keyed by module id, trigger index, and mode.
    • Code changes reuse the same per-script key, so the existing code !== state.code path closes and recreates the runtime instead of leaving hash-keyed engines behind.
    • Existing callers continue to work because the explicit engineKey option is optional.
  • Added module trigger runtime metadata.

    • getModuleTriggerRuntimes() preserves each trigger's source module id and index for stable runtime keys.
    • getModuleTriggers() remains available for existing callers.
  • Optimized setChatVar.

    • setChatVar now skips writes when the stored value is already identical.
    • This avoids unnecessary script state mutation from Lua code that repeatedly writes the same state value.
    • The function returns true when a value changed and false when the write was skipped.
    • The return value is exposed through the scripting bridge and Lua setState.
  • Added lightweight Lua chat access APIs.

    • getChatData(id, index) returns only the message text.
    • getChatRole(id, index) returns only the message role.
    • getRecentChats(id, count) returns only the latest N messages.
    • These provide cheaper alternatives to getFullChat(id) for scripts that only need a small part of the chat.

Impact

This is intended to be backward compatible.

Existing Lua APIs such as getChat, getFullChat, setState, and button triggers remain available. The new chat access APIs are additive, and the setChatVar behavior only skips redundant writes where the final stored value would be unchanged.

The main expected impact is better performance for Lua-heavy workflows, especially display/status-panel scripts and setups with multiple Lua triggers in the same mode.

No model request or response behavior is changed.

Additional Notes

Tested in dev server.

Footnotes

  1. Modifies the behavior of prompting, requesting, or handling responses from AI models.

  2. Over 80% of the code is AI generated.

@SameDesu123 SameDesu123 marked this pull request as ready for review May 22, 2026 01:19
Copy link
Copy Markdown
Collaborator

@cubicj cubicj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One compatibility concern: returning true or false from the Lua-facing setChatVar() / setState() is useful, but it changes the behavior of existing setter APIs. Existing scripts may call these setters in return position assuming they return nothing, and that can now leak a boolean into the trigger result.

Could you check the compatibility impact here?

@SameDesu123
Copy link
Copy Markdown
Contributor Author

SameDesu123 commented Jun 3, 2026

@cubicj Thanks for catching this. I pushed a follow-up commit that keeps the compatibility behavior for the existing Lua-facing setters: setChatVar() and setState() no longer return the internal boolean, so existing scripts like return setState(...) will not leak a boolean trigger result or accidentally stop generation.

For scripts that explicitly need to know whether a write changed state, I added opt-in APIs: setChatVarChanged() and setStateChanged(). The trigger-local setter path now also reports changed/unchanged consistently for those opt-in calls.

Validated with:

  • pnpm check
  • git diff --check
  • pnpm test -- src/ts/parser/tests/chatVar.svelte.test.ts

@SameDesu123 SameDesu123 requested a review from cubicj June 3, 2026 09:52
Copy link
Copy Markdown
Collaborator

@cubicj cubicj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verified the follow-up. Thanks for taking the compatibility feedback. Existing Lua-facing setChatVar() / setState() stay no-return, and changed/skipped is now opt-in through the new *Changed APIs.

Check, tests, and build pass locally. GitHub checks pass.

Approving — thanks for the update!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants