1
0
Fork 0

sort systems into folders
Run Docker Build / build (push) Successful in 16s Details
Run Python Build / build (push) Successful in 22s Details

This commit is contained in:
Sean Sube 2024-06-22 17:00:46 -05:00
parent 37ef494796
commit 205d6923b3
Signed by: ssube
GPG Key ID: 3EED7B957D362AF1
35 changed files with 204 additions and 47 deletions

View File

@ -5,6 +5,21 @@ TaleWeave AI is an open-source game engine designed for creating rich, immersive
![TaleWeave AI logo with glowing sunrise over angular castle](https://docs-cdn.taleweave.ai/taleweave-github-1280.png)
## Contents
- [TaleWeave AI](#taleweave-ai)
- [Contents](#contents)
- [Features](#features)
- [Game Actions](#game-actions)
- [Game Systems](#game-systems)
- [Requirements](#requirements)
- [Recommended](#recommended)
- [Setup](#setup)
- [Documentation](#documentation)
- [Contributing](#contributing)
- [Support and Community](#support-and-community)
- [License](#license)
## Features
TaleWeave AI is meant for gamers, developers, and researchers. It is a:
@ -26,7 +41,7 @@ TaleWeave AI does a few things out of the box:
- Generate a world from a brief text prompt
- Simulate the actions of characters in that world
- Allow humans to interact with each other and with NPCs
- Track detailed status for each entity: mood, hunger, thirst, hygiene, time of day, weather, etc
- Track detailed status for each entity: mood, hunger, thirst, hygiene, weather, and more
- Summarize the environment into LLM prompts
- Foster emergent behavior through action digests, shared environment, and note taking
@ -35,27 +50,45 @@ TaleWeave AI can:
- Be modified in almost every way - everything is a plugin, including the planning and action stages that drive the simulation
- Be run locally - does not require any cloud services, but does play nicely with them
- Connect to your data - game systems can fetch data for RAG, making responses richer and more consistent
- Export training data - for analysis and fine tuning of character models
- Export training data - for analysis, visualization, and fine tuning of character models
- Plug in to your workflow - run the simulation step by step in Jupyter notebooks using the TaleWeave AI engine as a Python library
- Connect to your server and vice versa - the Discord bot is a plugin and can be replaced with your favorite chat platform
## Contents
### Game Actions
- [TaleWeave AI](#taleweave-ai)
- [Features](#features)
- [Contents](#contents)
- [Requirements](#requirements)
- [Recommended](#recommended)
- [Setup](#setup)
- [Documentation](#documentation)
- [Contributing](#contributing)
- [Support and Community](#support-and-community)
- [License](#license)
TaleWeave AI has in-game actions for:
| Core | Life Sim | RPG |
| ------------ | --------------- | --------- |
| Planning | Hunger & Thirst | Combat |
| Conversation | Hygiene | Crafting |
| Movement | Sleeping | Magic |
| Exploration | | Movement* |
| | | Writing |
1. The core exploration actions provide ways for characters to expand the world by finding new rooms and items.
2. The RPG movement actions provide additional situational movement like crawling, climbing, and jumping.
### Game Systems
TaleWeave AI has game systems for:
| Core | Life Sim | RPG | Environment |
| -------- | --------------- | ------ | ----------- |
| Acting | Hunger & Thirst | Health | Humidity |
| Planning | Hygiene | Quests | Temperature |
| Summary | Mood | | Time of day |
| | Sleeping | | Weather |
1. The core summary system provides character with a summary of actions taken by other characters in between turns.
All of the game systems are optional, including the core systems, so you can configure a world where characters only
plan and never act, or vice versa.
## Requirements
- Python 3.10
- Ollama, vLLM, or another OpenAI-compatible LLM API (including OpenAI)
- Python 3.10+
- Ollama or an OpenAI-compatible LLM API like llama.cpp, vLLM, or OpenAI
While TaleWeave AI can be run entirely on CPU, one or more GPUs are highly recommended.

View File

@ -11,7 +11,7 @@ from taleweave.context import (
world_context,
)
from taleweave.errors import ActionError
from taleweave.systems.action import ACTION_SYSTEM_NAME
from taleweave.systems.core.action import ACTION_SYSTEM_NAME
from taleweave.utils.conversation import loop_conversation
from taleweave.utils.search import (
find_character_in_room,

View File

@ -1,5 +1,4 @@
from logging import getLogger
from typing import Callable, List
from packit.agent import Agent, agent_easy_connect
@ -22,7 +21,7 @@ from taleweave.generate import (
generate_room,
link_rooms,
)
from taleweave.systems.action import ACTION_SYSTEM_NAME
from taleweave.systems.core.action import ACTION_SYSTEM_NAME
from taleweave.utils.effect import apply_effects, is_effect_ready
from taleweave.utils.search import find_character_in_room
from taleweave.utils.string import normalize_name
@ -254,7 +253,7 @@ def action_use(item: str, target: str) -> str:
return outcome
def init_optional() -> List[Callable]:
def init():
"""
Initialize the custom actions.
"""

View File

@ -8,7 +8,7 @@ from taleweave.context import (
)
from taleweave.errors import ActionError
from taleweave.models.planning import CalendarEvent
from taleweave.systems.planning import PLANNING_SYSTEM_NAME
from taleweave.systems.core.planning import PLANNING_SYSTEM_NAME
from taleweave.utils.planning import get_recent_notes
from taleweave.utils.template import format_prompt

View File

@ -60,8 +60,8 @@ if True:
from taleweave.models.prompt import PromptLibrary
from taleweave.plugins import load_plugin
from taleweave.state import save_world_state
from taleweave.systems.action import init_action
from taleweave.systems.planning import init_planning
from taleweave.systems.core.action import init_action
from taleweave.systems.core.planning import init_planning
def int_or_inf(value: str) -> float | int:

View File

@ -159,7 +159,7 @@ def init():
subscribe(GameEvent, digest_listener)
return [
GameSystem(
"digest",
"summary",
format=format_digest,
generate=generate_digest,
initialize=initialize_digest,

View File

@ -0,0 +1,24 @@
from os import path
from taleweave.systems.generic.logic import load_logic
def logic_path(system: str) -> str:
return path.join(".", "taleweave", "systems", "environment", system, "logic.yaml")
SYSTEM_NAMES = [
"humidity",
"temperature",
"weather",
]
def init_logic():
systems = []
for system_name in SYSTEM_NAMES:
logic_file = logic_path(system_name)
if path.exists(logic_file):
systems.append(load_logic(logic_file))
return systems

View File

@ -0,0 +1,40 @@
rules:
# wet/dry logic
- group: environment-moisture
match:
type: character
wet: true
chance: 0.1
set:
wet: false
- group: environment-moisture
match:
type: character
wet: true
temperature: hot
chance: 0.2
set:
wet: false
- group: environment-temperature
match:
type: room
temperature: hot
chance: 0.2
trigger: [taleweave.systems.sim.environment_triggers:hot_room]
- group: environment-temperature
match:
type: room
temperature: cold
chance: 0.2
trigger: [taleweave.systems.sim.environment_triggers:cold_room]
labels:
- match:
type: character
wet: true
backstory: You are soaking wet.
description: They are soaking wet and dripping water.
# false intentionally omitted

View File

@ -10,14 +10,14 @@ from taleweave.context import get_dungeon_master
from taleweave.game_system import GameSystem
from taleweave.models.base import dataclass
from taleweave.models.entity import Room, World, WorldEntity
from taleweave.systems.logic import load_logic
from taleweave.systems.generic.logic import load_logic
from taleweave.utils.string import or_list
logger = getLogger(__name__)
LOGIC_FILES = [
"./taleweave/systems/weather/weather_logic.yaml",
"./taleweave/systems/environment/weather/logic.yaml",
]

View File

@ -1,21 +1,51 @@
from .crafting_actions import action_craft
from .language_actions import action_read
from .magic_actions import action_cast
from .movement_actions import action_climb
from os import path
from taleweave.systems.generic.logic import load_logic
from .crafting.actions import action_craft
from .magic.actions import action_cast
from .movement.actions import action_climb
from .quest.actions import accept_quest, submit_quest
from .writing.actions import action_read, action_write
def logic_path(system: str) -> str:
return path.join(".", "taleweave", "systems", "rpg", system, "logic.yaml")
SYSTEM_NAMES = [
"combat",
"crafting",
"health",
"magic",
"movement",
"quest",
"writing",
]
def init_actions():
return [
# crafting
action_craft,
# language
action_read,
# magic
action_cast,
# movement
action_climb,
# quest
accept_quest,
submit_quest,
# writing
action_read,
action_write,
]
def init_logic():
return []
systems = []
for system_name in SYSTEM_NAMES:
logic_file = logic_path(system_name)
if path.exists(logic_file):
systems.append(load_logic(logic_file, name_prefix=system_name))
return systems

View File

View File

View File

View File

@ -1,14 +1,15 @@
from taleweave.context import action_context, get_system_data
from taleweave.errors import ActionError
from taleweave.systems.quest import (
from taleweave.utils.search import find_character_in_room
from taleweave.utils.template import format_prompt
from .system import (
QUEST_SYSTEM,
complete_quest,
get_active_quest,
get_quests_for_character,
set_active_quest,
)
from taleweave.utils.search import find_character_in_room
from taleweave.utils.template import format_prompt
def accept_quest(character: str, quest: str) -> str:

View File

@ -15,7 +15,7 @@ from taleweave.models.entity import (
World,
WorldEntity,
)
from taleweave.systems.logic import match_logic
from taleweave.systems.generic.logic import match_logic
from taleweave.utils.search import (
find_entity_reference,
find_item_in_container,

View File

@ -19,3 +19,21 @@ def action_read(item: str) -> str:
return str(action_item.attributes["text"])
return f"The {item} has nothing to read."
def action_write(item: str, text: str) -> str:
"""
Write on an item like a book or a sign.
Args:
item: The name of the item to write on.
text: The text to write.
"""
with action_context() as (_, action_character):
action_item = find_item_in_character(action_character, item)
if not action_item:
return f"You do not have a {item} to write on."
action_item.attributes["text"] = text
broadcast(f"{action_character.name} writes on {item}")
return f"You write on the {item}."

View File

@ -1,15 +1,21 @@
from taleweave.systems.logic import load_logic
from os import path
from .hunger_actions import action_cook, action_eat
from .hygiene_actions import action_wash
from .sleeping_actions import action_sleep
from taleweave.systems.generic.logic import load_logic
LOGIC_FILES = [
"./taleweave/systems/sim/environment_logic.yaml",
"./taleweave/systems/sim/hunger_logic.yaml",
"./taleweave/systems/sim/hygiene_logic.yaml",
"./taleweave/systems/sim/mood_logic.yaml",
"./taleweave/systems/sim/sleeping_logic.yaml",
from .hunger.actions import action_cook, action_eat
from .hygiene.hygiene_actions import action_wash
from .sleeping.actions import action_sleep
def logic_path(system: str) -> str:
return path.join(".", "taleweave", "systems", "sim", system, "logic.yaml")
SYSTEM_NAMES = [
"hunger",
"hygiene",
"mood",
"sleeping",
]
@ -26,4 +32,10 @@ def init_actions():
def init_logic():
return [load_logic(filename) for filename in LOGIC_FILES]
systems = []
for system_name in SYSTEM_NAMES:
logic_file = logic_path(system_name)
if path.exists(logic_file):
systems.append(load_logic(logic_file, name_prefix=system_name))
return systems