164 lines
4.9 KiB
Python
164 lines
4.9 KiB
Python
from pathlib import Path
|
|
|
|
from takopi.config import ProjectConfig, ProjectsConfig
|
|
from takopi.context import RunContext
|
|
from takopi.router import AutoRouter, RunnerEntry
|
|
from takopi.runners.mock import Return, ScriptRunner
|
|
from takopi.transport_runtime import TransportRuntime
|
|
|
|
|
|
def _make_runtime(*, project_default_engine: str | None = None) -> TransportRuntime:
|
|
codex = ScriptRunner([Return(answer="ok")], engine="codex")
|
|
pi = ScriptRunner([Return(answer="ok")], engine="pi")
|
|
router = AutoRouter(
|
|
entries=[
|
|
RunnerEntry(engine=codex.engine, runner=codex),
|
|
RunnerEntry(engine=pi.engine, runner=pi),
|
|
],
|
|
default_engine=codex.engine,
|
|
)
|
|
project = ProjectConfig(
|
|
alias="proj",
|
|
path=Path("."),
|
|
worktrees_dir=Path(".worktrees"),
|
|
default_engine=project_default_engine,
|
|
)
|
|
projects = ProjectsConfig(projects={"proj": project}, default_project=None)
|
|
return TransportRuntime(router=router, projects=projects)
|
|
|
|
|
|
def test_resolve_engine_uses_project_default() -> None:
|
|
runtime = _make_runtime(project_default_engine="pi")
|
|
engine = runtime.resolve_engine(
|
|
engine_override=None,
|
|
context=RunContext(project="proj"),
|
|
)
|
|
assert engine == "pi"
|
|
|
|
|
|
def test_resolve_engine_prefers_override() -> None:
|
|
runtime = _make_runtime(project_default_engine="pi")
|
|
engine = runtime.resolve_engine(
|
|
engine_override="codex",
|
|
context=RunContext(project="proj"),
|
|
)
|
|
assert engine == "codex"
|
|
|
|
|
|
def test_resolve_message_defaults_to_chat_project() -> None:
|
|
codex = ScriptRunner([Return(answer="ok")], engine="codex")
|
|
router = AutoRouter(
|
|
entries=[RunnerEntry(engine=codex.engine, runner=codex)],
|
|
default_engine=codex.engine,
|
|
)
|
|
project = ProjectConfig(
|
|
alias="proj",
|
|
path=Path("."),
|
|
worktrees_dir=Path(".worktrees"),
|
|
chat_id=-42,
|
|
)
|
|
projects = ProjectsConfig(
|
|
projects={"proj": project},
|
|
default_project=None,
|
|
chat_map={-42: "proj"},
|
|
)
|
|
runtime = TransportRuntime(router=router, projects=projects)
|
|
|
|
resolved = runtime.resolve_message(
|
|
text="hello",
|
|
reply_text=None,
|
|
chat_id=-42,
|
|
)
|
|
|
|
assert resolved.context == RunContext(project="proj", branch=None)
|
|
|
|
|
|
def test_resolve_message_uses_ambient_context() -> None:
|
|
runtime = _make_runtime()
|
|
ambient = RunContext(project="proj", branch="feat/ambient")
|
|
|
|
resolved = runtime.resolve_message(
|
|
text="hello",
|
|
reply_text=None,
|
|
ambient_context=ambient,
|
|
)
|
|
|
|
assert resolved.context == ambient
|
|
assert resolved.context_source == "ambient"
|
|
|
|
|
|
def test_resolve_message_reply_ctx_overrides_ambient() -> None:
|
|
runtime = _make_runtime()
|
|
ambient = RunContext(project="proj", branch="feat/ambient")
|
|
|
|
resolved = runtime.resolve_message(
|
|
text="hello",
|
|
reply_text="`ctx: proj @reply`",
|
|
ambient_context=ambient,
|
|
)
|
|
|
|
assert resolved.context == RunContext(project="proj", branch="reply")
|
|
assert resolved.context_source == "reply_ctx"
|
|
|
|
|
|
def test_resolve_message_directives_override_ambient() -> None:
|
|
runtime = _make_runtime()
|
|
ambient = RunContext(project="proj", branch="feat/ambient")
|
|
|
|
resolved = runtime.resolve_message(
|
|
text="/proj @main do it",
|
|
reply_text=None,
|
|
ambient_context=ambient,
|
|
)
|
|
|
|
assert resolved.context == RunContext(project="proj", branch="main")
|
|
assert resolved.context_source == "directives"
|
|
|
|
|
|
def test_resolve_message_branch_directive_merges_with_ambient_project() -> None:
|
|
runtime = _make_runtime()
|
|
ambient = RunContext(project="proj", branch="feat/ambient")
|
|
|
|
resolved = runtime.resolve_message(
|
|
text="@hotfix do it",
|
|
reply_text=None,
|
|
ambient_context=ambient,
|
|
)
|
|
|
|
assert resolved.context == RunContext(project="proj", branch="hotfix")
|
|
assert resolved.context_source == "directives"
|
|
|
|
|
|
def test_resolve_message_project_directive_clears_ambient_branch() -> None:
|
|
codex = ScriptRunner([Return(answer="ok")], engine="codex")
|
|
router = AutoRouter(
|
|
entries=[RunnerEntry(engine=codex.engine, runner=codex)],
|
|
default_engine=codex.engine,
|
|
)
|
|
projects = ProjectsConfig(
|
|
projects={
|
|
"proj": ProjectConfig(
|
|
alias="proj",
|
|
path=Path("."),
|
|
worktrees_dir=Path(".worktrees"),
|
|
),
|
|
"other": ProjectConfig(
|
|
alias="other",
|
|
path=Path("."),
|
|
worktrees_dir=Path(".worktrees"),
|
|
),
|
|
},
|
|
default_project=None,
|
|
)
|
|
runtime = TransportRuntime(router=router, projects=projects)
|
|
ambient = RunContext(project="proj", branch="feat/ambient")
|
|
|
|
resolved = runtime.resolve_message(
|
|
text="/other do it",
|
|
reply_text=None,
|
|
ambient_context=ambient,
|
|
)
|
|
|
|
assert resolved.context == RunContext(project="other", branch=None)
|
|
assert resolved.context_source == "directives"
|