Commit Graph
334 Commits
Author SHA1 Message Date
Haozhe Wu 65660e4087 docs: news for 06-12 — provider reliability overhaul (capability layer, provider doctor, streaming liveness) 2026-06-12 23:41:25 +08:00
Haozhe Wu fa2ad4b664 fix(providers): capability-gated payloads, explicit stream errors, liveness + provider doctor
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
2026-06-12 23:41:19 +08:00
zwrong 38582c564d fix(trace): all entries carry iter right after type, resume before start/message
Three interrelated fixes for trace.jsonl field consistency:

1. Field order — every entry now has `iter` immediately after `type`.
   This was already the convention for tool_call, tool_result, thinking,
   answer, and cancelled. Fixed start, message (user+assistant), and end
   to follow the same pattern.

2. Iteration values — start and message (user) previously used
   `self._run_iteration` (which is 0 before the loop begins), so the
   first turn showed iter=0 while the first loop iteration showed iter=1.
   Changed to `self._run_iteration + 1` so they share the same iter as
   the first loop iteration. end now carries `iter` in addition to
   `iterations` (the per-run count), so it participates in iteration
   grouping like every other entry.

3. Resume ordering — the iteration-counter restore logic (reading max
   iter from an existing trace to continue a session) was placed AFTER
   start/message were written, so resumed sessions had iter=0 on those
   entries. Moved the resume block before the write calls.

Tests added (TestTraceFieldConsistency):
- test_tool_result_iter_second — write_tool_result() dict order
- test_generic_write_preserves_type_then_iter — generic write order
- test_all_entry_types_carry_iter — 10 entry types all have iter at
  position 1; catches future regressions

Closes the long-standing gap where start/message/end could not be
attributed to a specific turn in multi-turn sessions.

Signed-off-by: zwrong <1003912034@qq.com>
2026-06-12 13:44:19 +08:00
zwrong c4dec47576 feat(agent): complete trace.jsonl — zero truncation, message entries, tool result offload
- TraceWriter: add write_tool_result() with 50K offload threshold + 500-char preview
- TraceWriter: read() auto-resolves offloaded results from tool-results/*.txt
- TraceWriter: add find_trace_dir() — sessions/ first, runs/ fallback
- loop.py: sessions/<id>/trace.jsonl when session_id valid, runs/ fallback for -p
- loop.py: remove all [:N] truncation from trace entries (prompt, thinking, answer, args, summary)
- loop.py: add message type entries (user/assistant) for full conversation replay
- loop.py: use write_tool_result() for proper inline/offload routing
- loop.py: auto_compact transcript now uses trace.dir_path
- _legacy.py: find_trace_dir() in _build_history_from_trace, cmd_show, cmd_trace, cmd_continue
- _legacy.py: cmd_trace display supports new fields (result_path, result_preview, result_size)
- tests: 18 new TraceWriter tests covering inline, offload, boundary, mixed, unicode, find_trace_dir

Signed-off-by: zwrong <1003912034@qq.com>
2026-06-12 13:44:15 +08:00
Haozhe Wu c390aa8462 docs: news for 06-10/06-11 — swarm market-data hardening, Docker Ollama + persistence
Two entries across all 5 READMEs (3 visible + earlier rotated into
details): 06-11 swarm loader-backed get_market_data rollout (#198/#199/
#200, bare-ticker grounding, 48 tools) bundled with Docker state
persistence (#197); 06-10 host-side Ollama reachability (#196).
2026-06-11 13:34:12 +08:00
Haozhe Wu 2ba6ae2f0c fix(docker): persist user agent state across container rebuilds
All user-level agent state lives under ~/.vibe-trading in the container
(persistent memory, sessions.db search index, user-created skills,
shadow accounts, hypothesis registry, broker connector config), but
docker-compose only mounted volumes for web sessions and backtest runs.
Every `docker compose up --build` therefore recreated the container and
silently wiped the user's memory store (#197). Swarm run history and
uploads were lost the same way.

- Mount vibe-home -> /home/vibe/.vibe-trading, plus vibe-swarm-runs and
  vibe-uploads.
- Pre-create /home/vibe/.vibe-trading owned by the service user in the
  Dockerfile so the named volume inherits writable permissions (a named
  volume mounted onto a missing path is created root-owned and the
  non-root user cannot write).
- README: document what persists across updates.

Verified end-to-end: memory written via PersistentMemory in one
container is intact in a fresh container on the same volume; the
counterfactual run without the volume reproduces the wipe.

Fixes #197.
2026-06-11 13:17:04 +08:00
b6fd9b1fd4 fix(docker): reach host Ollama via host.docker.internal (#196)
* fix(docker): reach host Ollama via host.docker.internal

Inside the container, OLLAMA_BASE_URL=http://localhost:11434 resolves to
the container itself, so the agent's preflight check and AgentLoop fail
with "Connection refused" even when Ollama is running on the host.

Override OLLAMA_BASE_URL to http://host.docker.internal:11434 in the
compose service (leaving agent/.env correct for bare-metal runs) and add
an extra_hosts host-gateway mapping so the same file also works on Linux.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(docker): parameterize OLLAMA_BASE_URL and document host networking

Address PR review feedback:
- Make OLLAMA_BASE_URL overridable via Compose variable substitution
  (${OLLAMA_BASE_URL:-http://host.docker.internal:11434}) so it can be
  changed without editing the compose file when Ollama runs elsewhere.
- Note the Docker Engine >= 20.10 / Compose v2 requirement for the
  host-gateway mapping, both inline and in the README Docker section.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Shah Newaz Khan <shah.khan@lexful.ai>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 12:55:48 +08:00
Haozhe Wu dfd71b4bc2 feat(swarm): ground bare US tickers mentioned in swarm prompts
Grounding previously only matched loader-suffixed symbols (NVDA.US),
so an investment_committee run on "long or short on NVDA" got no
pre-fetched ground-truth prices and workers fell back to ad-hoc
scripts (#198, fix direction 5).

Promote bare all-caps tokens to <TOKEN>.US under guards:
- 2-5 uppercase letters only, dotted compounds rejected on both sides
  (FOO.USDA promotes neither side; sentence-ending "NVDA." still works)
- stopword list for finance/English acronyms (ETF, CEO, GDP, USD,
  bare crypto symbols, index providers like MSCI, ...)
- suffixed matches are blanked before the bare scan, so BTC-USDT can
  never leak a bogus BTC.US
- promotions sort after explicit symbols, so explicit symbols win the
  max-symbols cap; the per-symbol fetch remains the final validator

Closes the last open item of #198.
2026-06-11 12:22:51 +08:00
Haozhe Wu d7d1654f32 fix(swarm): expose get_market_data across all market-data presets
PR #199 added the loader-backed get_market_data tool to
investment_committee and equity_research_team. Extend it to the 16
remaining workers (across 11 presets) whose skills include tushare,
yfinance, or okx-market, so every OHLCV-capable worker gets the
loader-first path and the worker prompt policy.

Add a regression test locking the convention: any preset worker with a
market-data skill must whitelist get_market_data.

Part of #198.
2026-06-11 12:14:15 +08:00
Chengcheng DingandChengcheng Ding d1ed1019c0 fix(swarm): preserve preset context for continuations (#200)
Signed-off-by: Chengcheng Ding <billdin1999@gmail.com>
Co-authored-by: Chengcheng Ding <billdin1999@gmail.com>
2026-06-11 12:11:37 +08:00
Chengcheng DingandChengcheng Ding 7436986246 fix(swarm): expose loader-backed market data tool (#199)
Signed-off-by: Chengcheng Ding <billdin1999@gmail.com>
Co-authored-by: Chengcheng Ding <billdin1999@gmail.com>
2026-06-11 12:10:52 +08:00
Haozhe Wu a80b4431bf fix(web): arm SSE safety timeout so a no-event turn can't hang forever
The streaming safety timeout guarded on lastEventRef.current being truthy, but
it starts at 0 and only real SSE events (not the keep-alive heartbeat) update
it. A turn whose very first event never arrives — e.g. the LLM provider hangs
before emitting a token — left it at 0, so the guard short-circuited and the UI
stayed on "Agent is working…" indefinitely. Arm the clock on entering the
streaming state so the timeout fires after sse_timeout and resets to idle with a
notice. Turns issue #195's hang into a recoverable timeout.
2026-06-09 20:33:24 +08:00
Haozhe Wu f735e4ca51 fix(backtest): make mootdx & futu first-class config sources
Two whitelists/maps had drifted as mootdx and futu loaders were added:

1. BacktestConfigSchema._VALID_SOURCES rejected an explicit
   source="mootdx"/"futu" even though both are registered loaders (and in
   FALLBACK_CHAINS), while src/tools/backtest_tool.py already allowed them.
   Fix: one canonical VALID_SOURCES in backtest.loaders.registry, consumed by
   both backtest.runner and src.tools.backtest_tool so they cannot diverge.

2. metrics annualisation maps (_TRADING_DAYS / _BARS_PER_DAY) lacked mootdx and
   futu, so intraday backtests on them fell back to bars_per_day=1 and
   mis-annualised vol/Sharpe. Fix: add both as equity sources (252 days, 240-min
   session, mirroring tushare/akshare).

Regression tests: mootdx/futu accepted by the config schema, every registered
loader covered by VALID_SOURCES, and intraday bars_per_year correct for both.
2026-06-09 19:17:21 +08:00
Matt Van HornandMatt Van Horn 05e492a99a docs: add custom data loader guide (#194)
Signed-off-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
2026-06-09 19:06:58 +08:00
Haozhe Wu bbd8466ded fix(web): surface auth-required reason on remote 403 (#191) (#192)
Chat sends from a non-loopback client (another machine, VM host, LAN
device) without API_AUTH_KEY returned 403 on every sensitive endpoint,
but the UI only showed a generic "Failed to send message, please retry."
The send path now surfaces AUTH_REQUIRED_MESSAGE so users know to set
API_AUTH_KEY (and enter it once in Settings) or browse via localhost.

Also document the localhost-vs-LAN rule in the web-UI setup and add a
2026-06-09 news entry across all 5 locale READMEs.
2026-06-09 11:10:02 +08:00
Haozhe Wu 6b37c040c1 revert: drop GHCR pre-built image path (#187)
The Path E "pull a pre-built image, no clone" deploy path was open-box
broken: the GHCR package defaults to private, so anonymous `docker pull`
fails, and the path was never verified end-to-end against the main repo
(the contributor tested a self-built image, not ghcr.io/hkuds/vibe-trading).

Removes the publish workflow, docker-compose.prod.yml, the Dockerfile
VERSION arg, and the README Path E section/table row/tree note. The
2026-06-08 news entry is rewritten to cover only the Gemini 3.x
dict-path fix (#184). Also drops the now-orphan edge-build paths-ignore.

If a buildless deploy path is wanted later, do it properly: make the
package public, verify an anonymous pull works, then document it.
2026-06-08 10:45:25 +08:00
Haozhe Wu 4389246350 docs(readme): add 2026-06-07 + 2026-06-08 news in 5 locales
06-07 live swarm status in chat (#188) + preset routing (#189); 06-08 one-pull GHCR image (#187) + Gemini 3.x dict-path fix (#184). Older 06-05/06-04 folded into Earlier news to keep 3 visible.
2026-06-08 10:29:02 +08:00
Haozhe Wu 7dd9e58870 ci(docker): skip GHCR edge build for doc-only main pushes
Release builds still always fire via the release trigger; only the edge-on-main-push build is skipped when a commit touches nothing but .md / docs/ / wiki/.
2026-06-08 10:29:02 +08:00
Chengcheng DingandChengcheng Ding 0f0fcb6280 fix(swarm): honor explicit preset names (#189)
Signed-off-by: Chengcheng Ding <billdin1999@gmail.com>
Co-authored-by: Chengcheng Ding <billdin1999@gmail.com>
2026-06-08 10:13:12 +08:00
Chengcheng DingandChengcheng Ding f194e51f4d feat(web): show swarm agent status in chat (#188)
Signed-off-by: Chengcheng Ding <billdin1999@gmail.com>
Co-authored-by: Chengcheng Ding <billdin1999@gmail.com>
2026-06-08 10:13:07 +08:00
Kai LüttmannandCopilot d77f6b3379 feat: publish pre-built image to GHCR on release (closes #183) (#1) (#187)
* feat: publish pre-built image to GHCR on release (#183)

* docs: remove Watchtower references from README

* Add workflow_dispatch trigger to Docker publish workflow

* Allow Docker publish on additional branch

* Update Docker publish workflow triggers

Removed manual trigger and restricted push branches.

---------
authored-by: Kai Lüttmann <33122946+KaiLuettmann@users.noreply.github.com>

Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
2026-06-08 10:12:59 +08:00
Pham Van Ngoan 0e4ffc8c66 fix(llm): preserve Gemini thought_signature through the AgentLoop dict path (#184)
#176 added the Gemini thought_signature round-trip but only covered the
in-memory AIMessage path its unit tests exercise. The AgentLoop replays
conversation history as OpenAI-format dicts, stamping the signature into
tool_calls[i].extra_content.google.thought_signature
(loop.py _attach_tool_call_thought_signatures).

LangChain's _convert_dict_to_message discards extra_content during the early
_convert_input step of invoke()/stream() -- before _get_request_payload
re-injects -- so _signature_maps reads an empty additional_kwargs and the
outbound request goes out unsigned. Gemini then rejects the next tool-using
turn with HTTP 400 "Function call is missing a thought_signature in
functionCall parts". This broke every tool-using loop turn on gemini-3.x
(single or parallel), e.g. the parallel load_skill case.

Override ChatOpenAIWithReasoning._convert_input -- the single chokepoint both
invoke and stream call while input is still raw dicts -- to lift signatures
back onto the converted AIMessage in the same
additional_kwargs["tool_call_thought_signatures"] shape the in-memory path
uses, so the existing _signature_maps / _inject_tool_call_thought_signatures
machinery handles both paths identically. Idempotent via an
isinstance(raw, dict) guard. No parallel-specific handling needed: Gemini
signs only the first of N parallel calls and that signature covers the block.

Add regression tests in TestChatOpenAIWithReasoningOutboundPayload that drive
the real dict path (the gap #176's tests missed): red without the fix
(KeyError: 'extra_content'), green with it.
2026-06-08 10:12:56 +08:00
Haozhe Wu b31e9b4af1 docs(readme): add 2026-06-06 alpha compare news in 5 locales 2026-06-07 01:08:47 +08:00
Haozhe Wu b110bdc3b2 feat(factors): add alpha compare across CLI, REST, Web UI and agent tool
Head-to-head comparison of hand-picked Alpha Zoo alphas, sharing one core
(compare_runner.compare_alphas) across four surfaces:

- CLI: `vibe-trading alpha compare <id1> <id2> ... --sort ir`
- REST: POST /alpha/compare + SSE progress/result stream
- Web UI: Compare view in Alpha Zoo (catalogue multi-select -> ranked table)
- Agent: read-only `alpha_compare` tool (now 47 tools)

Adds a backward-compatible `only=` subset filter to run_bench so comparing
a few alphas no longer benches the whole zoo. Ranks by IC mean/std, IR,
IC-positive ratio or sample count, each with its gap to the leader.

39 new backend tests; frontend tsc + 197 vitest + build green.
2026-06-07 01:08:42 +08:00
Haozhe Wu 9b9e83fe6c docs(readme): add 2026-06-05 news (Dhan/Shoonya, Gemini, docstrings, tests) in 5 locales 2026-06-05 21:52:59 +08:00
Haozhe Wu 36c5a4457c fix(deps): patch 7 Dependabot alerts (react-router XSS/DoS, vitest RCE)
Bump react-router-dom ^7.1.0 -> ^7.15.0 (resolves to 7.17.0), clearing 6 react-router advisories (XSS, open redirect, DoS, turbo-stream arbitrary constructor; patched across 7.13.2-7.15.0).

Bump vitest + @vitest/coverage-v8 ^3.2.6 -> ^4.1.0 (resolves to 4.1.8), clearing the critical Vitest UI-server arbitrary file read/exec (patched in 4.1.0) and aligning the coverage peer dependency on the v4 line. Frontend suite (197 tests) green on vitest 4; production build passes.
2026-06-05 20:56:40 +08:00
sambazhu d17faacefc test: add frontend test suite + backend security/coverage tests
Cherry-picked the test-infra commit from #175 (sambazhu): vitest setup + 19 frontend test files (197 tests), backend auth/path-traversal/CORS tests, yfinance crypto fallback (BTC-USDT->BTC-USD), and CI coverage + frontend-test steps. Dropped the PR's separate i18n commit to stay consistent with #163.

Fix: align @vitest/coverage-v8 to ^3.2.6 (was ^4.1.8, incompatible with vitest ^3.2.6 - blocked npm install and the new npm ci CI step).
2026-06-05 20:41:14 +08:00
leeadmin 44f14b67f8 docs(factors): add Chinese docstrings to factor zoo
Cherry-picked the factor-module Chinese docstrings from #180 (alpha101 / gtja191 / qlib158 / academic, 452 files, purely additive). Dropped the i18n parts — react-i18next deps + 29 swarm-preset name_zh/description_zh (currently unused) — to stay consistent with the #163 decision to not bundle i18n yet.
2026-06-05 20:25:36 +08:00
Matt Van HornandMatt Van Horn 51b207f0ba fix: round-trip Gemini thoughtSignature through OpenAI-compat tool calls (#176)
Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
2026-06-05 20:15:42 +08:00
Panditvirchandra77-lgtmandHaozhe Wu dda7a5739b feat(trading): add Dhan + Shoonya Indian broker connectors (paper-capped)
Two broker_sdk connectors for the Indian equity and F&O markets (NSE/BSE):
Dhan (dhanhq) and Shoonya / Finvasia (NorenRestApiPy). Read access plus
locally simulated paper-account order placement.

Both brokers expose no sandbox and no runtime paper/live discriminator — a
single token / TOTP login reaches the same real account — so, following the
Longbridge precedent, the order path is structurally capped at paper:

- place_order / cancel_order refuse any non-paper config at the first line, so
  a flipped `profile` override can never reach a live order;
- no live order-placing profile is registered (paper-sdk read-only,
  paper-trade local-sim, live-sdk-readonly read-only — three profiles each,
  mirroring Longbridge);
- DHAN/SHOONYA tool-class maps wired into the live classifier registry;
- order ops pinned WRITE; secrets redacted; pyotp made an optional dependency;
  Shoonya sessions cached per user_id to avoid cross-account reuse.

Tests cover profile registration, the non-paper fail-closed guard, paper
simulation, WRITE-pinned order ops, secret redaction, and a regression guard
that these no-discriminator brokers never expose a *-live-trade profile.

Maintainer follow-up to PR #174: the original submission shipped live order
placement with no structural paper/live discriminator (and an invalid asset
class that crashed the live path); this revision caps both connectors to
paper + read-only to keep the paper/live boundary structural, never an
agent-flippable config flag.

Co-authored-by: Haozhe Wu <haozhe_wu@connect.hku.hk>
2026-06-05 15:45:11 +08:00
Haozhe Wu c2257fe6f3 fix(wiki): make footer counter all-time cumulative, not a 30-day window
Sum the full visits history instead of windowing to 30 days, so the agent/human counts grow monotonically since launch (data is never GC'd).
2026-06-05 14:54:43 +08:00
Haozhe Wu ee28390a2c fix(wiki): cache-bust main.js so browsers load the traffic-counter JS immediately
main.js is browser-cached up to 4h; the fresh HTML still pointed at the unversioned /main.js, so returning visitors kept running the pre-counter JS and the footer never populated. Versioned query forces an immediate fetch of the new module.
2026-06-05 14:47:39 +08:00
Haozhe Wu cb82c6262c fix(wiki): align live-trading copy with shipped Robinhood Agentic support; hide footer counter until data loads
The wiki still claimed 'no live trading / does not execute live trades', which contradicts the shipped opt-in bounded Robinhood Agentic channel (and the README). Aligns home, docs, and alpha-library copy with the README's framing. Also fixes a CSS specificity bug where .footer-traffic{display:flex} overrode the [hidden] attribute, showing placeholder dashes before /api/stats data arrived.
2026-06-05 14:39:55 +08:00
Haozhe Wu e2a42aa4ab fix(wiki): cache PyPI installs in D1, drop redundant GitHub call from /api/stats
pypistats/GitHub calls from the Worker intermittently rate-limit, blanking the footer. PyPI now reads through a D1 last-good cache so it never goes empty; GitHub stars are dropped here since main.js already loads them client-side.
2026-06-05 14:14:07 +08:00
Haozhe Wu 6fac55d795 fix(ci): deploy wiki in config mode so Pages Functions compile
pages deploy <dir> from repo root uploads functions/ as static files and never compiles them, so /api/stats (the agent-vs-human counter) was never live. Run wrangler from wiki/ (workingDirectory) with the wrangler.toml present so functions/ is detected and compiled.
2026-06-05 14:10:04 +08:00
Haozhe Wu 25b6ee5d72 feat(wiki): add agent-vs-human traffic counter to vibetrading.wiki
First-party, anonymous analytics for the public wiki — no client-side telemetry in the pip package. Pages Function middleware classifies each page request (AI agent / bot / human) by User-Agent server-side and counts it into D1; /api/stats serves the footer's aggregate counts alongside public PyPI install and GitHub star numbers.
2026-06-05 14:03:17 +08:00
Haozhe Wu 1cd4ba19df docs(readme): add 2026-06-04 opt-in data cache news entry across 5 locales 2026-06-04 23:40:06 +08:00
Matt Van Horn ff56134b91 feat(loaders): opt-in local data cache for all backtest data sources (#177)
Add an opt-in local market-data cache (VIBE_TRADING_DATA_CACHE) for the backtest
loaders. When enabled, every data source — tushare, okx, ccxt, akshare, mootdx,
yfinance, futu — caches settled historical bars under ~/.vibe-trading/cache
(user home, never the repo tree) so repeated and long-horizon / cross-market
backtests skip the network and avoid provider rate limits.

- Generic loader_cache_get / loader_cache_put / cached_loader_fetch helpers in
  the loader base; batch/connection loaders (yfinance, futu) skip the bulk
  download / FutuOpenD connection entirely on a full cache hit.
- Staleness guard: ranges ending today or in the future are never cached, since
  the key is content-addressed on end_date, not fetch time.
- Cached frames round-trip byte-identical to freshly fetched ones (columns name
  and per-level index dtype preserved across the duckdb parquet round-trip).
- pid + uuid tmp filenames for concurrency-safe atomic writes; cache version 2.
- Documented in .env.example; staleness, real-duckdb, and batch-loader tests.

Closes #171.

Signed-off-by: Haozhe Wu <haozhe_wu@connect.hku.hk>
2026-06-04 23:14:32 +08:00
Roger 1a5f096496 docs: add AI contributor guide (#173)
Add AGENT_CONTRIBUTOR_GUIDE.md for AI/automation-assisted contributors: safe
local checks, high-risk broker/MCP/credential surfaces, targeted test hints,
documentation and security rules, PR expectations, and rollback notes. Linked
from CONTRIBUTING.md so agent-assisted contributors see it before changing code.

Adds a guard test (agent/tests/test_agent_guide_paths.py) that parses the guide
for in-repo paths and asserts each still exists, so the guide turns a renamed
test/entry-point into a red CI run instead of silently rotting. pytest --ignore
targets (gitignored e2e suites) and .env do-not-write references are excluded by
design.

Signed-off-by: Haozhe Wu <haozhe_wu@connect.hku.hk>
2026-06-04 18:42:26 +08:00
Haozhe Wu 2c2c072319 docs: add trendshift badge to readmes 2026-06-04 10:43:21 +08:00
Haozhe Wu d1309b4f73 docs(readme): add 2026-06-03 community-triage news entry across 5 locales
Adds the 2026-06-03 News entry (trace call_id correlation #168, dead-doc
reference cleanup #166, langchain-community install-warning clarification
#167, Gemini thoughtSignature scoped to help-wanted #170) to the English,
Chinese, Japanese, Korean, and Arabic READMEs, and collapses the 2026-05-31
entry into the "Earlier news" section to keep three latest entries visible.
2026-06-03 23:39:18 +08:00
Haozhe Wuandzwrong 65a14c632e feat(loop): add call_id to trace entries for tool-call correlation
Adds the tool call_id to the tool_call and tool_result trace records so a
result can be correlated back to its originating call when replaying a trace.
Keeps the existing [:200] truncation on serialized args to avoid bloating
trace files with large tool inputs.

Equivalent to #168 (arg truncation preserved).

Co-authored-by: zwrong <1003912034@qq.com>
2026-06-03 22:59:25 +08:00
Haozhe Wu b5efee66ab docs: remove dead docs/live-trading/SPEC.md references from source comments
The live-trading source files referenced docs/live-trading/SPEC.md in
docstrings, comments, and tests, but docs/ is gitignored (internal planning),
so external contributors hit a dead path when they grep / ls-tree for it.
Genericize the references to "the live-trading SPEC"; docs/ stays internal.

Closes #166
2026-06-03 22:59:21 +08:00
Haozhe Wu 0df32f2eb3 feat(live): direct-SDK bounded-autonomy order gate + HK/CN universe
Function-based mandate gate for direct-SDK live orders mirroring the MCP gate:
mandate load + schema/expiry check, kill-switch halt, quantity→notional pricing,
fail-closed pre-trade checks via check_mandate, per-broker audit, and a daily
count consumed only on a confirmed placement. Shared daily counter (order_guard
now delegates to it). AssetClass gains HK_EQUITY/CN_EQUITY and OrderIntent gains
an explicit asset_class so the mandate gate buckets HK/A-share correctly. The 6
connector classification maps are wired into the live registry for fail-closed
WRITE coverage. Covered by two adversarial audit rounds; full suite 2979 passed.
2026-06-02 12:52:14 +08:00
Haozhe Wu 8563d5e78b feat(trading): add 6 SDK broker connectors with paper+live order placement
Tiger/Longbridge/Alpaca/OKX/Binance/Futu connectors under a new broker_sdk
transport — read-only account/positions/orders/quote/history + paper-account
order placement, plus bounded mandate-gated order placement for five of them.
Longbridge is paper + read-only only (its API exposes no runtime paper/live
discriminator). Per-broker structural paper/live guards: Tiger 17-digit account,
Alpaca/Binance host separation, OKX flag + uid pin, Futu trd_env via get_acc_list.
New trading_place_order/trading_cancel_order tools; generic period/limit wired
through the tool and CLI. News updated across all 5 READMEs.
2026-06-02 12:51:50 +08:00
Haozhe Wu ede8a8b33b fix(ui): clarify dev-jargon labels, drop drift-prone chip counts, add Compare loading state
Addresses UX feedback from #163: rename systems jargon leaking into chrome
(ev -> evidence, Run bench -> Run benchmark, Decay -> Decay (days), Compact
context -> Summarize conversation), add a hint for Reasoning effort, remove
hardcoded skill/preset/tool counts that go stale under frequent releases, and
show a skeleton on the Compare route while run data loads.
2026-06-02 10:37:20 +08:00
Roger de2a180ebd docs: clarify OpenClaw MCP smoke test (#165)
Closes #164
2026-06-02 10:03:56 +08:00
Octopus bcc3ae6405 feat: upgrade MiniMax default model to M3 (#162)
Add MiniMax-M3 as the new default model and retain MiniMax-M2.7 as
the legacy alternative (incl. -highspeed). Update llm_providers.json
registry, cli onboard provider choices, .env.example example, and the
provider-default regression tests.

Signed-off-by: Octopus <liyuan851277048@icloud.com>
Signed-off-by: octo-patch <liyuan851277048@icloud.com>
2026-06-02 00:52:45 +08:00
Haozhe Wu 15c7a9b577 docs(release): credit v0.1.9 cycle contributors across READMEs
Refresh the Contributors section in all 5 READMEs from the v0.1.8 cycle
list to the v0.1.9 cycle (PRs #124–#160): @toanalien, @ai7eam-dev,
@shadowinlife, @DoubleSky123, @ArthurXi, @omcdecor-cyber, @Soli22de,
@ruok808, @faizack, @fightZy, @lcwSeven, @Teerapat-Vatpitak.
2026-06-01 23:07:06 +08:00
Haozhe Wu 5a06371a94 chore(release): 0.1.9
Roll-up release since 0.1.8 — connector-first broker profiles (IBKR +
Robinhood Agentic Trading), Research Goal runtime, swarm reconcile/MCP
keepalive + worker MCP tools + strict alpha-bench + retry_run, the
agent/cli/ package refactor, the mootdx A-share loader, a robustness pass,
and the session/version fixes (#150 #156 #157 #158 + UI indicator).

Version → 0.1.9 across pyproject, SKILL.md, frontend APP_VERSION, and the
wiki docs version selector. MCP tool count corrected to 36 (adds retry_run)
across all 5 READMEs, with the ar/ko tool lists rebuilt from a stale 22 and
the ar skill count fixed 75→77. CHANGELOG [0.1.9] + 0.1.9 news entry added
to all 5 READMEs. Home backtest card data-source count corrected 3→7.
v0.1.9
2026-06-01 23:00:43 +08:00