tavern-harness 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +90 -113
- package/README.zh.md +16 -1
- package/package.json +1 -1
- package/vite.config.ts +15 -0
package/README.md
CHANGED
|
@@ -1,161 +1,138 @@
|
|
|
1
|
-
# Tavern Harness ·
|
|
1
|
+
# Tavern Harness · An AI-Native Role-Playing Sandbox
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[GitHub Repository](https://github.com/Rannichan/Tavern-Harness) · [Product Site](https://rannichan.github.io/Tavern-Harness/) · [Open Sandbox](https://rannichan.github.io/Tavern-Harness/#world) · [Report an Issue](https://github.com/Rannichan/Tavern-Harness/issues) · [Discussions](https://github.com/Rannichan/Tavern-Harness/discussions) · [Discord](https://discord.gg/kPSWGeaHx) · [Skill Sandbox Design](./notebook/skill-sandbox-design.md)
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
<a id="run"></a>
|
|
6
|
+
## 1 · Getting Started
|
|
6
7
|
|
|
7
|
-
>
|
|
8
|
+
> Requires **Node.js 18 or later**. Tavern Harness is a frontend web app with an optional local sandbox service—no Docker or database server required.
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
### Option 1: One-Command Start (Recommended)
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
- 任意 OpenAI 兼容 `chat/completions` 接口,**流式输出**(SSE)
|
|
13
|
-
- **多 Provider 管理**:Base URL / API Key,连通性测试与模型列表拉取
|
|
14
|
-
- **思考模式**:独立展示 thinking 内容(`reasoning` / `reasoning_content` / `thinking_content`),支持 Qwen `chat_template_kwargs` 适配
|
|
15
|
-
- **原生工具调用**:OpenAI `tools` 协议,本地真实执行,`role=tool` 结果回灌,最多 4 层 ReAct 链式调用
|
|
16
|
-
- **多模态附件**:图片(粘贴 / 选择)随消息发送为 data URL
|
|
17
|
-
- **消息管理**:右键编辑历史消息、重新生成回复、查看原始请求/响应日志(自动脱敏)
|
|
18
|
-
- **中断生成**:可随时停止流式输出,已生成部分自动持久化
|
|
19
|
-
- **魔法命令**:`/new` 开始新话题(截断上下文)、`/pass` 跳过本轮发言(群聊)
|
|
20
|
-
- **Markdown 渲染**:代码高亮、表格、行内/块级数学公式(KaTeX)
|
|
21
|
-
- 每条消息记录延迟、token 用量、tokens/s、所用模型等指标
|
|
22
|
-
|
|
23
|
-
### 会话模式
|
|
24
|
-
- **标准对话(STANDARD)**:与助手一对一
|
|
25
|
-
- **NPC 对话**:与单个角色卡对话,独立人设、开场白、技能配置
|
|
26
|
-
- **群聊(GROUP)**:2~5 位 NPC 同场对话
|
|
27
|
-
- 回合制:PRESET(按座位顺序)/ RANDOM(随机)
|
|
28
|
-
- `@角色名` 直接指定下一个发言者
|
|
29
|
-
- 玩家可扮演角色(User Persona)
|
|
30
|
-
|
|
31
|
-
### 角色工坊(对标 SillyTavern)
|
|
32
|
-
- **角色卡(NPC)**:人设、开场白、彩色首字母头像 / 选图,编辑页内按角色启用技能(内置角色「酒馆老板」默认启用全部内置技能)
|
|
33
|
-
- **SillyTavern PNG 导入**:chara V2 / ccv3 V3 一键导入,解析人设、开场白、内嵌Lorebook
|
|
34
|
-
- **Lorebook**:世界观设定附加在人设后,可绑定到会话
|
|
35
|
-
- **技能表(工具)**:
|
|
36
|
-
- 内置:`run_shell_script`(受控本地命令执行)、`roll_dice`、`create_skill` / `update_skill` / `delete_skill`、`get_tavern_info`、角色与Lorebook CRUD
|
|
37
|
-
- **生成式技能**:`template` / `http_get` / `javascript`(Web Worker 沙箱,支持 async/await,可注入 `$read`/`$write`/`$append`/`$list` 持久化游戏状态)/ `file_read` / `file_write` / `shell`(真实执行,白名单直执 + 其余命令确认)/ `device_action`(通知 / 震动)
|
|
38
|
-
- **确认门控**:更新/删除类操作、以及所有**非白名单 shell 命令**均弹出确认框
|
|
39
|
-
|
|
40
|
-
## 🚀 使用
|
|
41
|
-
|
|
42
|
-
### 直接启动(npm)
|
|
43
|
-
|
|
44
|
-
需要 Node.js 18 或更高版本。无需克隆仓库或全局安装:
|
|
12
|
+
No repository clone or global installation is required:
|
|
45
13
|
|
|
46
14
|
```bash
|
|
47
15
|
npx tavern-harness
|
|
48
16
|
```
|
|
49
17
|
|
|
50
|
-
|
|
18
|
+
The first run downloads the package, starts the local service, and opens your browser automatically. Optional arguments:
|
|
51
19
|
|
|
52
20
|
```bash
|
|
53
21
|
npx tavern-harness --no-open
|
|
54
22
|
npx tavern-harness --port 5273
|
|
55
23
|
```
|
|
56
24
|
|
|
57
|
-
|
|
25
|
+
The service listens only on the local machine. When using shell skills, commands run locally with the permissions of the user who started the command. Run only versions from trusted sources and review every command-confirmation dialog.
|
|
58
26
|
|
|
59
|
-
###
|
|
27
|
+
### Option 2: Develop from Source
|
|
60
28
|
|
|
61
29
|
```bash
|
|
30
|
+
git clone https://github.com/Rannichan/Tavern-Harness.git
|
|
31
|
+
cd Tavern-Harness
|
|
62
32
|
npm install
|
|
63
|
-
npm run dev #
|
|
64
|
-
npm run build # 构建
|
|
65
|
-
npm run preview # 预览
|
|
33
|
+
npm run dev # Defaults to port 5173 and automatically tries the next port if occupied
|
|
66
34
|
```
|
|
67
35
|
|
|
68
|
-
|
|
36
|
+
### Configure a Model Provider on First Launch
|
|
69
37
|
|
|
70
|
-
|
|
71
|
-
2. 在聊天页顶部点击模型名选择模型
|
|
72
|
-
3. 回到对话,开聊!
|
|
38
|
+
After starting the app, open **Settings → Model Service Provider**:
|
|
73
39
|
|
|
74
|
-
|
|
40
|
+
1. **Add a provider**: enter a name, Base URL, and API Key. Any OpenAI-compatible `chat/completions` API is supported, including OpenAI, DeepSeek, Qwen, SiliconFlow, Ollama, LM Studio, and self-hosted vLLM.
|
|
41
|
+
2. **Test the connection**: the app fetches the model list automatically. If the target service does not expose CORS headers, requests are forwarded through the built-in same-origin proxy for private-network or LAN addresses. On success, the Base URL is rewritten to its proxy form and saved.
|
|
42
|
+
3. **Select a model**: click the model name at the top of the chat page, then return to the conversation and start chatting.
|
|
75
43
|
|
|
76
|
-
|
|
44
|
+
### Data Privacy
|
|
77
45
|
|
|
78
|
-
|
|
46
|
+
- **All data is stored in browser IndexedDB**: conversations, character cards, lorebooks, skills, statistics, and API keys are not uploaded to any server.
|
|
47
|
+
- Data is tied to the browser, port, and site origin. Switching browsers, opening a private window, or using a different port will not show existing data. This is expected browser security behavior; use the same browser and port each time.
|
|
79
48
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
```
|
|
49
|
+
<a id="features"></a>
|
|
50
|
+
## 2 · Features
|
|
83
51
|
|
|
84
|
-
|
|
52
|
+
### 🍺 The Tavern Keeper Is Always Ready to Help
|
|
85
53
|
|
|
86
|
-
|
|
87
|
-
COMMAND_SERVICE_TOKEN=临时随机值 COMMAND_APPROVAL_TOKEN=另一临时随机值 node sandbox-server.mjs
|
|
88
|
-
```
|
|
54
|
+
Whether you are creating a character card, designing a tabletop RPG scenario, or simply unsure where to begin, ask the Tavern Keeper.
|
|
89
55
|
|
|
90
|
-
|
|
56
|
+
The tavern is designed around AI assistance to make creating and playing games easier.
|
|
91
57
|
|
|
92
|
-
|
|
93
|
-
- Vite 代理覆盖内部认证头,浏览器不能自行指定服务密钥;服务不开放跨域访问。
|
|
94
|
-
- **权限模型(命令分级)**:
|
|
95
|
-
- **直接执行命令 → 不需确认**:白名单按能力分类维护:
|
|
96
|
-
- 基础信息:`pwd`、`date`、`whoami`、`uname`、`hostname`、`uptime`、`which`
|
|
97
|
-
- 文件与目录:`ls`、`touch`、`mkdir`、`cp`、`basename`、`dirname`、`du`、`stat`、`file`
|
|
98
|
-
- 文本与结构化数据:`echo`、`printf`、`cat`、`head`、`tail`、`wc`、`uniq`、`grep`、`cut`、`tr`、`diff`、`cmp`、`od`、`xxd`、`hexdump`、`strings`、`tee`、`jq`
|
|
99
|
-
- 系统配置 / 查询:`localectl`、`timedatectl`、`ffprobe`
|
|
100
|
-
- 逻辑 / 数学 / 校验:`true`、`false`、`seq`、`factor`、`bc`、`sha256sum`、`md5sum`、`cksum`、`sum`
|
|
101
|
-
- 解释器、命令启动器、带 exec / 外部程序 / 动态插件能力的工具,以及所有压缩工具均不在白名单中;包括 `node`、`npm`、`npx`、`git`、`env`、`xargs`、`awk`、`find`、`sed`、`tar`、`zip`、`sort`、`openssl`、`calc`、`gzip`、`gunzip`、`xz`、`unzip`,执行前必须取得用户许可。
|
|
102
|
-
- **任何非白名单命令 → 弹窗确认后执行**:服务端先签发绑定脚本与会话、60 秒有效且只能使用一次的确认票据;前端展示整段脚本并在用户批准后携票据重发。裸 `confirmed` 标记无效;拒绝返回 `CANCELLED`。
|
|
103
|
-
- 其余规范:单条命令 5s 超时、输出截断、脚本 ≤ 8000 字符 / ≤ 20 条命令;无 shell 解释器,不支持管道、重定向、变量展开或命令替换。
|
|
104
|
-
- 该服务仅监听 `127.0.0.1`,不对外暴露;未启动时返回明确错误提示。
|
|
58
|
+
### 🛠️ Skill System
|
|
105
59
|
|
|
106
|
-
|
|
60
|
+
Characters are more than chat partners: they are **agents with extensible skills**. Equip each character with the abilities needed for richer gameplay.
|
|
107
61
|
|
|
108
|
-
|
|
62
|
+
The tavern includes essential skills such as dice rolling. You can also ask the Tavern Keeper to **create any skill you need**.
|
|
109
63
|
|
|
110
|
-
-
|
|
111
|
-
- 删除对话时会**一并删除其专属工作目录**(磁盘目录 + 沙箱未启动时写入浏览器虚拟工作区 IndexedDB 的数据一并清理);
|
|
112
|
-
- shell 命令以该目录为 `cwd` 执行;读写路径必须留在当前会话工作目录内(普通会话仅允许通过 `public` 软链读取公共目录,写入仍拒绝);
|
|
113
|
-
- 文件读写 / 文件列表只对该目录可见(无法访问其它会话或外部目录);
|
|
114
|
-
- 浏览器虚拟工作区(沙箱未启动时的回退)同样按会话隔离:`generated_skill_workspace/sessions/session-<会话id>/…`;
|
|
115
|
-
- 通过文件工具维护的不同会话数据互不可见、互不影响;本地命令读写也受同一目录边界约束。
|
|
64
|
+
### 💬 Multi-Character Group Chats
|
|
116
65
|
|
|
117
|
-
|
|
66
|
+
Each room supports up to **six characters** and provides a turn-order board for managing group conversations.
|
|
118
67
|
|
|
119
|
-
|
|
68
|
+
Use **@mentions** and **skip** to create natural multi-character scenes—whether observing from above or role-playing as part of the group.
|
|
120
69
|
|
|
121
|
-
|
|
70
|
+
### 🎁 Share Your Game with Friends
|
|
122
71
|
|
|
123
|
-
-
|
|
124
|
-
- 写入 / 追加工作区相对路径文件(单文件 ≤ 400KB);普通会话对 `public/...` 写入会被直接拒绝
|
|
125
|
-
- 通过 `file_list` 端点列出工作区文件(上限 500 个)
|
|
72
|
+
Compatible with the **Tavern ecosystem**, including one-click PNG character-card imports.
|
|
126
73
|
|
|
127
|
-
|
|
74
|
+
You can also export and share an entire game: recipients can import it and play immediately without manually creating characters, skills, or conversation settings.
|
|
128
75
|
|
|
129
|
-
###
|
|
76
|
+
### 🍃 Fully Local and Clean
|
|
130
77
|
|
|
131
|
-
|
|
78
|
+
The app supports **OpenAI-format APIs**. Use a hosted API plan or run a model locally; your data remains on your device.
|
|
132
79
|
|
|
133
|
-
|
|
134
|
-
- 代理连通后,Provider 的 Base URL 会被自动改写为同源代理形式并保存,无需手动填写
|
|
80
|
+
The project has no external harness dependency, and its UI is designed for a clean, focused experience.
|
|
135
81
|
|
|
136
|
-
|
|
82
|
+
<a id="gameplay"></a>
|
|
83
|
+
## 3 · Gameplay Examples
|
|
137
84
|
|
|
138
|
-
-
|
|
139
|
-
- Zustand(全局状态)
|
|
140
|
-
- Dexie.js(IndexedDB ORM,对应 Room)
|
|
141
|
-
- KaTeX(数学渲染)
|
|
142
|
-
- marked(Markdown 解析)
|
|
143
|
-
- Web Worker 沙箱(JavaScript 技能隔离执行)
|
|
85
|
+
> These examples progress from simple to advanced: the first three work out of the box, while the remaining four gradually introduce sandbox capabilities. In every example, “the Keeper” means the built-in **Tavern Keeper** character, which exists on first launch and has all built-in skills enabled by default.
|
|
144
86
|
|
|
145
|
-
|
|
87
|
+
### Example 1: Late-Night Company (No Setup)
|
|
146
88
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
89
|
+
1. Create a new conversation → select **NPC Chat** → choose **Tavern Keeper** or any custom character.
|
|
90
|
+
2. Chat naturally as you would with a friend. Enable **thinking mode** to see the Keeper's reasoning.
|
|
91
|
+
3. Long-press or right-click any message to edit history, regenerate, inspect raw logs, or fork a branch.
|
|
92
|
+
|
|
93
|
+
### Example 2: Tabletop Dice Rolls (Role-Playing)
|
|
94
|
+
|
|
95
|
+
1. Create an **NPC Chat** for a GM and give the character a prompt such as: “You are the GM for this campaign; use `roll_dice` to decide fate.”
|
|
96
|
+
2. Use the opening message to introduce a story hook. The Keeper can call `roll_dice` and display results such as critical successes or failures.
|
|
97
|
+
3. Add campaign rules and world setting to a Lorebook, then bind it to the conversation to turn the character into a complete world.
|
|
98
|
+
|
|
99
|
+
### Example 3: A Group-Chat Script (Up to Six Characters)
|
|
100
|
+
|
|
101
|
+
1. Create multiple NPCs in the **Character Workshop**, such as a detective, butler, and protagonist.
|
|
102
|
+
2. Create a **Group Chat**, add up to six characters, drag to set their speaking order, or enable random ordering.
|
|
103
|
+
3. Use `@character-name` to choose the next speaker. Enter `/new` to begin a new topic with truncated context, or `/pass` to skip your turn.
|
|
104
|
+
|
|
105
|
+
### Example 4: Create Skills in the Moment
|
|
106
|
+
|
|
107
|
+
1. Ask the Keeper: “Create a skill that accepts a city and returns the weather.” It can call `create_skill` to create a new `template` or `http_get` skill.
|
|
108
|
+
2. New skills are disabled for all characters by default. Enable them for the desired character in **Character Workshop → Skills**.
|
|
109
|
+
3. Skills can use `$read`, `$write`, `$append`, and `$list` to work with the conversation workspace, with no restart required.
|
|
110
|
+
|
|
111
|
+
### Example 5: A Persistent Mini-Game (Advanced Sandbox)
|
|
112
|
+
|
|
113
|
+
1. Ask the Keeper to write a `javascript` skill for an affinity system, saving each turn's value to `state.json` with `$write`.
|
|
114
|
+
2. Create another skill that reads with `$read` and uses `file_write` to generate an HTML dashboard, `dashboard.html`.
|
|
115
|
+
3. Use `file_display` to visualize value changes in a pop-up; workspace files can be previewed in an isolated, resizable HTML view.
|
|
116
|
+
4. Deleting the conversation also removes its `sandbox_workspace/session-<id>/` directory.
|
|
117
|
+
|
|
118
|
+
### Example 6: Organize Files with Shell Skills
|
|
119
|
+
|
|
120
|
+
1. Ask the Keeper in chat to use `ls` to inspect the workspace, `cat` to read files, and `cp` to archive creative work.
|
|
121
|
+
2. Reads and writes must remain in the current conversation workspace. Non-allowlisted commands such as `node` and `git`, plus modifying operations such as `mv` and `rm`, require confirmation.
|
|
122
|
+
3. Regular conversations have read-only access to `public/`. Only the built-in Tavern Keeper can write to the public area, allowing shared assets across conversations.
|
|
123
|
+
|
|
124
|
+
### Example 7: Take an Entire World with You (Import, Export, and Fork)
|
|
125
|
+
|
|
126
|
+
1. Mid-game, choose **Export Game** and decide whether to include conversation history to create a self-contained JSON file.
|
|
127
|
+
2. Send the JSON to a friend, who can use **Import Game** to restore your characters and world in one step. Conflicts create copies instead of overwriting data.
|
|
128
|
+
3. Or create a branch / fork to explore multiple endings from the same history.
|
|
129
|
+
|
|
130
|
+
<a id="feedback"></a>
|
|
131
|
+
## 4 · Community and Feedback
|
|
157
132
|
|
|
158
|
-
|
|
133
|
+
- 🐛 Found a bug or have a feature request? Open a [GitHub Issue](https://github.com/Rannichan/Tavern-Harness/issues). You are welcome to attach exported game JSON or browser-console logs, but always remove API keys first.
|
|
134
|
+
- 🟣 For usage discussions, gameplay ideas, character and skill sharing, or development updates, join the [Discord community](https://discord.gg/kPSWGeaHx).
|
|
135
|
+
- 🤝 Pull requests are welcome.
|
|
136
|
+
- 📣 Star or watch the repository to receive updates.
|
|
159
137
|
|
|
160
|
-
|
|
161
|
-
- API Key 只存储在浏览器本地 IndexedDB,不上传任何服务器
|
|
138
|
+
> The tavern is open 24 hours a day, and the Keeper is always here to help.
|
package/README.zh.md
CHANGED
|
@@ -9,7 +9,22 @@
|
|
|
9
9
|
|
|
10
10
|
### 方式一:一键启动(推荐)
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
无需克隆仓库或全局安装:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npx tavern-harness
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
首次运行会下载包、启动本地服务,并自动打开浏览器。可选参数:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npx tavern-harness --no-open
|
|
22
|
+
npx tavern-harness --port 5273
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
服务仅监听本机。使用 shell 技能时,命令会以启动命令的当前用户权限在本机执行;请仅运行来自可信来源的版本,并审阅每次命令确认弹窗。
|
|
26
|
+
|
|
27
|
+
### 方式二:从源码开发
|
|
13
28
|
|
|
14
29
|
```bash
|
|
15
30
|
git clone https://github.com/Rannichan/Tavern-Harness.git
|
package/package.json
CHANGED
package/vite.config.ts
CHANGED
|
@@ -262,6 +262,21 @@ function sandboxProxyPlugin(): Plugin {
|
|
|
262
262
|
|
|
263
263
|
export default defineConfig({
|
|
264
264
|
plugins: [react(), corsProxyPlugin(), sandboxProxyPlugin()],
|
|
265
|
+
optimizeDeps: {
|
|
266
|
+
include: [
|
|
267
|
+
'@dnd-kit/core',
|
|
268
|
+
'@dnd-kit/sortable',
|
|
269
|
+
'@dnd-kit/utilities',
|
|
270
|
+
'dexie',
|
|
271
|
+
'dompurify',
|
|
272
|
+
'katex',
|
|
273
|
+
'marked',
|
|
274
|
+
'react',
|
|
275
|
+
'react-dom',
|
|
276
|
+
'use-sync-external-store/shim/with-selector',
|
|
277
|
+
'zustand',
|
|
278
|
+
],
|
|
279
|
+
},
|
|
265
280
|
server: {
|
|
266
281
|
port: 5173,
|
|
267
282
|
open: false,
|