Channels: GET/PUT /channels/config and POST /channels/config/test expose the IM channel configuration over the API - per-channel enable/token/allowlist editing, a connection test (Telegram runs a real getMe), and honest unavailable-adapter reporting for missing optional dependencies. The Settings UI grows a channel-configuration section (ChannelConfigSection).
Custom providers: custom_provider_routes + custom_profiles add provider-definition management (create/test/activate OpenAI-compatible endpoints) with capabilities.py resolving active custom credentials; the Settings UI gets CustomProviderManager with a draft -> tested -> active progression (DESIGN.md documents the design system for this flow).
Persian (fa): full fa.json locale with key parity across all seven locales, RTL handling in index.css and the chat components, i18n loader registration, and LANGCHAIN_MAX_TOKENS passthrough for custom LLM endpoints.
Full suite on the integrated tree: 11645 passed, 107 skipped, 0 failed.
The vite bump alone could not install. `@vitejs/plugin-react@^4.3.0` peers on
`vite ^4 || ^5 || ^6 || ^7`, so npm refused the tree with ERESOLVE.
`@vitejs/plugin-react@5.2.0` is the first release whose peer range includes
`^8.0.0` — every 5.x before it stops at 7 — so the two have to move together.
Vite 8 bundles with Rolldown instead of Rollup, which needs two config changes:
- `manualChunks` had to become the function form. Rolldown calls it, so the
object map raised `TypeError: manualChunks is not a function` and the build
failed outright. Rollup accepts both forms, so this stays valid if the bump is
reverted. Chunking shifts as a result — vendor-react 106 kB to 280 kB and
index 395 kB to 203 kB — because the predicate catches transitive React deps
that the name list did not.
- `__dirname` to `import.meta.dirname`. Vite 8 warns the config uses features
unsupported by `configLoader: 'native'`, which becomes the default in a later
major.
Verified locally on the merge with current main: 461 frontend tests pass,
`npm run build` succeeds (and drops from 5.9s to 1.0s), and the dev server
boots and serves both / and a transformed /src/main.tsx.
Pushing to this branch takes it out of Dependabot's management; the bump needs a
companion change it cannot make on its own.
Backend: new /options/payoff and /options/chain HTTP routes wrapping the
existing options_payoff and get_options_chain tools (parity with MCP),
plus portfolio Greeks (delta/gamma/theta/vega/rho, multiplier-scaled)
computed from src.quantlib.options.bs_greeks.
Frontend: new Options Lab page — strategy builder with 12 presets,
expiry payoff chart with breakeven/spot markers and profit/loss fills,
spot x IV scenario heatmap, Greeks cards with plain-language
interpretations, and a live US options chain table (bid/ask spread,
volume, OI, IV, ITM/ATM highlighting). Full six-locale i18n.
Research only; does not place orders.
Signed-off-by: shadowinlife <shadowinlife@gmail.com>
Evaluate cron schedules in typed IANA zones with documented DST gap/fold semantics, preserve legacy UTC and interval behavior, and add Scheduled Research Web/i18n/docs coverage.
Closes#953.
React Router 7.12.0 through 8.2.x carry a high-severity RSC-mode CSRF bypass
(GHSA-qwww-vcr4-c8h2). We were on 7.18.1, inside that range. The advisory is not
reachable here — the app is a client-side SPA on createBrowserRouter with no
@react-router/server and no RSC entry point, and the frontend ships as static
Vite output — but 7.18.1 is the final 7.x release, no backport exists, and 8.3.0
is the only patched version, so staying put means staying on an EOL line with a
permanent open alert.
react-router-dom has no 8.x at all; the DOM exports moved into react-router
itself. So the dependency is swapped and every import rewritten. All ten APIs in
use here are unchanged in 8.3.0, and none of the data-layer surface that changed
most between majors is used.
react-router 8 requires Node >=22.22.0, which is the same wall that had jsdom 30
and @testing-library/jest-dom 7 sitting in the Dependabot ignore list. Node 20
reached EOL on 2026-04-30, so the toolchain moves to Node 22 across CI, the wiki
workflow, the Dockerfile and docker-compose. That unblocks all three at once:
jsdom and jest-dom are taken here too, and their ignores are removed rather than
left carrying a rationale that no longer holds.
Verified on the frontend suite: tsc -b and vite build clean, 310 tests across 35
files pass before and after the jsdom/jest-dom bumps.
1. Remove nonExplicitSupportedLngs — it strips region codes from compound
language keys (zh-CN → zh) causing isSupportedCode to reject them and
fall back to English.
2. Add /channels to Vite proxy paths — Settings page calls /channels/status
via Promise.all with getLLMSettings and getDataSourceSettings; without a
proxy rule these requests return index.html causing JSON parse errors.
3. Fix LanguageSwitcher always showing 'English' — i18n.languages (plural)
always includes the fallback 'en', and SUPPORTED_LANGUAGES has 'en' first
so .find() always matched 'en'. Fixed by checking i18n.language (singular)
first.
Signed-off-by: hoc.s <a615828a615828@outlook.com>
Add unified trading connector profiles and tools for IBKR and Robinhood. Gate live runner behavior by connector capability, preserve IBKR local read-only config, and update CLI, MCP, web UI, tests, skill docs, and multilingual README news.
Restructures the 3216-line agent/cli.py into a focused package
while preserving every existing surface verbatim.
Legacy compatibility:
- _legacy.py shim keeps every subcommand (serve, run, hypothesis,
alpha, memory, provider, swarm, sessions, ...) reachable through
the same CLI flags and console-script entry.
- Public symbols (cmd_*, _INIT_ENV_PATH, Confirm, AGENT_DIR, ...)
re-exported through cli.<name>; `from cli import *` exposes 76
symbols (was 1).
- Package-level cli.RUNS_DIR / cli.SESSIONS_DIR monkeypatches now
propagate into _legacy before any cmd_* runs.
New scaffolding:
- agent/cli/main.py interactive REPL front door
- agent/cli/commands/ slash router + handlers (15 commands)
- agent/cli/components/ reusable Rich UI building blocks
- agent/cli/{theme,intro,onboard,input,completer,stream}.py
- agent/cli/__main__.py restores `python -m cli`
- agent/cli/_version.py reads importlib.metadata.version() so
--version output and the banner stay aligned with pyproject.toml
Production wiring:
- New FastAPI middleware in api_server.py serves
frontend/dist/index.html on browser navigation to /runs/{id}
and /correlation, regex-narrowed so /runs/{id}/code and
/runs/{id}/pine API routes stay reachable.
- frontend/vite.config.ts dev proxy mirrors the same narrowing.
- scripts/dev backend starts via package-safe
`python -c 'import cli; cli.main(...)'`.
Chat-gate narrowed: chat --help / chat -h / chat --max-iter <bad> /
chat extra correctly reach legacy argparse instead of being
swallowed by the new REPL.
Tests: 2271 passed, 43 skipped (focused CLI/SPA test files:
test_cli_interactive.py 67 + test_spa_deep_link.py 13 + existing
CLI memory/init/hypothesis 48 = 128).
Bug fixes
- CompositeEngine no longer misroutes bare Chinese-futures codes like
RB2410 to GlobalFuturesEngine. _is_china_futures moved into a shared
_market_hooks module with a case-normalized product table and a
non-CN exchange guard. 9 new regression cases (RB2410 / rb2410 /
RB2410.SHFE / CL.NYMEX / M2412.CBOT / CF2412.ICE / AU2412.COMEX /
FG2412.EUREX / bare CN-collision still routes Chinese).
- Session FTS5 indexes now persist timestamps so cross-session search
can sort by date. Same path also fixes a re-upsert that was
wall-clocking every session's started_at on title-rename.
- Vite dev-mode proxy gained the missing /alpha entry; AlphaZoo page
resolves on npm run dev.
Cleanup
- Deleted swarm/api_models.py + swarm/mailbox.py + SwarmDashboard.tsx
(dead modules / orphaned UI after swarm-via-agent flow).
- Deleted SessionService.resume_attempt + get_attempts + get_attempt
+ SessionStore.list_attempts + Attempt.mark_waiting_user chain
(half-baked human-in-the-loop from initial commit).
- Deleted ChatLLM.achat (async sibling never called) and
_extract_balanced_json (only-tested helper).
- Deleted american_exercise_value in options_portfolio.py
(driver inlines bs_price logic).
- Deleted _compute_ic_series_reference in factor_analysis_core.py
(kept-as-reference, no callers).
- Collapsed MEMORY_TYPES duplication between cli.py and
memory.persistent; restored set-equality invariant assert.
- Deleted runSwarm (~197 LOC), swarmDash state, swarmCancelRef
write-only ref (orphaned by new agent-driven swarm flow).
- Dropped 76 unused 'vw = vwap(...)' boilerplate lines across
gtja191 alphas + their now-unused vwap imports.
- Cleared 11 F401 unused-import sites in tools/, agent/, providers/.
Test infrastructure
- test_e2e_harness_v2.py (real-LLM e2e) gated behind
VIBE_TRADING_RUN_LIVE_E2E so CI no longer flips shape based on
env-key presence. CI workflow now has explicit --ignore.
- test_auto_compact_with_long_history: monkeypatch TOKEN_THRESHOLD so
the test deterministically triggers compact instead of relying on
unrelated LLM behaviour.
- test_compact_tool_explicit: assertion corrected — compact tool is
special-cased in loop._process_tool_calls and does NOT emit
tool_call events. Assert on the 'compact' event instead.
- TestSwarmE2E: per-test @pytest.mark.timeout overrides matching the
internal 300s poll deadlines; cancel test now polls for terminal
state instead of fixed sleep(3).
Tooling
- ruff per-file-ignores for factors/zoo/** (3783 → 0 F401 noise);
F841 stays active in zoo to catch real formula bugs.
- frontend tsconfig: noUnusedLocals + noUnusedParameters as
regression guards.
- highlight.js hoisted to direct dependency (was transitive via
rehype-highlight).
- Vite proxy: dropped unused /run, /skills, /health, /api, /system;
added /alpha.
Annotations
- direction parameter renamed to _direction in 6 calc_commission
signatures (reserved for future borrow-fee asymmetry).
- _MARGIN_PER_CONTRACT in global_futures.py annotated as reference
data.
- Backtest engines' _calc_pct_change variants cross-reference each
other in docstrings.
Docs
- 2026-05-18 news entry added to README.md / README_zh.md /
README_ja.md / README_ko.md / README_ar.md; 2026-05-15 entry
rolled into the Earlier news <details>.
- Contributors heading: v0.1.7 cycle → v0.1.8 cycle in all 5
READMEs.
126 files changed, +363 / -1276.
vite.config.ts hardcoded http://localhost:8899 across 14 proxy entries,
ignoring the VITE_API_URL env that docker-compose.yml passes to the
frontend service (http://vibe-trading:8899). Inside the frontend
container, localhost resolves to the frontend's own network namespace,
so all proxied requests (sessions, runs, skills, etc.) ECONNREFUSED.
Read VITE_API_URL via loadEnv with the original localhost:8899 default,
and DRY the per-route target into a single PROXY_PATHS list driven by
Object.fromEntries.
Closes#78