Skip to content

⬆️ chore: traer PRs upstream #177, #178, #151, #160#2

Merged
paulpwo merged 11 commits intomainfrom
Chore/UpstreamPRs177-178-151-160
Apr 11, 2026
Merged

⬆️ chore: traer PRs upstream #177, #178, #151, #160#2
paulpwo merged 11 commits intomainfrom
Chore/UpstreamPRs177-178-151-160

Conversation

@paulpwo
Copy link
Copy Markdown
Owner

@paulpwo paulpwo commented Apr 11, 2026

Que hace este PR?

Cherry-pick de 4 PRs del upstream RichardAtCT/claude-code-telegram seleccionados por relevancia y seguridad:

Por que?

RichardAtCT#177 y RichardAtCT#178 son prerequisitos de confiabilidad para el scheduler (jobs SDD automatizados). RichardAtCT#151 da control desde Telegram. RichardAtCT#160 permite ajustar el modelo según la tarea sin reiniciar el bot.

Se omitió RichardAtCT#165 (per-chat routing) por riesgo de prompt injection desde el buffer de mensajes de grupo.

Como probarlo?

  • ENABLE_SCHEDULER=true/schedule list responde correctamente
  • /schedule add "0 9 * * *" "analiza el repo" → job creado
  • /model → inline keyboard con Opus/Sonnet/Haiku
  • Job que tarda >1s no se dropea (verificar logs del scheduler)

Matvii Sakhnenko and others added 11 commits April 10, 2026 20:02
With misfire_grace_time=300, heartbeats were still missed when the bot
was busy for >5 minutes (observed: 8m54s miss). Setting to None
guarantees every job fires exactly once, combined with coalesce=True
to prevent duplicate execution.
AgentHandler.handle_scheduled now dispatches work via asyncio.create_task
and returns immediately, preventing long Claude executions from blocking
the event bus and causing missed heartbeats. A semaphore (max 2) caps
concurrent Claude executions. handle_webhook remains unchanged.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add "scheduler" key to the bot deps dict and assign the real
JobScheduler instance after creation in run_application(), making
it accessible to command handlers via context.bot_data["scheduler"].
pause_job() removes job from APScheduler and sets is_active=0.
resume_job() re-registers with APScheduler and sets is_active=1.
list_jobs() now accepts include_paused flag to show all jobs.
Single /schedule entry point dispatching to subcommands:
list, add, remove, pause, resume. Auto-populates chat_id,
working_directory, and created_by from Telegram context.
Add /schedule handler to both agentic and classic mode registration,
gated on enable_scheduler. Add to get_bot_commands() for Telegram
command menu visibility.
16 tests covering all subcommands (list, add, remove, pause, resume),
argument parsing edge cases, error handling, and the scheduler-not-
available fallback path. 100% coverage on the handler module.
Update command lists in README and CLAUDE.md, expand the Job Scheduler
section in docs/setup.md with usage examples, and add CHANGELOG entry.
Add /model command with inline keyboard UI for switching between
Opus/Sonnet/Haiku models and effort levels (low/medium/high/max)
at runtime. Model changes force a new session since the CLI doesn't
support model switching on resumed sessions.

- Effort levels are model-aware: Haiku has none, Sonnet excludes
  "max", Opus supports all including "max"
- Override is per-user via context.user_data (in-memory, resets on
  bot restart)
- Threaded through all run_command call sites (orchestrator, classic
  message handler) into the SDK layer
- Registered in both agentic and classic handler modes
- Added to bot command menu and /help text
- 17 new tests covering keyboard display, model/effort selection,
  label formatting, and effort-per-model configuration

Closes RichardAtCT#138
Instead of just "Default", show "Default (claude-sonnet-4-6)" or
"Default (CLI default)" so users can verify what model is active
after resetting.
…ases

- callback.py: replace shared _model_effort_handler closure with two
  explicit lambdas (model:/effort:) — eliminates outer-scope capture;
  move import to module level
- command.py: drop _MODELS dict with hardcoded version IDs; use
  _MODEL_FAMILIES list of short CLI aliases ("opus"/"sonnet"/"haiku")
  which the CLI resolves to current latest automatically
- command.py: add CallbackQuery + ContextTypes type annotations to
  _handle_model_selection (fixes mypy strict mode)
- command.py: simplify _current_model_label (no reverse-map needed)
- command.py: add PR RichardAtCT#165 compatibility comment on force_new_session
- tests: update imports/assertions for _MODEL_FAMILIES; add 3 tests:
  closure regression guard, effort: prefix isolation, force_new_session

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@paulpwo paulpwo merged commit 8468e6d into main Apr 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants