refactor: split flat core into capability packages, layer the conversations service, English defaults for every model-facing text
This commit is contained in:
+22
-22
@@ -17,24 +17,24 @@ from test_conversations import ScriptedClient, World, world
|
||||
|
||||
from beaver_gateway.agents.claude import ClaudeAgent, ClaudeOptions
|
||||
from beaver_gateway.backends.claude_sdk import ClaudeSdkBackend
|
||||
from beaver_gateway.core.conversations import ConversationTexts
|
||||
from beaver_gateway.core.distill import (
|
||||
from beaver_gateway.conversations.service import ConversationTexts
|
||||
from beaver_gateway.conversations.distill import (
|
||||
Distiller,
|
||||
DistillContext,
|
||||
LineCap,
|
||||
check_digest,
|
||||
trim_summary,
|
||||
)
|
||||
from beaver_gateway.core.gateway_tools import _tools, build_tool_server
|
||||
from beaver_gateway.core.registry import AgentRegistry
|
||||
from beaver_gateway.core.scheduler import Job, JobRun, Scheduler
|
||||
from beaver_gateway.core.transcript import build_entries
|
||||
from beaver_gateway.conversations.tools import _tools, build_tool_server
|
||||
from beaver_gateway.app import AgentRegistry
|
||||
from beaver_gateway.jobs.scheduler import Job, JobRun, Scheduler
|
||||
from beaver_gateway.backends.transcript import build_entries
|
||||
from beaver_gateway.storage.models import Conversation
|
||||
|
||||
__all__ = ["world"]
|
||||
|
||||
DIGEST = """---
|
||||
type: выжимка
|
||||
type: digest
|
||||
source: "[[{chat}]]"
|
||||
date: 2026-08-29
|
||||
---
|
||||
@@ -59,7 +59,7 @@ class DistillerClient(ScriptedClient):
|
||||
async def receive_response(self):
|
||||
prompt = self.prompts[-1]
|
||||
written: list[ToolUseBlock] = []
|
||||
if self.write and self.digest_dir is not None and "файл не пиши" not in prompt:
|
||||
if self.write and self.digest_dir is not None and "write no file" not in prompt:
|
||||
chat = prompt.split("«", 1)[1].split("»", 1)[0] if "«" in prompt else "чат"
|
||||
path = self.digest_dir / "2026-08-29 - тема.md"
|
||||
path.write_text(self.frontmatter.format(chat=chat), encoding="utf-8")
|
||||
@@ -226,7 +226,7 @@ async def test_distill_writes_the_digest_indexes_it_and_merges_short(
|
||||
assert result.digest.path == config.dir / "2026-08-29 - тема.md"
|
||||
assert result.digest.source == "[[2026-08-20 - тема чата]]"
|
||||
index = config.index.read_text(encoding="utf-8")
|
||||
assert index.startswith("# индекс")
|
||||
assert index.startswith("# index")
|
||||
assert "- 2026-08-29 [[2026-08-20 - тема чата]] → [[2026-08-29 - тема]]" in index
|
||||
assert result.text.count("\n") == 2 and not result.trimmed
|
||||
closed = await world.conversations.get(chat.external_id)
|
||||
@@ -236,9 +236,9 @@ async def test_distill_writes_the_digest_indexes_it_and_merges_short(
|
||||
fork = await world.conversations.get(result.fork.external_id)
|
||||
assert fork.kind == "fork" and fork.agent_name == "x" and fork.status == "closed"
|
||||
items = await world.conversations.queue.recent(master.id)
|
||||
assert items[0].origin == "выжимка"
|
||||
assert items[0].origin == "digest"
|
||||
assert items[0].text.startswith(
|
||||
"Закрыт глубокий чат [[2026-08-20 - тема чата]], выжимка [[2026-08-29 - тема]]."
|
||||
"Deep chat [[2026-08-20 - тема чата]] closed, digest [[2026-08-29 - тема]]."
|
||||
)
|
||||
assert items[0].text.endswith(result.text)
|
||||
forked = ScriptedClient.instances[-1]
|
||||
@@ -270,8 +270,8 @@ async def test_memory_off_merges_without_a_file(world: World) -> None:
|
||||
assert (await world.conversations.get(chat.external_id)).status == "closed"
|
||||
items = await world.conversations.queue.recent(master.id)
|
||||
assert len(items) == 1 and items[0].text.endswith(result.text)
|
||||
assert ", выжимка" not in items[0].text
|
||||
assert "файл не пиши" in ScriptedClient.instances[-1].prompts[0]
|
||||
assert ", digest" not in items[0].text
|
||||
assert "write no file" in ScriptedClient.instances[-1].prompts[0]
|
||||
|
||||
|
||||
async def test_bad_frontmatter_and_long_merge_are_reported(world: World) -> None:
|
||||
@@ -294,13 +294,13 @@ async def test_bad_frontmatter_and_long_merge_are_reported(world: World) -> None
|
||||
def test_check_digest_rejects_what_is_not_a_digest(tmp_path: Path) -> None:
|
||||
config = Distiller(agent="x", dir=tmp_path, index=tmp_path / "i.md")
|
||||
path = tmp_path / "d.md"
|
||||
path.write_text("---\ntype: выжимка\nsource: ''\ndate: 2026-08-29\n---\nx\n")
|
||||
assert check_digest(path, config) == "`source` пустой"
|
||||
path.write_text("---\ntype: выжимка\nsource: '[[a]]'\ndate: вчера\n---\nx\n")
|
||||
path.write_text("---\ntype: digest\nsource: ''\ndate: 2026-08-29\n---\nx\n")
|
||||
assert check_digest(path, config) == "`source` is empty"
|
||||
path.write_text("---\ntype: digest\nsource: '[[a]]'\ndate: вчера\n---\nx\n")
|
||||
assert "`date`" in check_digest(path, config)
|
||||
path.write_text("---\ntype: выжимка\nsource: '[[a]]'\ndate: 2026-08-29\n---\n\n")
|
||||
assert check_digest(path, config) == "тело пустое"
|
||||
path.write_text("---\ntype: выжимка\nsource: '[[a]]'\ndate: 2026-08-29\n---\nx\n")
|
||||
path.write_text("---\ntype: digest\nsource: '[[a]]'\ndate: 2026-08-29\n---\n\n")
|
||||
assert check_digest(path, config) == "empty body"
|
||||
path.write_text("---\ntype: digest\nsource: '[[a]]'\ndate: 2026-08-29\n---\nx\n")
|
||||
digest = check_digest(path, config)
|
||||
assert not isinstance(digest, str) and digest.date.isoformat() == "2026-08-29"
|
||||
assert trim_summary("a\n\nb\nc\nd\ne\nf") == ("a\nb\nc\nd\ne", True)
|
||||
@@ -347,7 +347,7 @@ async def test_close_chat_tool_closes_after_the_reply(world: World) -> None:
|
||||
assert row.flags["closed_reason"] == "close_chat"
|
||||
assert row.flags["digest"] is not None
|
||||
items = await world.conversations.queue.recent(master.id)
|
||||
assert items[0].origin == "выжимка"
|
||||
assert items[0].origin == "digest"
|
||||
|
||||
|
||||
async def test_idle_picks_quiet_chats_after_launch_at_most_limit(world: World) -> None:
|
||||
@@ -412,8 +412,8 @@ async def test_line_cap_bounces_a_long_rewrite_and_asks_to_shorten(
|
||||
|
||||
client = ScriptedClient.instances[-1]
|
||||
assert len(client.prompts) == 2
|
||||
assert "70 строк при потолке 60" in client.prompts[1]
|
||||
assert "[инжект: потолок" in client.prompts[1]
|
||||
assert "70 lines against a cap of 60" in client.prompts[1]
|
||||
assert "[inject: cap" in client.prompts[1]
|
||||
assert state.read_text(encoding="utf-8").count("\n") == 10 - 1
|
||||
row = await world.conversations.get(job.external_id)
|
||||
assert row.flags["line_cap_attempts"] == 1
|
||||
|
||||
Reference in New Issue
Block a user