Register Mistral as a first-class provider with LiteLLM routing,
MISTRAL_API_KEY env var, and https://api.mistral.ai/v1 default base.
Includes schema field, registry entry, and tests.
Move ThinkingSpinner and StreamRenderer into a dedicated module to keep
commands.py focused on orchestration. Uses Rich Live with manual refresh
(auto_refresh=False) and ellipsis overflow for stable streaming output.
Made-with: Cursor
Preserve the provider and agent-loop streaming primitives plus the CLI experiment scaffolding so this work can be resumed later without blocking urgent bug fixes on main.
Made-with: Cursor
Merge process_direct() and process_direct_outbound() into a single
interface returning OutboundMessage | None. This eliminates the
dual-path detection logic in CLI single-message mode that relied on
inspect.iscoroutinefunction to distinguish between the two APIs.
Extract status rendering into a pure function build_status_content()
in utils/helpers.py, decoupling it from AgentLoop internals.
Made-with: Cursor
Keep status output responsive while estimating current context from session history, dropping low-value queue/subagent counters, and marking command-style replies for plain-text rendering in CLI. Also route direct CLI calls through outbound metadata so help/status formatting stays explicit instead of relying on content heuristics.
Made-with: Cursor
Handle /status at the run-loop level so it can return immediately while the agent is busy, and reset last-usage stats when providers omit usage data. Also keep Telegram help/menu coverage for /status without changing the existing final-response send path.
Made-with: Cursor
Only normalize nullable MCP tool schemas for OpenAI-compatible providers so optional params still work without collapsing unrelated unions. Also teach local validation to honor nullable flags and add regression coverage for nullable and non-nullable schemas.
Made-with: Cursor
Keep multimodal tool outputs on the native content-block path while
restoring redirect SSRF checks for web_fetch image responses. Also share
image block construction, simplify persisted history sanitization, and
add regression tests for image reads and blocked private redirects.
Made-with: Cursor
Exclude openai_codex alongside github_copilot from generated config,
filter OAuth-only providers out of the onboarding wizard, and clarify in
README that OAuth login stores session state outside config. Also unify
the GitHub Copilot login command spelling and add regression tests.
Made-with: Cursor
Keep messages already collected in the current poll cycle when a stale
IMAP connection dies mid-fetch, so retrying once does not drop emails
that were already parsed and marked seen. Add a regression test covering
a mid-cycle disconnect after the first message succeeds.
Made-with: Cursor
Record run_at_ms, status, duration_ms and error for each execution,
keeping the last 20 entries per job in jobs.json. Adds CronRunRecord
dataclass, get_job() lookup, and four regression tests covering
success, error, trimming and persistence.
Closes#1837
Made-with: Cursor
- wire tools.exec.enable and deny_patterns into the current AgentLoop
- preserve the current WebSearchTool config-based registration path
- treat deny_patterns=[] as an explicit override instead of falling back
to the default blacklist
- add regression coverage for disabled exec registration and custom deny
patterns
Made-with: Cursor
- Mask sensitive fields (api_key/token/secret/password) in all display
surfaces, showing only the last 4 characters
- Replace all emoji with pure ASCII labels for consistent cross-platform
terminal rendering
- Extract _print_summary_panel helper, eliminating 5x duplicate table
construction in _show_summary
- Replace 3 one-line wrapper functions with declarative _SETTINGS_SECTIONS
dispatch tables and _MENU_DISPATCH in run_onboard
- Extract _handle_model_field / _handle_context_window_field into a
_FIELD_HANDLERS registry, shrinking _configure_pydantic_model
- Return FieldTypeInfo NamedTuple from _get_field_type_info for clarity
- Replace global mutable _PROVIDER_INFO / _CHANNEL_INFO with @lru_cache
- Use vars() instead of dir() in _get_channel_info for reliable config
class discovery
- Defer litellm import in model_info.py so non-wizard CLI paths stay fast
- Clarify README Quick Start wording (Add -> Configure)
Cherry-pick from d6acf1a with manual merge resolution.
Keep onboarding edits in draft state until users choose Done or Save and
Exit, so backing out or discarding the wizard no longer persists partial
changes.
Co-Authored-By: Jason Zhao <144443939+JasonZhaoWW@users.noreply.github.com>
Tests for non-interactive onboard mode now explicitly use --no-interactive
flag since the default changed to interactive mode.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
MCP servers (e.g. Zapier) return JSON Schema union types like
`"type": ["string", "null"]` for nullable parameters. The existing
`validate_params()` and `cast_params()` methods expected only simple
strings as `type`, causing `TypeError: unhashable type: 'list'` on
every MCP tool call with nullable parameters.
Add `_resolve_type()` helper that extracts the first non-null type
from union types, and use it in `_cast_value()` and `_validate()`.
Also handle `None` values correctly when the schema declares a
nullable type.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The root cause of "Pool timeout" errors is that long-polling (getUpdates)
and outbound API calls (send_message, send_photo, etc.) shared the same
HTTPXRequest pool — polling holds connections indefinitely, starving sends
under concurrent load (e.g. cron jobs + user chat).
- Split into two independent pools: API calls (default 32) and polling (4)
- Expose connection_pool_size / pool_timeout in TelegramConfig for tuning
- Add _call_with_retry() with exponential backoff (3 attempts) on TimedOut
- Apply retry to _send_text and remote media URL sends
Tests the helpers directly without needing CronService, covering all
schedule kinds, edge cases (missing fields, unknown status), and
combined state output.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Covers all three schedule kinds (cron/every/at), human-readable interval
formatting, run state display (last run, status, errors, next run),
and disabled job filtering.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>