Add compact command

This commit is contained in:
2026-07-09 15:02:25 +02:00
parent 997ff20703
commit 02481c3de6
3 changed files with 61 additions and 8 deletions

View File

@@ -55,6 +55,7 @@ journalctl -u codex-tg-bot -f
- любой текст - задача для Codex
- `/new` - новая беседа, сброс текущего `thread_id`
- `/compact` - сжать контекст текущего Codex thread
- `/model` - выбор модели и reasoning effort
- `/status` - статус задачи, thread, модели и sandbox
- `/stop` - отменить текущую задачу

View File

@@ -167,15 +167,10 @@ def _codex_config() -> CodexConfig:
return CodexConfig(codex_bin=config.CODEX_BIN)
async def _get_thread(
codex: AsyncCodex,
thread_id: str | None,
model: str | None,
effort: str | None,
) -> tuple[Any, bool]:
def _thread_kwargs(model: str | None, effort: str | None) -> dict[str, Any]:
selected_model = model or config.CODEX_DEFAULT_MODEL
thread_config = {"model_reasoning_effort": effort} if effort else None
kwargs = {
return {
"approval_mode": _approval_mode(),
"config": thread_config,
"cwd": config.WORK_DIR,
@@ -183,6 +178,15 @@ async def _get_thread(
"model": selected_model,
"sandbox": _sandbox(),
}
async def _get_thread(
codex: AsyncCodex,
thread_id: str | None,
model: str | None,
effort: str | None,
) -> tuple[Any, bool]:
kwargs = _thread_kwargs(model, effort)
if thread_id:
try:
return await codex.thread_resume(thread_id, **kwargs), True
@@ -284,3 +288,17 @@ async def run_task(
raise
yield _done_from_turn(completed_turn, thread.id, items, usage)
async def compact_thread(
thread_id: str,
model: str | None = None,
effort: str | None = None,
) -> None:
"""Start compaction for an existing Codex thread."""
async with AsyncCodex(config=_codex_config()) as codex:
if config.OPENAI_API_KEY:
await codex.login_api_key(config.OPENAI_API_KEY)
thread = await codex.thread_resume(thread_id, **_thread_kwargs(model, effort))
await thread.compact()

View File

@@ -57,6 +57,7 @@ HELP_TEXT = (
"Контекст беседы сохраняется между сообщениями в этом чате.\n\n"
"Команды:\n"
"/new - начать новую беседу (сбросить контекст)\n"
"/compact - сжать контекст текущего thread\n"
"/model - выбрать модель и уровень reasoning effort\n"
"/status - статус текущей задачи и thread\n"
"/stop - отменить выполняющуюся задачу\n"
@@ -118,6 +119,39 @@ async def cmd_new(_, message: Message):
await message.reply_text("Контекста и не было - беседа новая.")
@app.on_message(filters.command("compact") & admin)
async def cmd_compact(_, message: Message):
chat_id = message.chat.id
task = running_tasks.get(chat_id)
if task and not task.done():
await message.reply_text(
"Сейчас выполняется задача. Дождитесь завершения или отмените ее через /stop."
)
return
thread_id = chats.get(chat_id, "thread_id")
if not thread_id:
await message.reply_text("В этом чате еще нет сохраненного Codex thread.")
return
progress = await message.reply_text("Сжимаю контекст thread...")
try:
await codex_runner.compact_thread(
thread_id,
model=chats.get(chat_id, "model"),
effort=chats.get(chat_id, "effort"),
)
except Exception:
log.exception("Compact failed in chat %s", chat_id)
await progress.edit_text("Не удалось запустить compact, подробности в логах бота.")
return
await progress.edit_text(
f"Compact запущен для thread `{thread_id[:8]}...`",
parse_mode=ParseMode.MARKDOWN,
)
@app.on_message(filters.command("model") & admin)
async def cmd_model(_, message: Message):
await message.reply_text(
@@ -177,7 +211,7 @@ async def cmd_stop(_, message: Message):
@app.on_message(
filters.text
& ~filters.command(["start", "help", "new", "model", "status", "stop"])
& ~filters.command(["start", "help", "new", "compact", "model", "status", "stop"])
& admin
)
async def on_task(client: Client, message: Message):