{"id":25650132,"url":"https://github.com/p-e-w/sorcery","last_synced_at":"2026-06-28T09:30:20.522Z","repository":{"id":277853996,"uuid":"933528919","full_name":"p-e-w/sorcery","owner":"p-e-w","description":"The future of AI roleplay","archived":false,"fork":false,"pushed_at":"2025-02-16T15:15:29.000Z","size":33,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-02-16T16:28:12.040Z","etag":null,"topics":["ai","llm","sillytavern"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/p-e-w.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-02-16T07:11:52.000Z","updated_at":"2025-02-16T16:21:50.000Z","dependencies_parsed_at":"2025-02-16T16:28:17.432Z","dependency_job_id":null,"html_url":"https://github.com/p-e-w/sorcery","commit_stats":null,"previous_names":["p-e-w/sorcery"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/p-e-w%2Fsorcery","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/p-e-w%2Fsorcery/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/p-e-w%2Fsorcery/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/p-e-w%2Fsorcery/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/p-e-w","download_url":"https://codeload.github.com/p-e-w/sorcery/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240331333,"owners_count":19784644,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai","llm","sillytavern"],"created_at":"2025-02-23T15:00:50.274Z","updated_at":"2026-06-28T09:30:18.435Z","avatar_url":"https://github.com/p-e-w.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"# Sorcery\n\nSorcery is a [SillyTavern](https://github.com/SillyTavern/SillyTavern) extension\nthat allows AI characters to reach into the real world. It lets you bind arbitrary\nSTscript or JavaScript code to arbitrary events in the chat. It is infinitely more\npowerful than existing \"character expression\" systems, and dramatically easier to\nuse than traditional function calling setups. It does **not** require a specially\ntrained function calling model.\n\nSorcery can enable your virtual characters to do tangible things, from interacting\nwith your SillyTavern instance to controlling smart home appliances and toys.\nIt is **zero-configuration,** and once installed will immediately work with most\nmodels and setups.\n\n![Screenshot](https://github.com/user-attachments/assets/71c0d9e5-6784-499e-8b67-26d531deb15f)\n\nSorcery executes actions **while the response is streaming, at the exact moment\nthe relevant event occurs,** as demonstrated in this video:\n\nhttps://github.com/user-attachments/assets/49ff8f62-2674-4062-b378-bc272d1212e1\n\nSorcery works by injecting dynamically generated instructions into the system prompt\nthat tell the model to insert special markers into its responses when the configured\nevents occur. It then hooks the output stream, and intercepts those markers, removing\nthem from the output and running the associated scripts. The whole process is\ncompletely invisible to the user.\n\nEven relatively small models respond well to Sorcery's instructions. For example,\nI have successfully used Sorcery with the IQ3_M quant of Mistral Small, which fits\ninto 12 GB VRAM.\n\n\n## Requirements\n\nFor Sorcery to work, you need:\n\n* A text completion backend\n* Instruct mode enabled\n* System prompt enabled\n* Any character-specific system prompt overrides *disabled*\n\nMost users of local models will already have this configuration, and don't\nneed to do anything special.\n\nSorcery may or may not work with API-only hosted models supporting only chat\ncompletion mode. I don't use such models myself, and haven't tested this case.\nFeedback is appreciated.\n\n\n## Installation\n\nSorcery can be installed in seconds:\n\n1. Open SillyTavern\n2. Click the \"Extensions\" button in the top bar\n3. Click \"Install extension\"\n4. Copy this URL into the input field: `https://github.com/p-e-w/sorcery`\n5. Click \"Install just for me\"\n\nA new button should appear in the top bar that looks like a wizard's hat.\nClick that button to open the Sorcery configuration UI.\n\n\n## Is this safe?\n\nIt's as safe as you want it to be.\n\nSorcery enables LLMs to execute the scripts written by the user, nothing more\nand nothing less. Models cannot provide their own code to execute, they can only\nchoose among the already configured scripts. Thus even with a malicious model,\nthe worst thing that can happen is that it runs one of the scripts you wrote,\nat a time that is inconvenient to you. But it is always you who decides what kind\nof code can be run.\n\n\n## Usage example: Controlling a smart bulb\n\nSorcery's ability to run arbitrary JavaScript code is extremely powerful, because\nit allows us to make requests to any HTTP server. By whipping up a purpose-built\nHTTP server with Python, we can let Sorcery do almost anything.\n\nThis example demonstrates how to control a Philips WiZ WiFi smart light bulb from\nSorcery. WiZ bulbs are relatively cheap, available in most countries, and can be\ncontrolled entirely using open-source software once configured. If you have another\nbrand of smart light, adapt the instructions as needed.\n\nConfigure your WiZ bulb and connect it to the same LAN as your PC. Then figure out\nthe local IP address of the bulb, for example by logging in to your router. Now\nfollow these instructions:\n\nCreate a Python virtual environment and install dependencies:\n\n```\npython3 -m venv .venv\nsource .venv/bin/activate\npip install flask[async] pywizlight\n```\n\nCopy the following code into a file called `main.py`:\n\n```python\nimport pywizlight\n# https://github.com/sbidy/pywizlight/issues/140#issuecomment-1321426436\ndel pywizlight.wizlight.__del__\nfrom pywizlight import wizlight, PilotBuilder\nfrom flask import Flask\n\nbulb_ip = \"192.168.1.10\"  # \u003c-- Your bulb's IP address\n\napp = Flask(__name__)\n\n@app.route(\"/on\")\nasync def light_on():\n  light = wizlight(bulb_ip)\n  await light.turn_on(PilotBuilder(brightness = 255))\n  return \"\"\n\n@app.route(\"/off\")\nasync def light_off():\n  light = wizlight(bulb_ip)\n  await light.turn_off()\n  return \"\"\n```\n\nRun the server:\n\n```\nflask --app main run --port 3000\n```\n\nOpen Sorcery and copy the following code into the JavaScript field of the\n**\"{{char}} turns off the lights\"** default script:\n\n```javascript\nfetch(\"http://127.0.0.1:3000/off\");\n```\n\nNow start a chat and create a situation where the AI character turns off the\nlights in the roleplay. **You will see your light bulb turning off in the real\nworld.** This is as close to magic as it gets.\n\n\n## Acknowledgments\n\nSorcery includes the [code-input](https://github.com/WebCoder49/code-input)\nlibrary to provide syntax-highlighted text inputs. code-input is licensed\nunder the MIT License.\n\nParts of Sorcery's UI HTML were copied from SillyTavern's \"World Info\" UI.\nSillyTavern is licensed under the GNU Affero General Public License.\n\n\n## License\n\nCopyright \u0026copy; 2025  Philipp Emanuel Weidmann (\u003cpew@worldwidemann.com\u003e)\n\nThis program is free software: you can redistribute it and/or modify\nit under the terms of the GNU Affero General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nThis program is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU Affero General Public License for more details.\n\nYou should have received a copy of the GNU Affero General Public License\nalong with this program.  If not, see \u003chttps://www.gnu.org/licenses/\u003e.\n\n**By contributing to this project, you agree to release your\ncontributions under the same license.**\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fp-e-w%2Fsorcery","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fp-e-w%2Fsorcery","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fp-e-w%2Fsorcery/lists"}