mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-10-06 23:12:22 +02:00
Snapshot current maintainer-preview application changes and regression fixtures for integration into lab. Excludes local runtime data, evaluation outputs and source backups. Focused Python regression selection: 140 passed; full suite not certified.
94 lines
4.5 KiB
Python
94 lines
4.5 KiB
Python
from types import SimpleNamespace
|
|
|
|
import pytest
|
|
|
|
from src.clean_agent_preview import dependent_write_prerequisite_error, required_read_tool_choice
|
|
from src.turn_contract import selected_tools_for_request
|
|
|
|
|
|
@pytest.mark.parametrize('prompt', [
|
|
'delete my last chat', 'remove my previous conversation',
|
|
'archive my last session', 'rename my last chat',
|
|
])
|
|
def test_session_mutations_include_lookup(prompt):
|
|
assert selected_tools_for_request(prompt) == {'list_sessions', 'manage_session'}
|
|
|
|
|
|
def contract():
|
|
return SimpleNamespace(required={'list_sessions', 'manage_session'},
|
|
required_read_operation=None, permits=lambda name: True)
|
|
|
|
|
|
def test_lookup_precedes_mutation_and_clarification_remains_possible():
|
|
tools = [{'function': {'name': name}} for name in ('manage_session', 'list_sessions')]
|
|
assert required_read_tool_choice(contract(), tools) == {
|
|
'type': 'function', 'function': {'name': 'list_sessions'}}
|
|
assert required_read_tool_choice(contract(), tools, calls=1,
|
|
attempted_required_tools={'list_sessions'}) is None
|
|
|
|
|
|
def test_failed_or_missing_lookup_cannot_unlock_mutation():
|
|
assert dependent_write_prerequisite_error(contract(), 'manage_session', set())
|
|
assert dependent_write_prerequisite_error(contract(), 'manage_session', {'web_search'})
|
|
assert dependent_write_prerequisite_error(contract(), 'manage_session', {'list_sessions'}) is None
|
|
|
|
|
|
def test_unavailable_lookup_does_not_force_delete():
|
|
assert required_read_tool_choice(contract(), [{'function': {'name': 'manage_session'}}]) is None
|
|
assert dependent_write_prerequisite_error(contract(), 'manage_session', set())
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_stream_orders_lookup_before_mutation_without_touching_real_chats(monkeypatch):
|
|
import json
|
|
from dataclasses import replace
|
|
import src.clean_agent_preview as module
|
|
from src.tool_policy import ToolPolicy
|
|
from src.tool_schemas import FUNCTION_TOOL_SCHEMAS
|
|
from src.turn_contract import resolve_full_inventory_contract
|
|
|
|
calls, requests = [], []
|
|
def tool(name, args):
|
|
return {'tool_calls': [{'index': 0, 'id': name, 'type': 'function',
|
|
'function': {'name': name, 'arguments': json.dumps(args)}}]}
|
|
responses = iter([tool('list_sessions', {}),
|
|
tool('manage_session', {'action': 'delete', 'session_id': 'fixture-previous'}),
|
|
{'content': 'Deleted the previous fixture chat.'}])
|
|
class Response:
|
|
def __init__(self, delta): self.delta = delta
|
|
async def __aenter__(self): return self
|
|
async def __aexit__(self, *args): pass
|
|
def raise_for_status(self): pass
|
|
async def aiter_lines(self):
|
|
yield 'data: ' + json.dumps({'choices': [{'delta': self.delta}]})
|
|
yield 'data: [DONE]'
|
|
class Client:
|
|
def __init__(self, **kwargs): pass
|
|
async def __aenter__(self): return self
|
|
async def __aexit__(self, *args): pass
|
|
def stream(self, *args, **kwargs):
|
|
requests.append(kwargs['json'])
|
|
return Response(next(responses))
|
|
async def execute(block, **kwargs):
|
|
calls.append(block.tool_type)
|
|
result = ('fixture-current: current chat; fixture-previous: previous chat'
|
|
if block.tool_type == 'list_sessions' else 'Deleted fixture-previous')
|
|
return block.tool_type, {'results': result, 'exit_code': 0}
|
|
monkeypatch.setattr(module.httpx, 'AsyncClient', Client)
|
|
monkeypatch.setattr(module, 'execute_tool_block', execute)
|
|
policy = ToolPolicy()
|
|
schemas = [s for s in FUNCTION_TOOL_SCHEMAS
|
|
if s['function']['name'] in {'list_sessions', 'manage_session'}]
|
|
scoped = replace(resolve_full_inventory_contract(schemas=schemas, policy=policy),
|
|
required=frozenset({'list_sessions', 'manage_session'}),
|
|
active_capabilities=frozenset({'sessions'}),
|
|
capabilities=frozenset({'sessions'}))
|
|
chunks = [chunk async for chunk in module.stream_preview(
|
|
endpoint_url='http://fixture', model='test', headers={}, turn_contract=scoped,
|
|
messages=[{'role': 'user', 'content': 'delete my last chat'}],
|
|
session_id='fixture-current', owner='test', disabled_tools=set(), tool_policy=policy)]
|
|
assert calls == ['list_sessions', 'manage_session'], '\n'.join(chunks)
|
|
assert requests[0]['tool_choice']['function']['name'] == 'list_sessions'
|
|
assert requests[1].get('tool_choice') is None
|
|
assert any('[DONE]' in chunk for chunk in chunks)
|