68 lines
2.2 KiB
Python
68 lines
2.2 KiB
Python
# retoor <retoor@molodetz.nl>
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
from typing import Any
|
|
|
|
from ..config import Settings
|
|
from ..errors import ToolInputError
|
|
from .store import get_store
|
|
|
|
|
|
class ChunkController:
|
|
def __init__(self, settings: Settings) -> None:
|
|
self._settings = settings
|
|
|
|
async def dispatch(self, name: str, arguments: dict[str, Any]) -> str:
|
|
if name != "read_more":
|
|
raise ToolInputError(f"Unknown chunk tool: {name}")
|
|
store = get_store()
|
|
if store is None:
|
|
return json.dumps(
|
|
{
|
|
"status": "unavailable",
|
|
"message": "No chunk store is active for this session.",
|
|
}
|
|
)
|
|
chunk_id = str(arguments.get("chunk_id", "")).strip()
|
|
if not chunk_id:
|
|
raise ToolInputError("read_more requires a chunk_id.")
|
|
text = store.get(chunk_id)
|
|
if text is None:
|
|
return json.dumps(
|
|
{
|
|
"status": "not_found",
|
|
"message": (
|
|
f"No stored content for chunk_id '{chunk_id}'. It may have expired; "
|
|
"re-run the original tool to get a fresh chunk_id."
|
|
),
|
|
}
|
|
)
|
|
|
|
offset = max(0, int(arguments.get("offset", 0) or 0))
|
|
length = int(
|
|
arguments.get("length", self._settings.max_response_chars)
|
|
or self._settings.max_response_chars
|
|
)
|
|
length = max(1, min(length, self._settings.max_response_chars))
|
|
|
|
total = len(text)
|
|
piece = text[offset : offset + length]
|
|
next_offset = offset + len(piece)
|
|
has_more = next_offset < total
|
|
return json.dumps(
|
|
{
|
|
"status": "success",
|
|
"chunk_id": chunk_id,
|
|
"offset": offset,
|
|
"shown_chars": len(piece),
|
|
"total_chars": total,
|
|
"remaining_chars": max(0, total - next_offset),
|
|
"next_offset": next_offset if has_more else None,
|
|
"has_more": has_more,
|
|
"content": piece,
|
|
},
|
|
ensure_ascii=False,
|
|
)
|