mirror of
https://github.com/vegu-ai/talemate.git
synced 2026-05-18 05:05:39 +02:00
0.37.0 - **Director Planning** — Multi-step todo lists in director chat plus a Generate long progress action for multi-beat scene arcs. - **Auto Narration** — Unified auto-narration replacing the old Narrate after Dialogue toggle, with a chance slider and weighted action mix. - **LLM Prompt Templates Manager** — Dedicated UI tab for viewing, creating, editing, and deleting prompt templates. - **Character Folders** — Collapsible folders in the World Editor character list, synced across linked scenes. - **OpenAI Compatible TTS** — Connect any number of OpenAI-compatible TTS servers in parallel. - **KoboldCpp TTS Auto-Setup** — KoboldCpp clients with a TTS model loaded register themselves as a TTS backend. - **Model Testing Harness** — Bundled scene that runs basic capability tests against any connected LLM. Plus 27 improvements and 28 bug fixes
97 lines
3.1 KiB
Python
97 lines
3.1 KiB
Python
"""
|
|
Shared helpers for node-graph unit tests.
|
|
|
|
These tests instantiate node classes directly and invoke their `run` method
|
|
inside a `GraphContext` so that socket value setters can write to state.
|
|
Inputs that have no upstream producer are pre-loaded as properties on the
|
|
node — `Node.get_input_value` falls back to the matching property when the
|
|
input socket has no `source` connection.
|
|
|
|
Mirrors the pattern in `tests/test_nodes_scene.py::_run_node` to avoid code
|
|
duplication across the per-module node-test files.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from talemate.context import ActiveScene
|
|
from talemate.game.engine.nodes.core import (
|
|
GraphContext,
|
|
NodeVerbosity,
|
|
)
|
|
|
|
|
|
# Reserved property names cannot be set via Node.set_property — they are
|
|
# pydantic model fields on Node, not entries in the `properties` dict. Tests
|
|
# that need to override these mutate `node.properties[name]` directly.
|
|
_RESERVED_PROPERTY_NAMES = {"title", "id"}
|
|
|
|
|
|
def apply_inputs(node, inputs: dict | None):
|
|
"""Pre-load `inputs` onto the node as properties. See module docstring."""
|
|
if not inputs:
|
|
return
|
|
for k, v in inputs.items():
|
|
if k in _RESERVED_PROPERTY_NAMES:
|
|
node.properties[k] = v
|
|
else:
|
|
node.set_property(k, v)
|
|
|
|
|
|
def capture_outputs(node) -> dict:
|
|
"""Capture outputs (and a `__deactivated` companion key per output) into a
|
|
plain dict. MUST be called BEFORE the surrounding `GraphContext` is
|
|
exited — socket `.value` and `.deactivated` reads are scoped to the
|
|
active context."""
|
|
outputs = {sock.name: sock.value for sock in node.outputs}
|
|
outputs.update(
|
|
{f"{sock.name}__deactivated": sock.deactivated for sock in node.outputs}
|
|
)
|
|
return outputs
|
|
|
|
|
|
async def run_node(
|
|
node,
|
|
*,
|
|
scene=None,
|
|
inputs: dict | None = None,
|
|
verbosity: NodeVerbosity = NodeVerbosity.NORMAL,
|
|
state_setup=None,
|
|
):
|
|
"""Run a node inside a GraphContext.
|
|
|
|
Parameters
|
|
----------
|
|
node:
|
|
Node instance to run.
|
|
scene:
|
|
Optional Scene to bind via `ActiveScene` for the duration of the run.
|
|
Many nodes call `talemate.context.active_scene.get()` and need this.
|
|
inputs:
|
|
Dict of {name: value} pre-loaded as properties on `node`. The node's
|
|
`get_input_value(name)` falls back to the property value when the
|
|
input socket has no source connected.
|
|
verbosity:
|
|
GraphState.verbosity to use for the run.
|
|
state_setup:
|
|
Optional `state_setup(state)` callback invoked AFTER the GraphContext
|
|
is created and BEFORE `node.run(state)`. Use to seed `state.data` /
|
|
`state.shared` etc.
|
|
|
|
Returns a dict of {output_name: value} plus {f"{name}__deactivated": bool}
|
|
for each output socket.
|
|
"""
|
|
apply_inputs(node, inputs)
|
|
|
|
async def _run():
|
|
with GraphContext() as state:
|
|
state.verbosity = verbosity
|
|
if state_setup:
|
|
state_setup(state)
|
|
await node.run(state)
|
|
return capture_outputs(node)
|
|
|
|
if scene is not None:
|
|
with ActiveScene(scene):
|
|
return await _run()
|
|
return await _run()
|