Refs #1677. The shadow report's PDF half depends on weasyprint's system
pango/cairo libraries, which pip cannot install; hosts without them
silently degraded to HTML-only output. Add a pure-Python fallback that
renders the same 8-section payload (plus charts) through reportlab
platypus, with CJK font registration from the local system list. Engine
order is weasyprint, then reportlab, then html-only; the weasyprint path
and its one-shot import probe are unchanged.
Signed-off-by: Yufeng He <40085740+he-yufeng@users.noreply.github.com>
`requires-python` capped Python at <3.14 because smartmoneyconcepts pulls
numba -> llvmlite, and llvmlite had no cp314 wheel. Two things are now
true that were not when that cap was written:
- llvmlite 0.49.0 does ship cp314 wheels (macOS arm64, manylinux x86_64
and aarch64, win_amd64, win_arm64), so the cap blocks 3.14 everywhere
for a reason that no longer holds;
- llvmlite ships no macOS x86_64 wheel at all from 0.46 on (0.45.1 is the
last, cp310-cp313), so Intel Macs hit a cmake source build on *every*
Python version. That is the failure in discussion #1035, and the cap
never addressed it.
The cap also backfired: only 0.1.13 carries it, so on 3.14 pip backtracks
to 0.1.12 and installs the very thing the cap exists to prevent.
smartmoneyconcepts is imported by exactly one file, the skill example
src/skills/smc/example_signal_engine.py, whose SKILL.md already told the
reader to install it. Nothing else imports numba, and no test depends on
it. Every other extra (pyharmonics, statsmodels, arch, baostock, pykrx,
openbb-ai, langchain-anthropic) is already absent from agent/requirements.txt
and the lock, so this just brings smartmoneyconcepts in line.
Verified on a throwaway CPython 3.14.4 venv: base install carries neither
numba nor llvmlite nor smartmoneyconcepts, `vibe-trading --version` runs,
and the suite is 10774 passed / 23 skipped / 0 failed under CI's own
extras ([dev,openbb,stats]). The regenerated lock differs by exactly the
three removed packages, with no incidental version bumps, and still passes
`pip install --dry-run --require-hashes` on 3.11.
Note for CI: the test job pins python-version 3.11, so 3.14 is now
supported but unexercised.
Exposes the agent to OpenBB Workspace over the openbb-ai SDK, behind an
optional `openbb` extra.
Security repairs on top of the contribution:
- pro.openbb.co is no longer a default CORS origin. CORS is installed
globally with credentials and keyless loopback mode admits safe GETs by
peer address, so that default would have let scripts on the OpenBB
origin read /sessions and /runs. Extra origins are now an additive
opt-in (VIBE_TRADING_EXTRA_CORS_ORIGINS) declared in the typed config
layer; the loopback-only defaults are unchanged.
- POST /v1/query carries require_auth. It reaches the full agent registry,
which auto-registers the order tools, so an unauthenticated caller could
have driven actions inside an already-active mandate.
- The three unadvertised LLM routes (chat title, dashboard title, prompt
enhancement) are removed rather than authenticated: they were absent
from the manifest and duplicated the existing authenticated title path.
- Conversation identity no longer hashes the first message. Any two
conversations opening with the same text mapped onto one persistent
session, leaking history between them, and later requests' full history
was ignored. openbb-ai 2.1.0 exposes no conversation id, and the SDK
contract is stateless with full history per request, so each request now
runs an ephemeral session replaying the supplied history.
- The SDK is wired into the dev install and CI, with an explicit import
check. It previously landed only in agent/requirements.txt while CI
installs the extras, so every bridge test silently skipped and the
feature could look green while being uninstallable.
- Workspace context is now ingested under an 8k budget instead of ignored,
and widget-dashboard-search is advertised as false: widget groups carry
metadata only, and the value round-trip is not implemented, so the model
is told values are absent rather than left to invent them.
The contributor's requirements-lock.txt rewrite was dropped (stale
Python-3.12 regen with unrelated downgrades; the runtime targets 3.11).
Note for operators: a browser POST from a remote Workspace origin is still
refused by the pre-existing cross-site guard, independently of CORS and of
a valid token. Self-hosted same-origin Workspace and server-side callers
work; that boundary is pinned by a test.
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.
- Add credentials.py: unified credential resolution for data and trading
- Add test_longbridge_credentials.py: coverage for credential resolution
- Remove longbridge from requirements.txt (optional extra only)
- Update requirements-lock.txt
- Update .env.example with Longbridge credential hints
Longbridge (>=0.2.5) is the official LongPort OpenAPI Python SDK
used by the longbridge trading connector. It was previously undeclared
(assumed to be installed by the connector's own requirements.txt),
which breaks pip install vibe-trading-ai users whose envs pins the lock
file and Docker builds that rely solely on requirements-lock.txt.
Changes:
- agent/requirements.txt: add longbridge>=0.2.5
- pyproject.toml: add longbridge>=0.2.5 to dependencies
- requirements-lock.txt: regenerated (resolves to longbridge==4.3.3)
Connector code lives at agent/src/trading/connectors/longbridge/.
History data loader is out of scope (tracked for PR2).
Relates to: feat/longbridge-support (PR1 of 4)
Co-authored-by: fanfpy <fanfpy@gmail.com>
Implements VT-001 through VT-010 from the 2026-07-10 external security
audit (Trivy/Semgrep/ZAP/Gitleaks/pip-audit against a real deployment):
- VT-001 (Critical): AST hardening in backtest/runner.py rejects
network/subprocess/eval/os.environ/unsafe-open calls reachable from
generated SignalEngine method bodies (previously only checked
top-level statements). Defense-in-depth: ephemeral per-run HOME,
RLIMIT_AS/NOFILE caps, best-effort UID-drop to a new vibe-sandbox
user (currently inert under Docker's cap model - see session doc;
accepted as documented residual gap, primary AST defense unaffected).
- VT-002: multi-stage Dockerfile split so build-essential never
reaches the runtime image.
- VT-003: SSE auth moved from a long-lived API key in the URL query
string to short-lived single-use tickets; access-log redaction for
any remaining query secrets.
- VT-004: agent/.env split-brain fixed (bind mount + atomic 0600
writes) between docker-compose and Web UI settings writes.
- VT-005: /correlation now requires auth + per-IP rate limit; generic
exceptions no longer leak raw text to clients.
- VT-006: CSP-Report-Only + security headers middleware; Google Fonts
replaced with self-hosted @fontsource packages.
- VT-007: docker-compose hardening (cap_drop ALL + minimal cap_add,
no-new-privileges, read_only rootfs, resource limits).
- VT-008: /health split into /live (liveness) and /ready (real
provider-config readiness check); /health kept as a compat alias.
- VT-009: base images pinned by digest, GitHub Actions pinned by
commit SHA, dependabot.yml added, hash-verified requirements-lock.txt
now actually wired into the Docker build via --require-hashes.
- VT-010: universe-panel pickle cache sidecar upgraded from an
unkeyed SHA-256 (forgeable by anyone with cache-dir write access)
to a keyed HMAC.
Implemented via a 5-parcel Workflow (file-disjoint, independent
adversarial verification per parcel, then a holistic final audit).
The final audit caught a real regression (CI env-var-gate violation)
and confirmed a dependency-pinning gap, both fixed and re-verified
here, including a latent transitive-dependency bug the fix surfaced
(smartmoneyconcepts<0.0.27 pulls an unbuildable zigzag package) - see
docs/sessions/2026-07-13_session_vt476_security_hardening.md (local,
gitignored) for full evidence trail.
Full suite: 5191 passed, 6 pre-existing/environmental failures
(unchanged from main). Docker build + hardened compose boot verified
end-to-end.
Raise Pillow and LangChain floors past disclosed advisories, and align the direct langgraph constraint with the newer LangChain 1.3 dependency graph so the package remains installable.
Local verification: Python 3.13 venv pip dry-run for editable install resolved; Pillow/langchain/langgraph/langchain-openai installed and imported; pip check passed.
* chore(release): 0.1.10 — version sync, wheel packaging, Docker weasyprint libs
Release-prep for 0.1.10 (bundles the global data layer + everything since 0.1.9):
- version 0.1.9 -> 0.1.10 synced across all surfaces: pyproject, frontend
package.json/lock, sidebar footer + i18n, SKILL.md, Dockerfile LABEL. REST
API + MCP server now derive the version from cli._version (were hardcoded
"5.0.0" / unset).
- pyproject package-data ships skill example scripts (skills/**/*.py) so the
wheel + sdist include them; fastmcp floor -> 2.14.0 (first release where the
MCP version= kwarg applies).
- Dockerfile installs weasyprint native libs (Pango/HarfBuzz/Fontconfig/Cairo/
gdk-pixbuf + DejaVu) so PDF reports render in the image; .dockerignore *.md
-> /*.md (root-anchored, skill markdown still ships).
- README news (5 locales): 06-19 reframed as the v0.1.10 release; 06-19/06-18
trimmed.
Verified: clean-room pip install imports all new loaders/tools; wheel + sdist
carry the eastmoney/sec-edgar skills incl. UTF-8 references + scripts; 4167
backend tests pass (weasyprint PDF path covered on CI).
* docs(release): credit v0.1.10 cycle contributors across READMEs
Refresh the Contributors section in all 5 READMEs from the v0.1.9 cycle to
the v0.1.10 cycle (PRs #162–#260): @Hinotoi-agent, @mvanhorn, @gyx09212214-prog,
@BillDin, @Robin1987China, @LemonCANDY42, @zwrong, @forge-builder, @skloxo,
@LeeCQiang, @KaiLuettmann, @ngoanpv, @ShahNewazKhan, @sambazhu, @bhlt, @octo-patch.
A cluster of provider reports traced to one root: every OpenAI-compatible
provider shared a single shim that applied DeepSeek/Kimi/Gemini quirks
globally and silently swallowed stream failures.
- Provider capability layer (capabilities.py): reasoning capture/replay,
Gemini thought signatures, Kimi User-Agent (version from package
metadata), OpenRouter reasoning body — gated per provider, no
cross-contamination
- Optional native DeepSeek adapter via VIBE_TRADING_DEEPSEEK_ADAPTER
(auto/native/openai-compatible) + 'deepseek' extra (langchain-deepseek)
- ChatLLM.stream_chat: silent fallback to chat() removed; failures raise
ProviderStreamError with redacted provider/model context; one retry for
transient errors in AgentLoop + swarm worker (deterministic 4xx fail fast)
- Empty model response diagnosed as empty_model_response instead of
'reached max iterations'
- reasoning_delta SSE event (throttled to 1/s, first chunk immediate) +
frontend 'Reasoning…' indicator; reasoningActive reset on safety timeout
- SSE heartbeats carry no replay id; replay falls back to full buffer on
unknown last-event-id; read-only tools get a hard timeout
(VIBE_TRADING_TOOL_TIMEOUT_SECONDS) instead of hiding behind heartbeats
- 'vibe-trading provider doctor' prints redacted provider/model/package/
proxy diagnostics; preflight includes the same hint
- kimi-k2.x temperature=1 requirement auto-applied; Kimi path verified
end-to-end against the live API (kimi-k2.6 tool calls + strict
multi-turn reasoning replay)
Refs #208#203#195#204