feat: per-conversation project binding + action-tool consent gate
- Conversations bind to a project on creation; RAG scopes to the conversation's project, not the global setting. - Action tools (web_search/fetch_url/remember) are withheld unless allow_action_tools is enabled (off by default). Settings toggle. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -57,6 +57,17 @@ def test_search_empty_query_returns_nothing():
|
||||
assert asyncio.run(s.search_documents("", _fake_embed)) == []
|
||||
|
||||
|
||||
def test_conversation_project_binding():
|
||||
s = _store()
|
||||
assert s.conversation_project("nope") is None # not created yet
|
||||
s.create_conversation("c1", "projX")
|
||||
assert s.conversation_project("c1") == "projX"
|
||||
s.create_conversation("c1", "other") # idempotent: keeps projX
|
||||
assert s.conversation_project("c1") == "projX"
|
||||
s.create_conversation("c2")
|
||||
assert s.conversation_project("c2") == "" # unscoped
|
||||
|
||||
|
||||
def test_conversation_recall_uses_vec_and_matches_brute_force():
|
||||
s = _store()
|
||||
if not s.vec_enabled:
|
||||
|
||||
@@ -41,6 +41,15 @@ def test_action_tools_registered():
|
||||
assert names == ["web_search", "remember"]
|
||||
|
||||
|
||||
def test_action_tools_gated_by_consent():
|
||||
allow = ["search_memory", "web_search", "remember", "fetch_url"]
|
||||
on = [s["function"]["name"] for s in tools.schemas_for(allow, allow_actions=True)]
|
||||
off = [s["function"]["name"] for s in tools.schemas_for(allow, allow_actions=False)]
|
||||
assert set(on) == set(allow) # all pass when actions allowed
|
||||
assert off == ["search_memory"] # action tools withheld when not
|
||||
assert tools.is_action("remember") and not tools.is_action("search_memory")
|
||||
|
||||
|
||||
class _FakeManager:
|
||||
"""Returns a tool_call on the first chat() call, plain content after."""
|
||||
def __init__(self):
|
||||
|
||||
Reference in New Issue
Block a user