Commit Graph
327 Commits
Author SHA1 Message Date
Haozhe Wu b20af90b8d docs: point community Discord to the official HKUDS server
Re-add the Discord badge (5 READMEs) and an issue-template contact removed
in 8346def, now pointing at the org-controlled HKUDS community server
(discord.gg/6TdQnT5xcF, guild 1296348098003734629, ~1.9k members) — the same
server linked from the HKUDS org profile and LightRAG — instead of the
compromised invite. Keeps GitHub Discussions as a second contact.
2026-06-18 22:18:36 +08:00
Haozhe Wu 8346def2aa fix(security): remove compromised Discord invite from README + issue template
The discord.gg/2vDYc2w5 invite (in all 5 READMEs and the issue-template
contact links) resolves to a "Vibe-Trading" Discord server we no longer
control. It runs a fake Collab.Land wallet "verification" via
collab.layers-land.com — a throwaway domain registered 2026-06-18 — that
phishes users' crypto wallets. Remove every public pointer to it and replace
the issue-template community link with GitHub Discussions.
2026-06-18 22:13:12 +08:00
Haozhe Wu 69545dbabd fix(live): extend Robinhood OAuth init timeout (#263) 2026-06-18 21:42:28 +08:00
83ec532564 feat(autopilot): add goal-hypothesis bridge for Research Autopilot Phase 1 (#260)
* feat(autopilot): add goal-hypothesis bridge for Research Autopilot Phase 1

New `run_research_autopilot` agent tool that connects the Hypothesis
Registry to the Research Goal runtime. Given a hypothesis_id, the tool
reads the hypothesis, creates a research goal with the thesis as
objective and backtest-relevant criteria, and returns a goal snapshot
with next-step hints.

Auto-registered via BaseTool subclass discovery.

Signed-off-by: Robin1987China <fanrenzhige@163.com>

* feat(autopilot): add generate_backtest_config tool for Phase 2

New `generate_backtest_config` tool auto-generates backtest config.json
from hypothesis metadata. Maps universe names (CSI 300, S&P 500, etc.)
to standard index codes and uses hypothesis.data_sources for the source
field. Writes config.json to a run directory and returns the path so the
agent can proceed to create signal_engine.py and call backtest.

Signed-off-by: Robin1987China <fanrenzhige@163.com>

* fix: harden research autopilot config generation

---------

Signed-off-by: Robin1987China <fanrenzhige@163.com>
Co-authored-by: Robin1987China <fanrenzhige@163.com>
Co-authored-by: Haozhe Wu <haozhe_wu@connect.hku.hk>
2026-06-18 21:39:49 +08:00
Haozhe Wu d6bf209303 fix(provider): parse DeepSeek DSML tool calls
Fixes #261.
2026-06-18 21:38:57 +08:00
cf32a6dfaa feat(loaders): add local data loader for CSV/Parquet/DuckDB files (#252)
* feat(loaders): add local data loader for CSV/Parquet/DuckDB files

- New 'local' loader reads OHLCV from user-configured CSV/Parquet/DuckDB sources
- Config file at ~/.vibe-trading/data-bridge/config.yaml maps symbols to files
- Symbols prefixed with 'local:' auto-route to the local data source
- Integrated into loader registry with fallback chain support

Signed-off-by: Robin1987China <fanrenzhige@163.com>

* fix: allow duckdb local loader without path

---------

Signed-off-by: Robin1987China <fanrenzhige@163.com>
Co-authored-by: Robin1987China <fanrenzhige@163.com>
Co-authored-by: Haozhe Wu <haozhe_wu@connect.hku.hk>
2026-06-18 21:37:39 +08:00
HinotobiandHaozhe Wu 43d33a036f [security] fix(live): contain mandate proposal identifiers (#256)
* fix: contain live mandate proposal identifiers

* test: use valid mandate proposal id in consent helper

---------

Co-authored-by: Haozhe Wu <haozhe_wu@connect.hku.hk>
2026-06-18 21:34:49 +08:00
Hinotobi 078ce6fcd2 fix(security): contain MCP swarm run IDs (#258)
Signed-off-by: hinotoi-agent <paperlantern.agent@gmail.com>
2026-06-18 21:30:30 +08:00
Hinotobi 27c74932b1 fix(memory): validate persistent memory types (#257)
Signed-off-by: hinotoi-agent <paperlantern.agent@gmail.com>
2026-06-18 21:30:23 +08:00
Haozhe Wu 1387b213d6 docs: update June 16 and 17 news 2026-06-17 01:30:35 +08:00
Haozhe Wu 7aa6b1d960 test: cover assistant-prefill handoff paths (#251) 2026-06-17 01:19:52 +08:00
卫斯李andwesley d0ff3599c1 fix(loop,providers): prevent assistant prefill errors + configurable Kimi User-Agent (#248)
- Replace assistant-role handoff messages with user-role in agent loop
  to avoid "assistant message prefill" rejection on Anthropic Claude Opus 4.8+
- Allow MOONSHOT_USER_AGENT env var to override Kimi/Moonshot User-Agent header
  for compatibility with Kimi Coding API endpoint

Closes #246, Closes #204

Signed-off-by: wesley <wesley87@wesley87deMacBook-Pro.local>
Co-authored-by: wesley <wesley87@wesley87deMacBook-Pro.local>
2026-06-17 01:17:24 +08:00
Matt Van HornandMatt Van Horn 43ffd041c0 feat(providers): add glm/zhipu provider alias and model-name inference (#247)
Add a first-class `glm` alias of the existing `zhipu` provider so a model
name like `glm-4.6`/`glm-5.1` resolves to the Zhipu capability record and
base URL instead of silently falling back to the OpenAI slot.

- capabilities.py: share one `_ZHIPU_CAPABILITIES` record between `zhipu`
  and the new `glm` alias (mirrors kimi/moonshot), and infer `zhipu` for
  model ids starting with `glm`.
- llm_providers.json: register a `glm` entry aliasing the Zhipu env names
  and default model so onboarding/diagnostics surface it.
- tests: cover the alias, model-name inference, env-name resolution, the
  unchanged openai fallback, and the new registry default.

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-17 01:17:20 +08:00
Haozhe Wu ecbbd72eff fix: make harmonic backend optional (#250) 2026-06-17 01:11:51 +08:00
Hinotobi 97c67c9bb5 [security] fix(api): require auth for settings writes (#245)
Require a valid bearer token (not just loopback peer IP) for settings WRITE endpoints (/settings/llm, /settings/data-sources) when API_AUTH_KEY is configured, closing a DNS-rebinding / loopback-trust bypass while keeping zero-config local dev writes.

Also reconciles the DNS-rebound security tests across the #241-#245 sprint: now that #242's rebound-host middleware 403s loopback requests with an attacker-controlled Host before they reach the route, the end-to-end rebound tests for /swarm/runs and /sessions/messages (#243) and /settings/llm (#245) assert the request is rejected at the host-gate layer (403) and never reaches the shell-tool / settings-write decision. Full suite: 3217 passed.
2026-06-16 00:51:58 +08:00
Hinotobi 0568527cd6 [security] fix(api): require explicit opt-in for agent shell tools (#243)
* fix(api): require explicit opt-in for swarm shell tools

* test: cover session shell tool opt-in boundary
2026-06-16 00:37:50 +08:00
Hinotobi e5ee704e2e fix(api): reject untrusted loopback hosts (#242) 2026-06-16 00:37:18 +08:00
Hinotobi 73d3e1153b fix: require explicit auth for local shutdown (#241)
Signed-off-by: hinotoi-agent <paperlantern.agent@gmail.com>
2026-06-16 00:36:27 +08:00
sambazhu 205e4c1843 fix(frontend): sync completed chat attempts (#236) 2026-06-16 00:36:07 +08:00
gyx09212214-prog 9ba1f7bf7b fix(loaders): tolerate malformed RSSHub timeout env vars (#240)
Signed-off-by: gyx09212214-prog <gyx09212214@gmail.com>
2026-06-16 00:36:03 +08:00
gyx09212214-prog f4ce8b44d4 test(search): cover ddgs retry fallback behavior (#239) 2026-06-16 00:35:58 +08:00
gyx09212214-prog d8c55f3112 fix(run-card): write strict JSON for non-finite metrics (#238)
Signed-off-by: gyx09212214-prog <gyx09212214@gmail.com>
2026-06-16 00:35:52 +08:00
Haozhe Wu f63849e55e docs: news for 06-15 — web_search multi-engine resilience + Web UI run-continuity (#229) 2026-06-15 18:38:37 +08:00
Haozhe Wu f0ba648b1f fix(agent): make Stop responsive mid-stream and between tools (#229) (#235)
Symptom 2 of #229: clicking Stop during a run did nothing, or only took
effect after a long delay. The cancel signal (_cancelled bool) was polled
only at the top of the ReAct iteration loop, so a Stop pressed while the
agent was mid-LLM-stream or executing tools was ignored until the entire
current iteration — the whole streamed answer plus all its tool calls —
finished and the next iteration check ran.

Add cooperative cancel checkpoints at the granularity the user actually
waits on:

- Switch _cancelled to a threading.Event (_cancel_event) so the flag is
  safe to poll from the streaming thread.
- Thread a should_cancel predicate into ChatLLM.stream_chat; the per-chunk
  loop breaks as soon as it is set, so a live stream stops at the next
  token instead of running to completion.
- After the stream returns, check the flag before processing tool calls:
  a cancel during streaming ends the run immediately and discards the
  partial turn (no tools run).
- Check the flag at the top of _process_tool_calls and between tool batches
  in _batch_execute, so a multi-tool turn stops after the current tool
  rather than launching the rest.

Limitation (documented in the PR): a connection that hangs before emitting
any chunk leaves the worker blocked in a socket read, which Python cannot
interrupt cooperatively from another thread; that case stays bounded by the
existing client timeout (TIMEOUT_SECONDS). Cancel now lands promptly in all
the normal "working" states (tokens streaming, tools running).

Tests: chat-level should_cancel breaks the chunk loop (and absence is a
no-op); loop-level cancel mid-stream ends the run as cancelled and skips
tool execution. Full suite: 3199 passed, 2 skipped.
2026-06-15 17:41:43 +08:00
Haozhe Wu 9b9e9f50a0 fix(web): reconnect SSE when returning to a running session (#229) (#234)
Symptom 1 of #229: navigating away from the chat page and back often made
the agent "stop working". The page run is server-side and the frontend only
subscribes via SSE; the unmount cleanup tore down that stream, but the
navigation effect only (re)subscribed when the URL session differed from the
store session. Returning to the SAME session hit neither branch, so SSE was
never reopened — in-flight events stopped arriving and the run looked frozen
until the 90s safety timeout flipped it to idle.

The backend already buffers events per session and replays them on connect
(GET /sessions/{id}/events?replay=active), and setupSSE already requests it;
the only defect was the missing re-subscribe on same-session remount.

Add that branch: re-hydrate like a reload — reset the transient streaming
view first (so replay=active rebuilds the in-flight turn from the ring buffer
instead of duplicating deltas onto the preserved text), refresh committed
history (covers an attempt that finished while away), then re-subscribe.

Symptom 2 (Stop ineffective during a hung/long turn) is cooperative-cancel
granularity in the agent core and is tracked separately.

Verified: tsc clean, frontend build passes, existing store/useSSE/Runtime
tests green (42).
2026-06-15 17:40:56 +08:00
Haozhe Wu 541c4e5d8c ci: bump first-party actions to Node 24 (checkout/setup-python/setup-node v6) (#233)
GitHub forces Node 20 actions onto the Node 24 runtime starting 2026-06-16
and removes Node 20 from runners on 2026-09-16. Bump the three first-party
actions to their latest Node-24-native majors across all workflows:

- actions/checkout v4 -> v6
- actions/setup-python v5 -> v6
- actions/setup-node v4 -> v6

Inputs are unchanged (node-version "20" is the frontend JS runtime, not the
action runtime). Third-party cloudflare/wrangler-action is out of scope.
2026-06-15 17:08:04 +08:00
Haozhe Wu 04480e8a03 fix(tools): make web_search resilient via multi-engine fallback (#232)
web_search relied on ddgs's default 'auto' backend, which leads with
DuckDuckGo — heavily rate-limited from cloud/shared IPs. When DDG
threw, the whole tool returned ❌ (issue #231) even though Google/
Bing/Brave/Mojeek/Yahoo were reachable.

- Pass an explicit ordered backend list so ddgs falls through a
  throttled engine to the next; override via VIBE_TRADING_SEARCH_BACKENDS
- Retry transient failures with linear backoff (3 attempts)
- Treat "No results found" as an ok+empty envelope, not an error
- On persistent failure, return an actionable message (retry / set
  backend env / use read_url) instead of a bare exception string
- Report the backend list used in the ok envelope

Tests: new tests/test_web_search_tool.py (6 cases, mocked ddgs) cover
multi-backend pass-through, env override, retry-then-succeed,
no-results, persistent-failure message, and max_results cap.
2026-06-15 17:01:32 +08:00
bhlt 5399a078e8 fix(baostock): support baostock-native code format (sh.601398) (#230)
The baostock loader previously only accepted tushare-style codes (601398.SH)
and silently rejected baostock-native codes (sh.601398) — the format baostock
uses in its own docs. _is_a_share() now accepts both (case-insensitive), and
_fetch_one() passes native codes through unchanged while still converting
tushare-style suffixes. Adds 10 unit tests.

Thanks to @bhlt for the fix.
2026-06-15 16:38:49 +08:00
Haozhe Wu 59d98a741b docs: news for 06-14 — per-run token usage + progressive Run Detail charts 2026-06-14 23:03:30 +08:00
gyx09212214-prog 9f5b8afe7b fix(loaders): tolerate malformed crypto timeout env vars (#227)
Malformed values like CCXT_TIMEOUT_MS=abc / OKX_TIMEOUT_S=abc raised ValueError at import time and could block startup. Add shared positive_env_int/float helpers in loaders/base.py; invalid/blank/non-positive timeout/budget values now warn and fall back to defaults. Valid values still honored.

Closes #227.
2026-06-14 22:25:29 +08:00
gyx09212214-prog 9e7c1a8772 fix(loaders): include requested yfinance end date (#226)
yfinance download(end=...) is exclusive while the loader API treats end_date as inclusive, so the final trading day was dropped. Pass end_date + 1 day to the yfinance call (bulk + single-symbol fallback); cache lookups/writes keep the original requested range.

Closes #226.
2026-06-14 22:25:26 +08:00
LemonCANDY42 88dd54c7c3 perf(run-detail): add opt-in chart payloads (#225)
Add opt-in chart payload modes for the Run Detail endpoint and UI. Default /runs/{id} stays byte-for-byte unchanged; ?chart_payload=summary returns metadata + chart_symbols (no bars/markers); ?chart_symbol=SYM returns one symbol's bars+markers. Run Detail UI renders summary first, then progressively loads selected symbols with loading/progress + cancel. New copy localized en + zh-CN.

Refs #215.
2026-06-14 22:14:50 +08:00
LemonCANDY42 8678c289ce feat(agent): persist AgentLoop usage artifacts (#223)
Persist provider-reported AgentLoop usage as a run-scoped artifact (<run_dir>/llm_usage.json) and surface it additively on /runs/{id}. Provider-reported tokens only — no prompt/content capture, no price estimation. Behind the existing usage guard so providers without usage_metadata write nothing. Live llm_usage SSE event keys unchanged.

Refs #214.
2026-06-14 21:52:11 +08:00
Haozhe WuandLanre Shittu ccfe50fff2 fix(loaders): land RSSHub event/sentiment provider with explicit feed config
Builds on @Shizoqua's verified provider core (#201) and resolves the three
open-box blockers from review:

- No built-in feed catalogue: the shipped DEFAULT_FEEDS routes (/stock/notice,
  /stock/news) don't exist in RSSHub, so a default run scored every bar 0.0.
  Feeds are now declared explicitly in config (event_feeds = list of
  {name, route_template, event_type, code_style}); DEFAULT_FEEDS is empty, so
  there is nothing to silently rot as RSSHub routes evolve.
- Per-symbol code formatting: a feed declares a code_style
  (raw / bare / exchange_prefix), so dotted backtest codes (600519.SH) are
  rewritten to the form a route needs (e.g. SH600519 for xueqiu-style routes).
- No silent all-zero scores: each fetch failure is logged per feed/code, and
  query_events raises EventProviderError when every fetch failed (configured
  but fully unreachable) instead of returning an all-zero event_score that
  reads as "sentiment considered, no signal". A reachable feed that returned
  no items stays a legitimate empty result.

PIT discipline, defusedxml hardening, the pluggable scorer, and the
engine/runner wiring are otherwise unchanged. Adds 12 tests for the code
styles, config parsing/validation, and the loud-failure path.

Thanks @Shizoqua (#201) for the provider core.

Co-authored-by: Lanre Shittu <136805224+Shizoqua@users.noreply.github.com>
2026-06-14 06:50:02 +08:00
Haozhe Wuandskloxo f470947c81 feat(loaders,i18n): add baostock/tencent A-share sources + zh-CN frontend i18n
A-share data sources (free, no-auth, bypass eastmoney CDN IP blocks):
- baostock loader (TCP protocol) + tencent loader (HTTP), both wrapped with
  cached_loader_fetch like the mootdx/akshare loaders so they honor the opt-in
  local cache
- registered into the a_share fallback chain (tushare -> mootdx -> baostock ->
  tencent -> akshare); auto-detect default source stays tushare
- pyproject [ashare] extra for the optional baostock dependency

Frontend i18n (English default, sidebar toggle to Chinese, persisted):
- i18next + react-i18next + browser-languagedetector; first visit defaults to
  English (localStorage-only detection, no navigator sniff), the toggle persists
  the choice across reloads
- en / zh-CN locales at full key parity, including the Runtime page
- i18n initialized in the test setup so useTranslation resolves real strings;
  restored the exported METRIC_LABELS so formatters consumers/tests keep working

Thanks @skloxo (#217) for the i18n layer and the A-share data sources.

Co-authored-by: skloxo <skloxo@users.noreply.github.com>
2026-06-14 06:50:02 +08:00
LemonCANDY42 b215e99805 feat(frontend): add read-only runtime status dashboard (#210)
Adds a dedicated /runtime page + sidebar entry rendering read-only /live/status: global halt, broker auth presence, runner liveness, active mandate limits/expiry, and derived runtime risk state. Fail-closed unavailable + empty-profile states. No write controls (no order/mandate/authorize/start/stop).

Verified locally: tsc --noEmit clean, Runtime.test.tsx 3/3 pass, vite build OK.
2026-06-14 05:12:04 +08:00
Haozhe Wu 4207392433 docs: news for 06-13 — resume past session by ID from the CLI (#218) 2026-06-14 00:12:03 +08:00
Haozhe Wu b2573b4689 Merge pull request #218 from zwrong/pr/trace-offload
feat(cli): show session-id on exit, add `resume <session-id>` subcommand
2026-06-14 00:01:51 +08:00
zwrong 8a02b7c87f refactor(cli): extract _build_session_history, add resume-by-id tests
Simplify / Brooks-Lint follow-up:

- Extract _build_session_history() helper to eliminate the duplicated
  get_messages -> role/content filter -> _HISTORY_RETAINED_TURNS slice
  pattern from both _maybe_resume_last_session and the resume path.
- Use _extract_max_iter instead of hardcoded max_iter=50 for the resume
  dispatch so future default changes propagate consistently.
- Add TestResumeByIdDispatch (3 tests) covering the vibe-trading resume
  <session-id> CLI dispatch path — previously uncovered.

Signed-off-by: zwrong <1003912034@qq.com>
2026-06-13 17:25:56 +08:00
zwrong 2317947c4e feat(cli): add vibe-trading resume <session-id> and exit session-id display
Exit interactive CLI shows the session ID so users can copy-paste
`vibe-trading resume <id>` to resume later. The resume subcommand
loads a specific session by ID and enters the interactive loop with
full history — messages are persisted through the existing
_run_one_turn / _append_message path.

Signed-off-by: zwrong <1003912034@qq.com>
2026-06-13 17:25:33 +08:00
Haozhe Wu 8b0199d4b5 Merge pull request #206 from zwrong/pr/trace-offload
feat(agent): complete trace.jsonl overhaul — zero truncation, offload, message entries, iter consistency
2026-06-13 01:22:00 +08:00
Haozhe Wuandzwrong 4f70258d40 fix(trace): rebase trace offload onto current main
Co-authored-by: zwrong <1003912034@qq.com>
2026-06-13 01:21:24 +08:00
Haozhe Wu 4c4565a50f fix(web): clear partial stream text on provider retry 2026-06-13 01:02:00 +08:00
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