mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-10-31 18:22:22 +01:00
budget_context_for_model() returns 0 when the endpoint does not prove its
context window, and compute_input_token_budget() answers 0 with the
conservative default budget (6000). The agent loop's small-local-server
clamp (`candidate_context <= 8192`) also matched 0 and cut the request to
max(1200, 0) tokens, so on any endpoint with an unreported window an open
document or a few thousand tokens of earlier context were trimmed away
before the model saw them ("5519 tokens > 1200 budget (ctx=1800)").
Apply the clamp only to a known window.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
72 lines
2.8 KiB
Python
72 lines
2.8 KiB
Python
"""An unknown context window must not be budgeted like a tiny local server (#6678).
|
|
|
|
``budget_context_for_model`` returns 0 when the endpoint does not prove its
|
|
window, and ``compute_input_token_budget`` answers 0 with the conservative
|
|
default budget. The agent loop's small-server clamp (``<= 8192``) also caught
|
|
0 and cut the request to 1200 tokens, so an open document or earlier context
|
|
of a few thousand tokens was trimmed away before the model saw it.
|
|
"""
|
|
import inspect
|
|
import json
|
|
|
|
import pytest
|
|
|
|
DONE = 'data: [DONE]\n\n'
|
|
MARKER = 'NIGHTJAR-7'
|
|
# ~3000 estimated tokens: over the old 1200 clamp, under the 6000 default.
|
|
CONTEXT = ''.join(
|
|
f'## Project-{n}\nOwner: team {n}. Status: active. Notes: routine maintenance '
|
|
'and quarterly review scheduled for every workstream in this registry.\n\n'
|
|
for n in range(60)
|
|
) + f'## Project-Alpha\nAlias: {MARKER}\n'
|
|
|
|
|
|
def _event(payload):
|
|
return 'data: ' + json.dumps(payload) + '\n\n'
|
|
|
|
|
|
async def _first_request(monkeypatch, tmp_path, context_window):
|
|
import src.agent_loop as al
|
|
from tests.test_agent_runtime_context import _patch_fake_skills
|
|
_patch_fake_skills(monkeypatch)
|
|
monkeypatch.setattr('src.tool_index.get_tool_index', lambda: None)
|
|
monkeypatch.setattr('src.model_context.budget_context_for_model',
|
|
lambda *args, **kwargs: context_window)
|
|
seen = []
|
|
|
|
async def provider(candidates, messages, **kwargs):
|
|
# Like llm_core: the per-candidate factory shapes and trims the request.
|
|
url, model, headers = candidates[0][:3]
|
|
request = kwargs['candidate_request_factory'](0, url, model, headers)
|
|
if inspect.isawaitable(request):
|
|
request = await request
|
|
seen.append((request or {}).get('messages', messages))
|
|
yield _event({'delta': 'ok'})
|
|
yield DONE
|
|
|
|
monkeypatch.setattr(al, 'stream_llm_with_fallback', provider)
|
|
history = [
|
|
{'role': 'user', 'content': 'Keep this registry for later:\n\n' + CONTEXT},
|
|
{'role': 'assistant', 'content': 'Saved.'},
|
|
{'role': 'user', 'content': 'What is the alias of Project-Alpha?'},
|
|
]
|
|
async for _ in al.stream_agent_loop('http://127.0.0.1:9/v1', 'model', history,
|
|
max_rounds=1, workspace=str(tmp_path)):
|
|
pass
|
|
assert seen, 'the provider was never called'
|
|
return json.dumps(seen[0])
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_unknown_context_window_keeps_earlier_context(monkeypatch, tmp_path):
|
|
request = await _first_request(monkeypatch, tmp_path, 0)
|
|
assert MARKER in request
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_known_small_window_is_still_clamped(monkeypatch, tmp_path):
|
|
# The clamp exists for small local servers whose window is known (n_ctx
|
|
# 2048 here); it must keep protecting them.
|
|
request = await _first_request(monkeypatch, tmp_path, 2048)
|
|
assert MARKER not in request
|