alienet commited on
Commit
91c393d
·
1 Parent(s): 7ecfdc2

5/15 bug fix

Browse files
README copy.md DELETED
@@ -1,137 +0,0 @@
1
- # BookWorld: Interactive Multi-Agent Story Creation System
2
-
3
- <div align="center">
4
-
5
- 🖥️ [Project Page](https://bookworld2025.github.io/) | 📃 [Paper](https://arxiv.org/abs/2406.18921) | 🤗 [Demo](https://huggingface.co/spaces/alienet/BookWorld)
6
-
7
- </div>
8
-
9
-
10
-
11
-
12
- This is the official implementation of the paper "BOOKWORLD: From Novels to Interactive Agent Societies for Story Creation".
13
-
14
- ![Preview.png](<https://media-hosting.imagekit.io/14ce589aed514385/Preview.png?Expires=1840513142&Key-Pair-Id=K2ZIVPTIP2VGHC&Signature=oH~h5cUOwe3DjyDa86z40LBKpVanA81kQcGWubqjAa7SdiRWbYq2GIIF27urVYi4JK6u20IcmbRmoIxqkIQ1D-IBc9aMKcyVLJrjtlsvbaePOzgi-GtivxWIFuJvSzzuOfYmWF89KxzQ~EFsximhKJqtuw-WCZYRhpEFMUSuy42z-Lhv4ou6mWM58PIwzvsdc~rJxtMEXdaoxA9BGKKfcWD8mrhN8TI~mQzeRP-WE6KxHS9ib3MKES1BN9n5jLa4vEI5I2OwnzBFnc2iJ2vcyYgYRUY~1JF-ucYubMt85H2aWo9PUBYy38BYzodDdI0X8sKesL~evjstY5RH0buyCw__>)
15
-
16
- ## Introduction
17
-
18
- BookWorld is a comprehensive system for social simulation in fictional worlds through multi-agent interactions. The system features:
19
-
20
- - Scene-based story progression with multiple character agents
21
- - Continuous updating of agent memories, status, and goals
22
- - World agent orchestration of the simulation
23
- - Support for human intervention and control
24
- - LLM-based story generation and refinement
25
-
26
- ## Setup
27
-
28
- ### Step 1. Clone the repository
29
- ```bash
30
- git clone https://github.com/your-repo/bookworld.git
31
- cd bookworld
32
- ```
33
-
34
- ### Step 2. Install dependencies
35
- ```bash
36
- pip install -r requirements.txt
37
- ```
38
-
39
- ### Step 3. Configure Simulation Settings
40
- - Update the configuration parameters in `config.json`:
41
- - `role_llm_name`: LLM model for character roles
42
- - `world_llm_name`: LLM model for world simulation
43
- - `config_path`: The path to the experiment
44
- - `if_save`: Enable/disable saving (1/0)
45
- - `scene_mode`: Scene progression mode
46
- - `rounds`: Number of simulation rounds
47
- - `mode`: Simulation mode ("free" or "script")
48
-
49
- ## Usage
50
-
51
- ### Step 1. Start the server
52
- ```bash
53
- python server.py
54
- ```
55
- or
56
- ```bash
57
- uvicorn server:app --host 127.0.0.1 --port 8000
58
- ```
59
-
60
- ### Step 2. Access the web interface
61
- Open a browser and navigate to http://localhost:8000.
62
-
63
- ### Step 3. Interact with the system
64
- - Start/pause/stop story generation
65
- - View character information and map details
66
- - Monitor story progression and agent interactions
67
- - Edit generated content if needed
68
-
69
- ### Step 4. Continue from previous simulation
70
- Locate the directory of the previous simulation within `/experiment_saves/`, and set its path to the `save_dir` field in `config.json`.
71
-
72
- ## Customization
73
- ### Construct Your Virtual World
74
- 1. Create the roles, map, worldbuilding following the examples given in `/data/`. You can improve the simulation quality by providing background settings about the world in `world_details/` or put character dialogue lines in `role_lines.jsonl`. Additionally, you can place an image named `icon.(png/jpg)` inside the character's folder — this will be used as the avatar displayed in the interface.
75
- 3. Enter the preset path to `preset_path` in `config.json`.
76
-
77
- ### Convert SillyTavern Character Cards to Role Data
78
- 1. Put your character cards in `/data/sillytavern_cards/`.
79
- 2. Run the script. It will convert all the cards into the role data that BookWorld needs.
80
- ```bash
81
- python convert_sillytavern_cards_to_data.py
82
- ```
83
- 3. Input role codes of all the characters participating in this simulation to `role_agent_codes` in the preset file.
84
-
85
- ## Directory Structure
86
-
87
- ```
88
- .
89
- ├── data/
90
- ├── frontend/
91
- │ ├── assets/
92
- │ ├── css/
93
- │ └── js/
94
- ├── modules/
95
- │ ├── db/
96
- │ ├── llm/
97
- │ ├── prompt/
98
- │ ├── main_role_agent.py
99
- │ └── world_agent.py
100
- ├── experiment_configs/
101
- ├── BookWorld.py
102
- ├── server.py
103
- ├── config.json
104
- └── index.html
105
- ```
106
-
107
-
108
- ## Authors and Citation
109
- **Authors:** Yiting Ran, Xintao Wang, Tian Qiu,
110
- Jiaqing Liang, Yanghua Xiao, Deqing Yang.
111
-
112
- ```bibtex
113
- @misc{ran2025bookworldnovelsinteractiveagent,
114
- title={BookWorld: From Novels to Interactive Agent Societies for Creative Story Generation},
115
- author={Yiting Ran and Xintao Wang and Tian Qiu and Jiaqing Liang and Yanghua Xiao and Deqing Yang},
116
- year={2025},
117
- eprint={2504.14538},
118
- archivePrefix={arXiv},
119
- primaryClass={cs.CL},
120
- url={https://arxiv.org/abs/2504.14538},
121
- }
122
- ```
123
- ## License
124
-
125
- This project is licensed under the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0).
126
-
127
-
128
- ## Acknowledgements
129
-
130
- - Fantasy Map: The background of map panel used in the frontend is from [Free Fantasy Maps](https://freefantasymaps.org/epic-world-cinematic-landscapes/), created by Fantasy Map Maker. This map is free for non-commercial use.
131
-
132
- ## Contact
133
-
134
- BookWorld is a foundational framework that we aim to continuously optimize and enrich with custom modules. We welcome and greatly appreciate your suggestions and contributions!
135
-
136
- If you have any suggestions or would like to contribute, please contact us at: [email protected]
137
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app.py CHANGED
@@ -14,7 +14,7 @@ app = FastAPI()
14
  default_icon_path = './frontend/assets/images/default-icon.jpg'
15
  config = load_json_file('config.json')
16
  for key in config:
17
- if "API_KEY" in key:
18
  os.environ[key] = config[key]
19
 
20
  static_file_abspath = os.path.abspath(os.path.join(os.path.dirname(__file__), 'frontend'))
@@ -25,8 +25,11 @@ class ConnectionManager:
25
  self.active_connections: dict[str, WebSocket] = {}
26
  self.story_tasks: dict[str, asyncio.Task] = {}
27
  if True:
28
- if "preset_path" in config and config["preset_path"] and os.path.exists(config["preset_path"]):
29
- preset_path = config["preset_path"]
 
 
 
30
  elif "genre" in config and config["genre"]:
31
  genre = config["genre"]
32
  preset_path = os.path.join(os.path.dirname(os.path.abspath(__file__)),f"./config/experiment_{genre}.json")
@@ -202,12 +205,6 @@ async def websocket_endpoint(websocket: WebSocket, client_id: str):
202
  }
203
  })
204
 
205
- elif message['type'] == 'request_api_configs':
206
- await websocket.send_json({
207
- 'type': 'api_configs',
208
- 'data': API_CONFIGS
209
- })
210
-
211
  elif message['type'] == 'api_settings':
212
  # 处理API设置
213
  settings = message['data']
 
14
  default_icon_path = './frontend/assets/images/default-icon.jpg'
15
  config = load_json_file('config.json')
16
  for key in config:
17
+ if "API_KEY" in key and config[key]:
18
  os.environ[key] = config[key]
19
 
20
  static_file_abspath = os.path.abspath(os.path.join(os.path.dirname(__file__), 'frontend'))
 
25
  self.active_connections: dict[str, WebSocket] = {}
26
  self.story_tasks: dict[str, asyncio.Task] = {}
27
  if True:
28
+ if "preset_path" in config and config["preset_path"]:
29
+ if os.path.exists(config["preset_path"]):
30
+ preset_path = config["preset_path"]
31
+ else:
32
+ raise ValueError(f"The preset path {config['preset_path']} does not exist.")
33
  elif "genre" in config and config["genre"]:
34
  genre = config["genre"]
35
  preset_path = os.path.join(os.path.dirname(os.path.abspath(__file__)),f"./config/experiment_{genre}.json")
 
205
  }
206
  })
207
 
 
 
 
 
 
 
208
  elif message['type'] == 'api_settings':
209
  # 处理API设置
210
  settings = message['data']
config.json CHANGED
@@ -2,12 +2,12 @@
2
  "role_llm_name": "gemini-2",
3
  "world_llm_name": "gemini-2",
4
  "embedding_model_name":"bge-m3",
5
- "preset_path":"./experiment_presets/example_free.json",
6
  "if_save": 0,
7
  "scene_mode": 1,
8
  "rounds": 10,
9
  "save_dir": "",
10
- "mode": "script",
11
 
12
  "OPENAI_API_KEY":"",
13
  "GEMINI_API_KEY":"",
 
2
  "role_llm_name": "gemini-2",
3
  "world_llm_name": "gemini-2",
4
  "embedding_model_name":"bge-m3",
5
+ "preset_path":"./experiment_presets/experiment_icefire.json",
6
  "if_save": 0,
7
  "scene_mode": 1,
8
  "rounds": 10,
9
  "save_dir": "",
10
+ "mode": "free",
11
 
12
  "OPENAI_API_KEY":"",
13
  "GEMINI_API_KEY":"",
data/roles/example_world/Lacia-en/icon.png ADDED

Git LFS Details

  • SHA256: 2468a8caec3317a001092870357ed27b09e769686b7effe2fcb1b3cb5ae57842
  • Pointer size: 131 Bytes
  • Size of remote file: 139 kB
data/roles/example_world/Trek-en/icon.png ADDED

Git LFS Details

  • SHA256: 115c00b1c2782283ea5d2361015721085cc850b550e75965e2a4e168259c01e7
  • Pointer size: 131 Bytes
  • Size of remote file: 155 kB
modules/llm/OpenRouter.py CHANGED
@@ -38,8 +38,6 @@ class OpenRouter(BaseLLM):
38
  self.initialize_message()
39
  self.user_message(text)
40
  response = self.get_response(temperature = temperature)
41
- print("In",self.count_token(text))
42
- print("Out", self.count_token(response))
43
  self.in_token += self.count_token(text)
44
  self.out_token += self.count_token(response)
45
  return response
 
38
  self.initialize_message()
39
  self.user_message(text)
40
  response = self.get_response(temperature = temperature)
 
 
41
  self.in_token += self.count_token(text)
42
  self.out_token += self.count_token(response)
43
  return response