Add the v0.1.12 cycle cohort (28 contributors) and demote the v0.1.11 list
into a collapsible block, in en/ja/ko/zh/ar. en/ja/ko keep English
descriptions; zh/ar translated.
Three fixes for the native zai provider on glm-5.1:
- get_llm_credentials now falls back to the provider catalog's
default_base_url when no *_BASE_URL is set, so CLI/manual-.env users
reach the canonical endpoint (Z.ai /api/coding/paas/v4) instead of
silently defaulting to api.openai.com. Web Settings already did this;
the backend credential path did not. Benefits all 22 providers.
- stream_chat falls back to a non-streaming invoke when a provider
streams zero chunks ('No generation chunks were returned'), instead of
raising ProviderStreamError. Scoped to the empty-stream case; genuine
provider errors still raise.
- ProviderStreamError appends a base-URL hint when the endpoint returns
an HTML error page (a common misconfiguration signal).
Fixes#758.
Rebased onto main and deduped — reuse the existing _restore_original_codes helper instead of the PR's parallel _map_result_to_requested; apply the same missing-symbol completion to both _fetch_auto and the explicit-source path. Fixes#681.
LLM answers with \(...\)/\[...\] or $$ formulas rendered as plain text --
the markdown pipeline had no math plugin. Normalize LLM delimiters to $$
outside code segments (streaming-safe for unclosed fences), parse with
remark-math (single-$ disabled so dollar amounts like "$150 to $120"
never become formulas), render with rehype-katex.
The options engine close branch computed cash/PnL from the full matched lot and
removed the whole position, ignoring the leg's requested qty — any partial close
wiped the entire lot with full PnL. Now an explicit leg qty closes only that many
contracts (clamped to the open size), cash/PnL scale to the closed fraction, and
the remainder stays open as a reduced-qty position; a close leg with no qty still
closes the whole lot (legacy). Closes#577.
Self-fix on merge: moved langchain-anthropic from core dependencies to an
[anthropic] optional extra (like [deepseek]) — _build_anthropic lazy-imports it
and raises an actionable install hint, so the base install stays lean. Resolved
llm.py conflicts against #563's centralized get_llm_credentials + the anthropic
native adapter-mode branch. Closes#694.
Reconciled the connector renderers with #735 (Longbridge schema-tolerant balances):
_print_connector_account now handles balances (broker_sdk) → remote-MCP nested
(Robinhood) → IBKR summary; positions use both remote-MCP shape and _first_present aliasing.
The vectorized _align did in-place np.nan_to_num/clip on arrays taken from
pandas via .values/astype(copy=False), which are read-only views under pandas
copy-on-write, raising 'ValueError: assignment destination is read-only' on
current main. Force a writable copy for the per-symbol signal array and use the
copy-returning nan_to_num for the position matrix. Vectorization stays numerically
equivalent to the scalar path (assert_frame_equal tests pass).
get_market_data could not resolve tickers like GC=F or EURUSD=X: detect_source
matched no pattern and fell to the 'tushare' default, routing them to
China-market loaders that cannot serve them; and the yahoo direct loader's
_is_supported guard rejected any non-.US/.HK/.NS/.BO symbol even though Yahoo's
public chart endpoint serves =F/=X verbatim.
Add =F/=X source patterns (route to yahoo) and accept =F/=X in the yahoo loader.
Closes#718
The shared 'connector positions'/'connector account' CLI renderers assumed the
IBKR result shape (position/avg_cost/sec_type/summary). broker_sdk connectors
such as Longbridge emit quantity/cost_price/market/balances, so every
non-matching key rendered as an empty cell.
Read key aliases (position|quantity, avg_cost|cost_price, sec_type|market) via a
None-aware _first_present helper (keeps a real zero qty), and render a balances
table when a connector returns 'balances' instead of IBKR 'summary' rows.
Closes#735
#729 made _apply_filter raise on inverted/degenerate date ranges (fail-fast
over silently returning an empty frame). But analyze_trade_journal called it
unwrapped, so the ValueError escaped as a raw traceback instead of the
{status: error} envelope the rest of the function uses; and the pre-existing
test_apply_filter_preserves_full_date_and_mixed_precision still asserted the
old silent-empty behavior. Wrap the call to return the error envelope and
update the stale assertion to expect the raise.
The annualized example used 0.01 with a '0.01%' comment, which reads as
1% (→1095% annualized), not the intended 0.01% (→10.95%). Standardize the
whole skill on the per-8h decimal convention OKX/Binance actually return
(0.0001 = 0.01%): fix the annualized example, funding_regime and
oi_funding_matrix thresholds, the cross-exchange dict, and the carry-trade
example; add an explicit units-convention note. Human-readable % tables
kept as-is.
The AST validator scanned os.<attr> but not getattr(os, "system")(...). Reject
getattr/setattr/delattr whose target is os or a forbidden module — keyed off the
target, not the attr string, so getattr(os, "sys"+"tem") is caught too.
Legit getattr(obj, name, default) on user objects (as the bundled harmonic
example uses) is unaffected.
IM /pairing ran with no authorization, so any allow-listed chat participant could
take over pairing across channels (+ Signal group members bypassed the sender
check, + code/sender_id leak). Add a config-driven operators allowlist (global +
per-channel, fail-closed when empty); gate every /pairing on operator identity in
runtime; scope store list/approve/revoke by channel; require per-sender auth for
control-plane slash-commands in Signal groups (ordinary /new /reset unchanged).
README documents the operator requirement.
Untrusted web/doc/search content entered the LLM context with no special-token
filtering, letting it forge system/assistant role boundaries. Add
neutralize_special_tokens() (hooked into with_security_warnings, applied to the 3
untrusted ingestion tools) that ZWSP-defangs the ChatML <|...|> family, the
DeepSeek fullwidth-bar <|...|> family (the shipped default model), Llama
[INST]/<<SYS>>/<s>, and Gemma role tokens. Text stays visually identical.
sse / streamable-http bound a TCP port with no Host/Origin validation (fastmcp
3.2.4 ships none), so a DNS-rebinding browser page could reach every MCP tool.
Wrap the network ASGI app (mcp.http_app) with TrustedHostMiddleware + an Origin
allow-list (VIBE_TRADING_MCP_ALLOWED_HOSTS, default loopback) and serve via
uvicorn. stdio (default) untouched.
_validate_api_auth / require_event_stream_auth trusted the loopback peer BEFORE
checking API_AUTH_KEY, so a same-host reverse-proxy/sidecar reached key-protected
routes with no token. Invert to key-first (mirrors require_settings_write_auth):
when a key is set every peer incl. loopback must present a valid bearer/ticket;
only the no-key dev mode keeps loopback trust. No-key default UX unchanged; the
bundled frontend already sends the bearer/ticket when a key is stored. Updates
3 tests that codified the loopback-bypass behavior.
MCP stdio previously force-enabled bash/background_run with no opt-out and the
module-level default was fail-open. Default to fail-closed and gate every
transport behind explicit opt-in (--enable-shell-tools flag or
VIBE_TRADING_ENABLE_SHELL_TOOLS). Local CLI is unaffected (still opts in
explicitly). Also shrinks the network-reachable surface of the bash
OS-command-injection sink (GHSA-m768). Adds regression tests + doc alignment.
#567 added feitu, a client SDK for the contributor-operated FTShare data
service. Reverting it: a 3-week-old, author-affiliated backend whose free tier
is at the operator's discretion is not a neutral public data source, and the
A/HK fallback chains already carry ample free coverage (tencent, mootdx,
eastmoney, baostock, akshare, yahoo, futu). Removed the loader, its test,
registry entries, fallback-chain slots, and doc/source-count references
(sources 22->21, free 20->19).