feat(chat): add workspace chat, attachments and agent delegation
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
import asyncio
|
||||
from types import SimpleNamespace
|
||||
import pytest
|
||||
from app.contracts import ChatRequest, ToolCall, ModelCapability, Message, ModelEventType as E
|
||||
from app.services import chat_agents, chat_retrieval
|
||||
|
||||
|
||||
def test_delegation_uses_existing_runtime_limits_and_no_network(monkeypatch):
|
||||
from app.container import container
|
||||
requests = []
|
||||
async def create(request):
|
||||
requests.append(request)
|
||||
return SimpleNamespace(run_id='run_test', status=SimpleNamespace(value='queued'), output=None, error_message=None)
|
||||
monkeypatch.setattr(container.agent, 'create_run', create)
|
||||
request = ChatRequest(provider_id='local', model='model', allow_agent=True, conversation_id='chat', messages=[], workspace_context={'file_path':'draft.md','content':'unsaved'})
|
||||
call = ToolCall(tool_call_id='call', name='agent.create', arguments={'input':'summarize'})
|
||||
result = asyncio.run(chat_agents.execute(call, request))
|
||||
assert result['status'] == 'queued'
|
||||
assert requests[0].metadata['conversation_id'] == 'chat'
|
||||
assert 'unsaved' in requests[0].input
|
||||
assert requests[0].allow_network is False
|
||||
assert 'notes.patch_markdown' in requests[0].allowed_tools
|
||||
with pytest.raises(ValueError):
|
||||
asyncio.run(chat_agents.execute(call, request.model_copy(update={'allow_agent':False})))
|
||||
|
||||
|
||||
def test_chat_delegates_once_and_keeps_snapshot_in_model_context(monkeypatch):
|
||||
calls, seen = [], []
|
||||
async def execute(call, request):
|
||||
calls.append(call)
|
||||
return {'run_id':'run_test','status':'queued'}
|
||||
monkeypatch.setattr(chat_agents, 'execute', execute)
|
||||
class Adapter:
|
||||
async def stream(self, request):
|
||||
seen.append(request)
|
||||
assert 'unsaved text' in request.system
|
||||
if len(seen) < 3:
|
||||
yield chat_retrieval.event(E.tool_call_start, {'tool_call_id':'call','name':'agent.create','arguments':{'input':'work'}})
|
||||
else:
|
||||
yield chat_retrieval.event(E.text_delta, {'text':'started'})
|
||||
yield chat_retrieval.event(E.done, {})
|
||||
request = ChatRequest(provider_id='local', model='model', use_rag=False, allow_agent=True, messages=[Message(role='user',content='do work')], workspace_context={'file_path':'a.md','content':'unsaved text'})
|
||||
provider = SimpleNamespace(adapter=Adapter(), config=SimpleNamespace(capabilities=[ModelCapability.chat, ModelCapability.tool_calling]))
|
||||
async def run(): return [event async for event in chat_retrieval.stream(request, provider)]
|
||||
events = asyncio.run(run())
|
||||
assert len(calls) == 1
|
||||
assert all(t.name != 'rag.search' for t in seen[0].tools)
|
||||
assert any(e.event == E.tool_call_end and e.data.get('result',{}).get('run_id') == 'run_test' for e in events)
|
||||
assert any(e.event == E.tool_call_end and e.data['status'] == 'failed' for e in events)
|
||||
Reference in New Issue
Block a user