feat(agent): add persistent runtime context providers
This commit is contained in:
@@ -0,0 +1,118 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from types import SimpleNamespace
|
||||
|
||||
import pytest
|
||||
|
||||
from nanobot.agent.tools.context import RequestContext
|
||||
from nanobot.runtime_context import (
|
||||
RUNTIME_CONTEXT_HISTORY_META,
|
||||
RuntimeContextBlock,
|
||||
append_runtime_context,
|
||||
public_history_message,
|
||||
resolve_runtime_context,
|
||||
)
|
||||
from nanobot.sdk.types import snapshot_from_session
|
||||
from nanobot.session.manager import Session, _message_preview_text
|
||||
from nanobot.session.webui_turns import _title_inputs
|
||||
from nanobot.webui.transcript import _session_user_event
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_resolve_runtime_context_preserves_provider_order() -> None:
|
||||
calls: list[str] = []
|
||||
|
||||
async def first(_request: RequestContext):
|
||||
calls.append("first")
|
||||
return RuntimeContextBlock(source="first", content="one")
|
||||
|
||||
async def second(_request: RequestContext):
|
||||
calls.append("second")
|
||||
return [RuntimeContextBlock(source="second", content="two")]
|
||||
|
||||
blocks = await resolve_runtime_context(
|
||||
[first, second],
|
||||
RequestContext(channel="cli", chat_id="direct"),
|
||||
)
|
||||
|
||||
assert calls == ["first", "second"]
|
||||
assert [(block.source, block.content) for block in blocks] == [
|
||||
("first", "one"),
|
||||
("second", "two"),
|
||||
]
|
||||
|
||||
|
||||
def test_public_history_removes_only_trusted_exact_suffix() -> None:
|
||||
block = RuntimeContextBlock(source="goal", content="private goal context")
|
||||
content, marker = append_runtime_context("visible user text", [block])
|
||||
assert marker is not None
|
||||
persisted = {
|
||||
"role": "user",
|
||||
"content": content,
|
||||
RUNTIME_CONTEXT_HISTORY_META: marker,
|
||||
}
|
||||
|
||||
assert public_history_message(persisted) == {
|
||||
"role": "user",
|
||||
"content": "visible user text",
|
||||
}
|
||||
|
||||
user_authored = {
|
||||
"role": "user",
|
||||
"content": "visible user text\n\nprivate goal context",
|
||||
}
|
||||
assert public_history_message(user_authored) == user_authored
|
||||
|
||||
|
||||
def test_public_history_keeps_content_when_marker_does_not_match() -> None:
|
||||
message = {
|
||||
"role": "user",
|
||||
"content": "user-edited content",
|
||||
RUNTIME_CONTEXT_HISTORY_META: {
|
||||
"version": 1,
|
||||
"sources": ["goal"],
|
||||
"suffix": "different suffix",
|
||||
},
|
||||
}
|
||||
|
||||
assert public_history_message(message) == {
|
||||
"role": "user",
|
||||
"content": "user-edited content",
|
||||
}
|
||||
|
||||
|
||||
def test_sdk_snapshot_hides_runtime_context() -> None:
|
||||
block = RuntimeContextBlock(source="goal", content="private goal context")
|
||||
content, marker = append_runtime_context("visible user text", [block])
|
||||
session = SimpleNamespace(
|
||||
key="cli:direct",
|
||||
created_at=SimpleNamespace(isoformat=lambda: "created"),
|
||||
updated_at=SimpleNamespace(isoformat=lambda: "updated"),
|
||||
metadata={},
|
||||
messages=[{
|
||||
"role": "user",
|
||||
"content": content,
|
||||
RUNTIME_CONTEXT_HISTORY_META: marker,
|
||||
}],
|
||||
)
|
||||
|
||||
snapshot = snapshot_from_session(session)
|
||||
|
||||
assert snapshot.messages == [{"role": "user", "content": "visible user text"}]
|
||||
|
||||
|
||||
def test_webui_preview_title_and_backfill_hide_runtime_context() -> None:
|
||||
block = RuntimeContextBlock(source="goal", content="private goal context")
|
||||
content, marker = append_runtime_context("visible user text", [block])
|
||||
persisted = {
|
||||
"role": "user",
|
||||
"content": content,
|
||||
RUNTIME_CONTEXT_HISTORY_META: marker,
|
||||
}
|
||||
session = Session(key="websocket:chat", messages=[persisted])
|
||||
|
||||
assert _message_preview_text(persisted) == "visible user text"
|
||||
assert _title_inputs(session) == ("visible user text", "")
|
||||
event = _session_user_event("websocket:chat", persisted)
|
||||
assert event is not None
|
||||
assert event["text"] == "visible user text"
|
||||
Reference in New Issue
Block a user