Commit Graph
677 Commits
Author SHA1 Message Date
Henry ParkandGitHub e1d9827b21 Merge pull request #1411 from nearai/staging-promote/38dafb96-23306226661
chore: promote staging to staging-promote/ec04354c-23271447493 (2026-03-19 16:48 UTC)
2026-03-19 09:54:37 -07:00
38dafb96b1 chore: bump telegram channel version to 0.2.5 (#1410)
Bump registry version to pass check-version-bumps.sh after
channels-src/telegram/ changes.

Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>
2026-03-19 09:47:40 -07:00
CPU-216andGitHub 9c34fe90f4 chore(ci): enforce test requirement for state machine and resilience changes (#1230) (#1304) 2026-03-19 09:35:37 -07:00
Henry ParkandGitHub e582166781 Merge pull request #1396 from nearai/staging-promote/3dcccc1e-23280048384
chore: promote staging to staging-promote/ec04354c-23271447493 (2026-03-19 04:37 UTC)
2026-03-19 08:58:29 -07:00
Henry ParkandGitHub 656d1f3e86 Merge pull request #1402 from nearai/staging-promote/b9e5acf6-23283208580
chore: promote staging to staging-promote/3dcccc1e-23280048384 (2026-03-19 06:44 UTC)
2026-03-19 08:58:09 -07:00
Henry ParkandGitHub 0e3aa4f806 Merge pull request #1409 from nearai/staging-promote/07c6ca72-23302016242
chore: promote staging to staging-promote/b9e5acf6-23283208580 (2026-03-19 15:15 UTC)
2026-03-19 08:57:54 -07:00
07c6ca72e9 fix: navigate telegram E2E tests to channels subtab (#1408)
* fix: navigate telegram E2E tests to channels subtab

wasm_channel extensions (like telegram) are now rendered in the
Settings → Channels subtab, not the Extensions subtab. Update
test_telegram_hot_activation to navigate there and use the correct
card selector. Also mock /api/gateway/status which loadChannelsStatus
fetches.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* fix: select telegram card by name, not first card in channels subtab

Built-in channel cards (Web Gateway, HTTP, etc.) render first in the
channels subtab content, so .first matches them instead of the
telegram extension card. Select by has_text="Telegram" to target
the correct card.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* refactor: make gateway_status_handler parameterizable in mock helper

Address review feedback: extract default gateway status handler and
accept an optional gateway_status_handler kwarg in mock_extension_lists
for test flexibility.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>
2026-03-19 08:11:15 -07:00
b9e5acf66e fix: add missing builder field and update E2E extensions tab navigation (#1400)
- Add `builder: None` to AgentDeps initializer in e2e_telegram_message_routing
  test (field added in #712 but test not updated)
- Update go_to_extensions() in test_telegram_hot_activation to navigate via
  settings tab -> extensions subtab (extensions tab was moved to settings)

Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>
2026-03-18 23:38:33 -07:00
3dcccc1e64 feat(self-repair): wire stuck_threshold, store, and builder (#712)
* feat(self-repair): wire stuck_threshold, store, and builder (#647)

Wire the previously dead-code fields in DefaultSelfRepair:

- stuck_threshold: detect_stuck_jobs() now filters by duration, only
  reporting jobs stuck longer than the configured threshold
- with_store(): wired in agent_loop.rs from AgentDeps.store for
  tool failure tracking via Database trait
- with_builder(): wired from register_builder_tool() return value
  through AppComponents and AgentDeps for automatic tool rebuilding
- tools: passed alongside builder for hot-reload logging

Remove all #[allow(dead_code)] annotations. Add regression tests for
threshold-based filtering (both above and below threshold).

Co-Authored-By: Claude Opus 4.6 <[email protected]>

* fix: add missing `builder` field to AgentDeps in gateway workflow harness

After rebase onto staging, AgentDeps gained a `builder` field for
self-repair tool rebuilding. The gateway workflow test harness was
missing this field, causing CI compilation failure.

Co-Authored-By: Claude Opus 4.6 <[email protected]>

* ci: retrigger CI

* fix: force CI refresh after path_routing_tests dedup

* test: add E2E test for stuck job repair and tool rebuild cycle

Tests the full self-repair flow requested in review:
1. Job transitions Pending -> InProgress -> Stuck
2. detect_stuck_jobs() finds it (zero threshold)
3. repair_stuck_job() recovers it back to InProgress
4. A broken tool is repaired via MockBuilder
5. Verify builder was invoked and repair succeeded

Uses a MockBuilder (impl SoftwareBuilder) that returns successful
BuildResult without requiring an LLM or filesystem. Uses libsql
test database for the store (increment_repair_attempts, mark_tool_repaired).

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* fix(self-repair): measure stuck_duration from Stuck transition, not started_at

- Use ctx.transitions to find the most recent Stuck transition timestamp
  instead of ctx.started_at (which reflects job start, not stuck time)
- Fix StuckJob.last_activity to use stuck transition timestamp
- Remove misleading "hot-reloaded into registry" log
- Remove stray "// ci fix" comment in memory.rs
- Add regression test: backdated started_at must not inflate stuck_duration

Co-Authored-By: Claude Opus 4.6 <[email protected]>

* ci: re-trigger CI with latest changes

Co-Authored-By: Claude Opus 4.6 <[email protected]>

* fix: add type annotation to Ok(()) in test to resolve E0282

Co-Authored-By: Claude Opus 4.6 <[email protected]>

---------

Co-authored-by: Claude Opus 4.6 <[email protected]>
2026-03-18 20:51:21 -07:00
c8ee55ed19 feat(testing): add FaultInjector framework for StubLlm (#1233)
* feat(testing): add FaultInjector framework for StubLlm (#1220)

Adds a configurable fault injection framework for testing retry, failover,
and circuit breaker behavior. The FaultInjector attaches to StubLlm and
provides per-call control over failure type, timing, and sequencing.

Components:
- FaultType: maps to LlmError variants (RequestFailed, RateLimited,
  AuthFailed, InvalidResponse, IoError, ContextLengthExceeded, SessionExpired)
- FaultAction: Succeed, Fail(FaultType), Delay(Duration)
- FaultMode: SequenceOnce (play then succeed), SequenceLoop (repeat forever),
  Random (seeded xorshift64 PRNG for reproducibility)
- FaultInjector: thread-safe (AtomicU32 counter + Mutex RNG)

Integration:
- StubLlm gains optional fault_injector field via with_fault_injector()
- When set, takes precedence over should_fail/error_kind
- Backward compatible: existing StubLlm usage unchanged

Closes #1220

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* refactor(testing): address review feedback on FaultInjector

- Remove redundant .abs() in random fault comparison
- Extract check_faults() helper to DRY up StubLlm methods
- Guard xorshift seed=0 (fixed point) by mapping to 1
- Add StubLlm integration test (stub_llm_fault_injector_sequence)
- Remove dead seed field from FaultMode::Random
- Move pub mod fault_injection to top of mod.rs
- Add Debug impl for FaultInjector
- Add empty_sequence_always_succeeds test
- Add random_seed_zero_does_not_always_fail test

* fix(testing): address #1233 review -- seed-0 bug, reset(), Debug derive

- Store seed in FaultMode::Random so reset() can re-init the RNG
- Add reset() method for test reproducibility (re-seeds RNG, zeros counter)
- Strengthen seed=0 regression test to 100 iterations with stricter assertion
- Add reset_restores_random_rng_from_stored_seed test
- Debug impl and empty_sequence test were already present from prior commit

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* ci: re-trigger CI with latest changes

Co-Authored-By: Claude Opus 4.6 <[email protected]>

* ci: trigger new run with skip-regression-check label

Co-Authored-By: Claude Opus 4.6 <[email protected]>

* fix(testing): address PR #1233 review -- error_rate validation and edge cases

- Validate error_rate is in 0.0..=1.0 and not NaN (panics on invalid input)
- Fix error_rate==1.0 edge case: use <= instead of < so 1.0 always fails
- Add regression tests for error_rate validation (NaN, negative, >1.0)
- Add tests for error_rate boundary values (0.0 never fails, 1.0 always fails)
- Add delay action test using tokio::time::pause() for deterministic timing

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>
2026-03-18 20:38:29 -07:00
8b15f8b259 feat(telegram): support auto split large message (#1084)
* feat(telegram): support auto split large message

* fix(telegram): strengthen split_message test assertion

Replace word-by-word contains check with assert_eq! on rejoined chunks,
ensuring split_message preserves content exactly.

send_response is still used (lines 745, 753) so it is intentionally kept.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* fix(telegram): add missing split_message tests and document limitations

- Add test for sentence-boundary splitting
- Add test for hard-cut on pathological input (no spaces)
- Add test for multi-byte character safety (emoji)
- Document CJK sentence punctuation limitation
- Document trim behavior at chunk boundaries

Co-Authored-By: Claude Opus 4.6 <[email protected]>

* ci: re-trigger CI with latest changes

Co-Authored-By: Claude Opus 4.6 <[email protected]>

---------

Co-authored-by: Hans <[email protected]>
Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>
2026-03-18 20:37:00 -07:00
Henry ParkandGitHub 44d16732a7 Merge pull request #1390 from nearai/staging-promote/94e4d9d3-23273403042
chore: promote staging to staging-promote/ec04354c-23271447493 (2026-03-19 00:12 UTC)
2026-03-18 17:30:59 -07:00
Henry ParkandGitHub 94e4d9d3dd Merge pull request #1389 from nearai/main
chore: sync main and staging
2026-03-18 17:11:54 -07:00
b7a1edf346 fix: remove debug_assert guards that panic on valid error paths (#1385)
* fix: remove debug_assert guards that panic on valid error paths (#1312)

Two debug_assert! calls added in #1312 fire on expected runtime error
paths (not programmer bugs), turning graceful error returns into panics
in debug/test builds:

- state.rs: Completed→Cancelled is a user-facing error handled by
  transition_to() returning Err — not a bug
- execute.rs: empty tool_name from malformed LLM output is handled by
  ToolError::NotFound — not a bug

Removes both asserts; keeps the circuit-breaker assert (genuinely guards
a caller invariant).

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* fix: tighten empty tool name test to assert ToolError::NotFound variant

Address review feedback: assert the specific error variant instead of
just is_err() so the regression test actually enforces the expected
error path.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* style: cargo fmt

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>
2026-03-18 17:02:09 -07:00
4566181f40 feat(gateway): unified settings page with subtabs (#1191)
* feat(gateway): full settings page polish with all tiers

- Backend: add ActiveConfigSnapshot to expose resolved LLM backend,
  model, and enabled channels via /api/gateway/status
- Add missing Agent settings (daily cost cap, actions/hour, local tools)
- Add Sandbox, Routines, Safety, Skills, and Search setting groups
- Settings import/export (JSON download + file upload)
- Active env defaults shown as placeholders in Inference settings
- Styled confirmation modals replace window.confirm() for remove actions
- Global restart banner persists across settings subtab switches
- Client-side validation with min/max constraints on number inputs
- Accessibility: aria-label on inputs, role=status on save indicators
- Settings search filters rows across current subtab
- Smooth CSS transitions for conditional field visibility (showWhen)
- Tunnel settings in Channels subtab
- Mobile responsive settings layout at 768px breakpoint
- i18n keys for toolbar, search, and import/export in en + zh-CN

Co-Authored-By: Claude Opus 4.6 <[email protected]>

* feat(gateway): polish settings page and remove registered tools debug section

Remove the "Registered Tools" table from the extensions tab (debug info
not useful to end users), clean up associated CSS/i18n/JS. Additional
settings page UI polish: extension card state styling, layout refinements.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* fix(gateway): address PR review feedback [skip-regression-check]

- Use refreshCurrentSettingsTab() in SSE event handlers to reduce duplication
- Remove unused formatGroupName/formatSettingLabel helpers
- Use i18n keys for MCP Configure/Reconfigure buttons
- Add data-i18n-placeholder to settings search input
- Remove data-i18n from confirm modal button (set dynamically by showConfirmModal)
- Fix cargo fmt in main.rs

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* fix(e2e): update tests for unified settings tab layout [skip-regression-check]

- Update TABS list: replace extensions/skills with settings
- Add settings_subtab/settings_subpanel selectors to helpers
- Update test_connection, test_skills, test_extensions, test_wasm_lifecycle
  to navigate via Settings > subtab instead of top-level tabs
- Move MCP card tests to use go_to_mcp() helper (MCP is now a separate subtab)
- Remove tools table tests and mock_ext_apis tools= parameter
- Fix CSP violation: replace inline onclick on confirm modal cancel button

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* fix(gateway): address second round of PR review feedback [skip-regression-check]

- Use I18n.t() for MCP empty state, export/import toasts, confirm modal
- Fix CLI channel card using wrong channel key ('repl' -> 'cli')
- Fix settings search counting hidden rows as visible
- Add aria-label i18n for settings search input
- Add common.loadFailed i18n key (en + zh-CN)
- Update E2E tests: WASM channel tests use Channels subtab,
  remove tests use custom confirm modal instead of window.confirm

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* fix(e2e): fix WASM channel card selector and skills remove confirm [skip-regression-check]

- WASM channel tests: filter by display name to avoid matching built-in
  channel cards in the Channels subtab
- Skills remove test: click confirm modal button instead of using
  window.confirm (skill removal now uses custom confirm modal)

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* fix(gateway): address third round of PR review feedback [skip-regression-check]

- approval_needed SSE: refresh any active settings subtab, not just
  Extensions — approvals can surface from Channels/MCP setup flows too
- renderCardsSkeleton: remove nested .extensions-list wrapper that
  caused skeleton cards to render constrained inside grid cells

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* fix(e2e): fix auth_completed reload test race condition [skip-regression-check]

Use expect_response to deterministically wait for the /api/extensions
reload triggered by handleAuthCompleted → refreshCurrentSettingsTab,
instead of a fixed 600ms sleep that was too short under CI load.
Also remove stale /api/extensions/tools route handler.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* fix(e2e): debug auth_completed reload test with function counter [skip-regression-check]

Inject a counter wrapper around refreshCurrentSettingsTab to verify it's
actually called, and wait for the async fetch to complete before
asserting the reload count.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* feat(gateway): localize all settings labels, descriptions, and channel cards [skip-regression-check]

Move 120+ hardcoded strings in settings definitions (INFERENCE_SETTINGS,
AGENT_SETTINGS, NETWORKING_SETTINGS) and channel card labels to i18n
keys. Render functions now resolve labels via I18n.t() so the settings
page translates when switching locales.

Covers: group titles, setting labels/descriptions, built-in channel
names/descriptions, and the "No settings found" empty state.

Both en.js and zh-CN.js updated with all new cfg.* and channels.* keys.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* fix(gateway): localize remaining hardcoded UI strings [skip-regression-check]

- Fix export error toast using wrong i18n key (importFailed → exportFailed)
- Replace "Failed to load settings:" with I18n.t('common.loadFailed')
- Localize renderBuiltinChannelCard: "Built-in", "Active", "Inactive"
- Localize settings placeholders: "env: ", "env default", "use env default"
- Localize "✓ Saved" indicator
- Add new i18n keys to both en.js and zh-CN.js

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* fix(gateway): confirm modal a11y, Esc/click-outside, search guard [skip-regression-check]

- Add role="dialog", aria-modal="true", aria-labelledby to confirm modal
- Focus confirm button when modal opens
- Close modal on Escape key or overlay click
- Skip settings search on non-settings panels (Extensions/MCP/Skills/Channels)

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* fix(gateway): boolean tri-state, search reset on subtab switch, stale model suggestions [skip-regression-check]

Address PR review feedback:
- Boolean settings now use a tri-state select (env default / On / Off)
  instead of a checkbox, matching the pattern used by other select settings
  and allowing users to revert to the env default
- Clear search input when switching settings subtabs so stale filters
  don't carry over to the new panel
- Always assign model suggestions (even empty array) so stale IDs from a
  previous successful /v1/models fetch don't persist when the endpoint
  later returns empty

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* fix(gateway): auth_completed handler, bedrock_cross_region select, integer-only number inputs [skip-regression-check]

Address PR review feedback:
- auth_completed SSE listener now delegates to handleAuthCompleted(data)
  instead of inlining logic with a bare closeConfigureModal() call, so
  only the matching extension's modal is dismissed
- bedrock_cross_region changed from free text to select with the four
  valid values (us/eu/apac/global), matching backend validation
- Number settings now use step=1 and parseInt() instead of parseFloat(),
  preventing fractional values that the backend (u32/u64) would reject

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

---------

Co-authored-by: Claude Opus 4.6 <[email protected]>
2026-03-18 16:18:29 -07:00
ec04354c6b fix: address valid review comments from PR #1359 (#1380)
- Cache discovery_schema() with OnceLock for routine tools (fixes #1361, #1371)
- Early-return on empty event cache before allocating Vec (fixes #1369)
- Extract batch concurrent count query helper to reduce duplication
- Fix ROUTINE_OK sentinel substring matching
- Migrate crate::safety import to ironclaw_safety per project convention

Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>
2026-03-18 15:34:05 -07:00
14abd60917 fix: full_job routine runs stay running until linked job completion (#1374)
* fix: full_job routine runs stay running until linked job completion (#1317)

Previously, execute_full_job() returned RunStatus::Ok immediately after
dispatching the job, causing routine runs to be marked as completed before
the linked worker job had actually finished. This meant failure notifications
were never sent and max_concurrent guardrails stopped applying once the run
was prematurely finalized.

Changes:
- execute_full_job() now returns RunStatus::Running instead of Ok
- execute_routine() skips finalization for Running status (leaves run open)
- New sync_dispatched_runs() polls on each cron tick, checks linked job
  state, and finalizes runs when jobs reach terminal states
- New list_dispatched_routine_runs() DB method on both backends
- Deferred notifications are sent when the run is actually finalized
- consecutive_failures is preserved (not reset) while outcome is unknown

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* fix: address PR review feedback (watcher predicate, running_count safety)

- FullJobWatcher: use is_parallel_blocking() instead of is_active() so
  the watcher exits when a job reaches Completed (not terminal but
  finished executing). Fixes infinite-poll for routine jobs.
- Remove running_count decrement from sync_dispatched_runs() — in normal
  flow execute_routine() handles it; sync only runs for crash recovery
  where the counter is already 0.
- Update PR description to match actual FullJobWatcher behavior.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* fix: sync only at startup to prevent double-completion race

- Move sync_dispatched_runs() out of cron loop into startup-only path.
  During normal operation FullJobWatcher handles finalization inline;
  running sync on every tick would race with the watcher.
- Update complete_dispatched_run() to properly advance runtime fields
  (last_run_at, next_fire_at, run_count) for crash recovery — in that
  scenario execute_routine() never reached its runtime update.
- Fix stale doc comment on complete_dispatched_run().

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* fix: use boot_time filter for safe periodic sync of orphaned runs

- Add boot_time field to RoutineEngine, set to Utc::now() at creation.
- sync_dispatched_runs() now filters runs by started_at < boot_time,
  so it only processes orphans from a previous process — never races
  with FullJobWatcher instances from the current process.
- Move sync back into the cron loop (safe with boot_time filter) and
  run it BEFORE check_cron_triggers to avoid picking up freshly
  dispatched runs.
- Fix doc comments to match actual behavior.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>
2026-03-18 15:33:57 -07:00
Henry ParkandGitHub a95a84ea79 Merge pull request #1379 from nearai/staging-promote/6831bb4d-23264725970
chore: promote staging to staging-promote/f2cd1d37-23262791325 (2026-03-18 20:09 UTC)
2026-03-18 14:16:45 -07:00
Henry ParkandGitHub 2033d77579 Merge pull request #1376 from nearai/staging-promote/f2cd1d37-23262791325
chore: promote staging to staging-promote/428303af-23255149035 (2026-03-18 19:20 UTC)
2026-03-18 14:16:32 -07:00
Henry ParkandGitHub 59acab43f4 Merge pull request #1359 from nearai/staging-promote/428303af-23255149035
chore: promote staging to main (2026-03-18 16:22 UTC)
2026-03-18 14:16:06 -07:00
6831bb4d7b fix: full_job routine concurrency tracks linked job lifetime (#1372)
* fix: add FullJobWatcher to track full_job lifecycle for concurrency (#1318)

full_job routines previously bypassed max_concurrent and global concurrency
limits because execute_full_job() returned RunStatus::Ok immediately after
dispatch. This meant running_count was decremented and the routine_run row
was finalized before the actual job completed.

Introduce FullJobWatcher struct that polls store.get_job() every 5s until
the linked job reaches a non-active state, then maps the final JobState to
RunStatus. execute_full_job now creates and awaits the watcher, keeping both
the DB-level running row and the in-memory running_count elevated for the
full job duration.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* test: full_job concurrency regression tests (issue #1318)

Add two integration tests verifying full_job routine concurrency:

1. full_job_max_concurrent_blocks_second_fire_while_first_active:
   Inserts a Running routine_run (simulating an in-flight full_job) and
   verifies fire_manual returns MaxConcurrent error for max_concurrent=1.

2. global_concurrency_counts_live_full_job_runs:
   Elevates running_count to simulate a live full_job holding the global
   slot, verifies check_cron_triggers skips due routines, then releases
   the slot and verifies the routine fires.

Also makes running_count_for_test() unconditionally public so integration
tests (separate crate) can access it.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* style: fmt and clippy fixes for full_job concurrency tests

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* fix: address PR review feedback on FullJobWatcher

- Add #[doc(hidden)] to running_count_for_test() to hide from public API
- Derive MAX_POLLS from POLL_INTERVAL to keep constants coupled
- Check job state before first sleep to finalize promptly for fast jobs
- Update execute_full_job doc comment to reflect blocking behavior

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>
2026-03-18 12:29:58 -07:00
42ffefabe4 fix: remove -x from coverage pytest to prevent suite-blocking failures (#1360)
One flaky test (test_builtin_echo_tool timeout) was stopping the entire
e2e coverage suite via -x, preventing 118+ remaining tests from running
and generating coverage data.

Tests are independent (each gets a fresh browser context via the
function-scoped page fixture), so removing -x is safe.

Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>
2026-03-18 12:29:44 -07:00
20202700db Fix duplicate LLM responses for matched event routines (#1275)
* fix: consume matched event routine messages

* style: run rustfmt for event routine fix

* fix: preserve preprocessing for routine-triggered messages

* fix: match routines against rewritten input

* refactor: narrow check_event_triggers API and simplify routine_engine_slot

Address Copilot review feedback:

- Change check_event_triggers to accept (user_id, channel, content) instead
  of &IncomingMessage, eliminating the need to clone the full message
  (including attachments) when hooks rewrite content.

- Remove routine_trigger_message and the Cow<IncomingMessage> indirection;
  the event-trigger check now inlines the is_internal + UserInput guard and
  passes the post-hook content string directly.

- Make routine_engine_slot non-optional since Agent::new() always
  initializes it. Removes the redundant Option wrapper and simplifies
  accessor/setter methods.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>
2026-03-18 12:29:35 -07:00
Ikko Eltociear AshimineGitHubgemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
f2cd1d37bc docs: add Japanese README (#1306)
* docs: add Japanese README

* Update README.ja.md

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

* Update README.ja.md

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

---------

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2026-03-18 11:34:19 -07:00
07e6e30ee3 fix: add debug_assert invariant guards to critical code paths (#1312)
* fix: add debug_assert invariant guards to critical code paths (closes #1215)

Add three debug_assert! calls to catch impossible-in-correct-code states
early in debug builds without affecting release performance:

- execute_tool_with_safety: assert tool_name is non-empty at entry
- JobContext::transition_to: assert state machine transition is valid
- CircuitBreakerProvider::record_success: assert circuit is not Open
  (check_allowed() must gate all calls before record_success())

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>

* test: add regression test for empty tool name invariant guard

Covers the debug_assert!(!tool_name.is_empty()) added in execute_tool_with_safety.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>

---------

Co-authored-by: Claude Sonnet 4.6 <[email protected]>
2026-03-18 11:34:11 -07:00
OctopusandGitHub 2d0b195321 feat: upgrade MiniMax default model to M2.7 (#1357)
* feat: upgrade MiniMax default model to M2.7

- Add MiniMax-M2.7 and MiniMax-M2.7-highspeed to model list
- Set MiniMax-M2.7 as default model
- Keep all previous models as alternatives
- Update related tests

* fix: use canonical model name in test per review

Use MiniMax-M2.7-highspeed (canonical casing) in the reasoning
models test for consistency with the documentation and provider
configuration.

[skip-regression-check]
2026-03-18 11:34:05 -07:00
CPU-216andGitHub 9286978547 chore(ci): add coverage gates via codecov.yml (#1228) (#1291)
- Project target: 80% with 2% threshold (was: auto with 1%)
- Patch target: 90% (was: 80% with 5% threshold)
- Add PR comment config with reach/diff/flags layout
- Enable require_changes to reduce comment noise
2026-03-18 11:33:58 -07:00
NigeandGitHub 0be591028a fix(mcp): retry after missing session id errors (#1355) 2026-03-18 11:33:51 -07:00
NigeandGitHub 33a2dd2c78 fix(telegram): preserve polling after secret-blocked updates (#1353)
* fix(telegram): preserve polling after secret-blocked updates

* style(telegram): simplify polling leak-scan guard

* style(telegram): satisfy clippy for poll leak guard
2026-03-18 11:33:45 -07:00
NigeGitHubgemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
bedc71ebdc fix(llm): cap retry-after delays (#1351)
* fix(llm): cap retry-after delays

* Update src/llm/retry.rs

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

---------

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2026-03-18 11:33:38 -07:00
NigeandGitHub e9b0823db9 fix(setup): remove nonexistent webhook secret command hint (#1349)
* fix(setup): remove nonexistent webhook secret command hint

* test(setup): cover webhook secret onboarding hint
2026-03-18 11:33:31 -07:00
Henry ParkandGitHub 428303af11 Redesign routine create requests for LLMs (#1147)
* Redesign routine create requests for LLMs

* Fix panic-check false positives in routine tests

* Tighten routine schema requirements

* Tighten routine schema tests

* Mark test assertions safe for CI scan

* Align test assertions with panic scan

* Polish routine schema metadata

* Simplify routine test assertions

* Improve tool discovery guidance

* Clarify lightweight routine delivery prompts

* Fix routine delivery target defaults
2026-03-18 09:04:00 -07:00
Henry ParkandGitHub 9bb05d2dcd Merge pull request #1285 from nearai/staging-promote/5c56032b-23178585631
chore: promote staging to main (2026-03-17 04:34 UTC)
2026-03-17 08:43:16 -07:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
7a4673c11e chore: update WASM artifact SHA256 checksums [skip ci] (#1297)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-16 23:13:13 -07:00
Henry ParkandGitHub 059fd97ce6 Merge pull request #1296 from nearai/staging-promote/2784cef4-23180012288
chore: promote staging to staging-promote/5c56032b-23178585631 (2026-03-17 05:32 UTC)
2026-03-16 22:34:14 -07:00
2784cef4d7 fix: relax timing thresholds in policy adversarial tests (100ms -> 500ms) (#1294)
These tests guard against catastrophic regex backtracking (seconds/minutes),
not 12ms differences. CI runners with coverage instrumentation (cargo-llvm-cov)
consistently exceed the 100ms threshold due to overhead, causing flaky failures.
500ms still catches real regressions while tolerating CI variability.

[skip-regression-check]

Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>
2026-03-16 22:29:41 -07:00
Henry ParkandGitHub ef5715cb96 fix: mark ironclaw_safety unpublished in release-plz (#1286) v0.19.0 2026-03-16 21:55:49 -07:00
github-actions[bot]GitHubironclaw-ci[bot] <266877842+ironclaw-ci[bot]@users.noreply.github.com>
1ad1335fea chore: release v0.19.0 (#973)
Co-authored-by: ironclaw-ci[bot] <266877842+ironclaw-ci[bot]@users.noreply.github.com>
2026-03-16 21:39:47 -07:00
5c56032b88 fix: Rate limiter returns retry after None instead of a duration (#1269)
* fix: Rate limiter returns retry after None instead of a duration

linter fix

* review fixes

* fix: rate limiter returns None for retry_after duration

Add regression test to src/llm/retry.rs that verifies RateLimited errors
always have a fallback duration (never None) due to the 60-second fallback
applied in all rate limit error creation sites (nearai_chat.rs,
anthropic_oauth.rs, embeddings.rs).

The production code fix adds `.or(Some(Duration::from_secs(60)))` to ensure
the error message never displays "retry after None" to the user.

[skip-regression-check]

Co-Authored-By: Claude Haiku 4.5 <[email protected]>

---------

Co-authored-by: Claude Haiku 4.5 <[email protected]>
2026-03-16 20:51:49 -07:00
Henry ParkandGitHub deee24c65b Merge pull request #1197 from nearai/staging-promote/e0f393bf-23105705354
chore: promote staging to staging-promote/e74214dc-23104855330 (2026-03-15 07:18 UTC)
2026-03-16 20:39:40 -07:00
Henry ParkandGitHub 2b6404e8b2 Merge pull request #1276 from nearai/staging-promote/90655277-23176260323
chore: promote staging to staging-promote/e0f393bf-23105705354 (2026-03-17 02:56 UTC)
2026-03-16 20:25:28 -07:00
Henry ParkandGitHub 0e7eb7f390 Merge pull request #1279 from nearai/staging-promote/4675e961-23176922462
chore: promote staging to staging-promote/90655277-23176260323 (2026-03-17 03:24 UTC)
2026-03-16 20:25:16 -07:00
Henry ParkandGitHub 4675e9618c Fix Telegram auto-verify flow and routing (#1273)
* Fix Telegram auto-verify flow and routing

* Fix CI formatting and clippy follow-ups

* Simplify Telegram waiting state update

* Fix notification fallback scopes

* Fix message metadata routing and zh-CN copy
2026-03-16 20:19:43 -07:00
Henry ParkandGitHub d0cb5f0ac5 test(e2e): fix approval waiting regression coverage (#1270)
* test(e2e): fix approval waiting regression coverage

* test(e2e): address Copilot review notes
2026-03-16 20:06:15 -07:00
Nick PismenkovandGitHub 9065527761 fix: jobs limit (#1274) 2026-03-16 19:46:00 -07:00
Henry ParkandGitHub d3e392ac16 Merge pull request #1267 from nearai/staging-promote/1f209db0-23170138026
chore: promote staging to staging-promote/e0f393bf-23105705354 (2026-03-16 23:06 UTC)
2026-03-16 16:43:27 -07:00
Henry ParkandGitHub 47659e9545 Merge pull request #1268 from nearai/staging-promote/c6128f4e-23170341776
chore: promote staging to staging-promote/1f209db0-23170138026 (2026-03-16 23:13 UTC)
2026-03-16 16:43:17 -07:00
Nick PismenkovandGitHub c6128f4e41 fix: misleading UI message (#1265)
* fix: misleading UI message

* review fixes

* review fixes

* enhance test
2026-03-16 16:13:02 -07:00
Henry ParkandGitHub ed0ed40dae ci: isolate heavy integration tests (#1266)
* fix staging CI coverage regressions

* ci: cover all e2e scenarios in staging

* ci: restrict staging PR checks and fix webhook assertions

* ci: keep code style checks on PRs

* ci: preserve e2e PR coverage

* test: stabilize staging e2e coverage

* fix: propagate postgres tls builder errors

* ci: isolate heavy integration tests

* fix: clean up heavy integration CI follow-up
2026-03-16 16:10:20 -07:00
Henry ParkandGitHub 1f209db0fa fix: bump channel registry versions for promotion (#1264) 2026-03-16 16:05:48 -07:00