30 Commits
Author SHA1 Message Date
sambazhu 22aefb422b feat(agent): env-configurable ReAct iteration cap (VIBE_TRADING_AGENT_MAX_ITERATIONS)
The web-session loop hardcodes max_iterations=50 with no config surface;
heavy multi-step pipelines (a four-layer concept-scoring sweep measured at
52 iterations of real progress) exceed it and die with 'reached max
iterations'. Default stays 50; the cap is read through the config accessor
like every other tuning knob.
2026-10-14 08:52:50 +08:00
sambazhu 00e130f1cf fix(tools): srv-tool client sends the token as a Bearer header
Same transport fix as the loader's (review of #1474): the query-string
token leaks into request-exception logs; the endpoint accepts
Authorization: Bearer, so the URL now carries only the format flag.
2026-09-18 17:07:46 +08:00
sambazhu 9425a5296e fix(tools): coerce EDB value strings to float in srv-tool rows
The EDB rows carry their measurement as a string ("value": "5.4"), so the
grounding evidence extractor — which indexes numeric leaves only — never
saw it while the same row's numeric indicatorcode did. Coercing the
measurement gives the verifier the true values; whether percent claims
verify against generic-tool leaves at all is a wider upstream grounding
question (metric pool admits analysis metrics only), noted separately.
2026-09-18 17:06:57 +08:00
sambazhu fd6f07b1e8 feat(tools): three Gildata research tools over the srv-tool NL endpoint
get_cn_macro_series (MacroIndustryData: China macro/regional/industry EDB
— FRED only covered US/global until now), get_cn_announcements
(AnnouncementData: A-share/HK/fund filings with highlighted excerpts —
get_sec_filings covers SEC only) and search_broker_reports
(FinancialResearchReport: the Juyuan report library, coexisting with the
eastmoney-backed get_research_reports). One thin shared client
(gildata_srv.py: JSON-RPC POST + format=json, own throttle bucket, dual
Accept header), routed api_names echoed so a mis-routed NL question is
visible to the agent, rows capped via limit, key-gated on GILDATA_TOKEN
with an optional GILDATA_SRV_TOOL_URL override. News/screening/FinQuery
deliberately left to the existing tools. MCP surface 75 -> 78.
2026-09-18 17:06:57 +08:00
sambazhu 927c06604c fix(grounding): fund NAV leaves count as price evidence
A fund's NAV is its dated price observation, but the generic leaf aliases
only knew close/price-style names — every unit_nav figure in a get_fund_nav
answer was 'no matching tool evidence', the answer gate rejected the run
twice, and the final answer shipped degraded with the NAV figures redacted
(measured live). Adds unit_nav/accumulated_nav/adjusted_nav (plus the
Chinese spellings) to the price aliases, pinned by a verifier-level test.
2026-09-18 17:06:57 +08:00
sambazhu 12c587ec08 fix(tools): get_fund_nav takes 'funds', not 'codes' — the identity gate made it uncallable
codes/symbols/tickers are the grounding gate's _SYMBOL_ARGUMENT_KEYS: a tool
carrying them demands a search_symbol identity lock from a previous batch,
and the resolver cannot resolve off-exchange fund codes (eastmoney/yahoo
know no 110022.OF) — measured live, the agent loop bounced between
identity_required and identity_conflict forever. The tool self-resolves
identities deterministically (exact ref_code match against the vendor) and
echoes fund_name in every result, so the gate added no safety. Renamed to
'funds' with a regression test pinning the parameter set against the gate's
key set.
2026-09-18 17:06:57 +08:00
sambazhu 1620acef01 feat(tools): get_fund_nav — NAV history for Chinese off-exchange funds
Off-exchange funds publish daily NAV, not OHLCV, so this lands as an
agent tool instead of stretching the loader contract: NetFundUnitValueReport
behind the same ParamCandidateRecall + disk-cache machinery (new otc_fund
wiring). Serves unit/accumulated/adjusted NAV and daily growth, ascending,
most-recent limit, per-fund errors never abort the batch; exchange-listed
codes are rejected with a pointer to get_market_data. Key-gated on
GILDATA_TOKEN; exposed as MCP tool #75 (manifest + six-README lists).
2026-09-18 17:06:57 +08:00
sambazhu 20fc8541bb feat(data): gildata serves HK equities and CN indices via internal-code recall
HKStockDailyQuotes for 00700.HK-style symbols (raw bars, volume already in
shares, stamped raw as a per-market exception after measuring 00700.HK) and
IndexDailyQuote for exchange-specific CN index codes (000xxx.SH / 399xxx.SZ,
so 000001.SZ stays Ping An Bank). Both tools need a Juyuan internal code:
ParamCandidateRecall with an exact ref_code match, cached to
~/.vibe-trading/cache/gildata-codes.json so a symbol costs one round-trip
per machine. Joins the hk_equity chain tail. US equities excluded — this
token's US history is sparse before ~2022 (12 rows in 2020, 134 in 2021),
which would silently corrupt backtests.
2026-09-18 17:06:57 +08:00
sambazhu cbc537da70 fix(data): gildata token moves from the URL query string to the Authorization header
Review of #1474: request exceptions (DNS failure, timeout) embed the full
URL in their message, so a query-string token leaks into error logs. The
endpoint accepts Authorization: Bearer (measured against the live service:
full payload with the header, 1001 without any credential) — the token now
rides the header and the URL carries only the format flag.
2026-09-18 17:06:38 +08:00
sambazhu 275ede9576 docs(skill): manifest source count 27->28 now that gildata registers 2026-09-18 15:10:20 +08:00
sambazhu 998eb2ec2e docs(changelog): note that a saved a_share order stops validating once gildata joins 2026-09-18 13:52:58 +08:00
sambazhu 83a03dc05f fix(data): send the MCP Accept header on gildata calls
The raw-api endpoint answers 400 unless Accept names both JSON and
text/event-stream — caught live after the first deploy, pinned with a
header assertion in the fetch test.
2026-09-18 13:47:36 +08:00
sambazhu 4b48ed9f40 docs: gildata row in data-routing skill, all six READMEs, changelog
Source-count 27->28, table row, A-share chain line, and an Unreleased
changelog entry describing the loader's caliber and auth behavior.
2026-09-18 13:27:39 +08:00
sambazhu 3ee64a47cf feat(settings): gildata token field on the data-sources card
Mirrors the tushare token plumbing end to end: configured/hint fields on
the GET response, token/clear on the PUT, dotenv persistence with env
sync and hot config reset, desktop secure-credential ownership, and the
password input with clear checkbox in all eight locales.
2026-09-18 13:27:39 +08:00
sambazhu 64ebb7cf5c feat(data): gildata (Hundsun Juyuan) A-share OHLCV loader via the raw-api MCP endpoint
Token-gated source talking to api.gildata.com with JSON-RPC POSTs:
StockDailyQuote with restorationStatus=1 serves forward split-and-dividend
adjusted dailies (caliber split_dividend, measured against a live payload),
volume converted from wan-shares to shares, avgprice/prevclose ignored
(different adjustment basis), silent rows:[] treated as no-data so the
fallback chain keeps walking. Joins the a_share chain tail; unavailable
without GILDATA_TOKEN so existing users see no behavior change.
2026-09-18 13:27:33 +08:00
sambazhuandClaude e132aec7b8 docs(settings): surface adjustment-caliber caveat in source priority card
Address PR review feedback (#1231): reordering a market's chain is now
user-facing, but sources differ in adjustment basis (yahoo/yfinance serve
raw OHLC while tencent/eastmoney/tushare serve adjusted prices), so a
reordered chain can silently change backtest numbers. Document the caveat
next to the setting (card + .env.example) in all seven locales; the
provenance stamp itself stays with the #1207 items 6/7 fix.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-27 13:15:55 +08:00
sambazhuandClaude ca54328315 fix(data): read source-order overrides through the config accessor
ci_grep_gates gate (e) rejects raw os.getenv outside src/config/ — the
gate run after the feature caught it. Switch the refresh snapshot to
get_env_value (an un-cached pass-through, so hot-apply semantics are
unchanged), imported inside the function like the sibling loaders'
accessor usage.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-26 18:23:31 +08:00
sambazhuandClaude 4a08d78309 feat(frontend): per-market data-source priority card in Settings
New SourcePrioritySettings card below the data-source form: pick a market,
reorder its fallback chain with up/down buttons (boundary-disabled), reset
to default, or leave it Default-badged. Saving sends every market in one
PUT — a non-default draft persists its order, a default-equal draft sends
null to clear residue in ~/.vibe-trading/.env — and the backend hot-applies
it. Invalid persisted overrides surface an inline warning naming the env
var. Copy added for all 7 locales (parity test enforced); api.ts gains
SourceOrderEntry/SourceOrderUpdate types on the existing data-source
endpoints.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-26 16:30:13 +08:00
sambazhuandClaude ad79b62e9a feat(data): env-configurable per-market source-order overrides
FALLBACK_CHAINS order was hardcoded; users with paid feeds (e.g. Tushare)
could not prioritize them without editing code. Add one env var per market
(MARKET_DATA_ORDER_<MARKET>, e.g. tushare-first for A-shares) whose value
must be a permutation of the market's default chain — invalid values warn
and keep the default, so a typo can never strip a market of sources.

- registry: snapshot default chains; refresh_source_order_overrides()
  reassigns chains in place (dict identity preserved for by-name importers)
  and is snapshot-gated, so override-free environments never touch
  FALLBACK_CHAINS. Hooked at import, _ensure_registered() and fetch start.
- market_data: auto-detected groups start at the override's head; explicit
  source requests, local:/qveris/tickerall codes and the
  fallback_chain_provider test hook keep their existing semantics.
- settings API: GET /settings/data-sources returns per-market
  default/effective/override state; PUT validates permutations (400 before
  persisting), writes ~/.vibe-trading/.env and hot-applies in-process.
- env_schema: declare the 12 vars on DataConfig for visibility.
- tests: registry machinery, market_data routing guards, settings API
  round-trip/reset/validation, env defaults, conftest shell scrub.

Default chains are byte-for-byte unchanged.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-26 16:22:19 +08:00
sambazhuandClaude d76b819a5c fix(api): add fundamental zoo to _VALID_ZOOS whitelist
The fundamental factor zoo (zoo/fundamental/, 4 PIT-safe alphas) shipped
in v0.1.11 and has a frontend card in AlphaZoo, but the API whitelist was
never updated — GET /alpha/list?zoo=fundamental and POST /alpha/bench both
reject it with 400 "unknown zoo 'fundamental'".

Add "fundamental" to _VALID_ZOOS so both endpoints accept it.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-18 09:55:37 +08:00
sambazhuandClaude 03adce85a3 fix(providers): force temperature=1 for the whole Kimi K-series
kimi-k3 rejects any temperature other than 1 ("invalid temperature:
only 1 is allowed for this model"), same as kimi-k2, but the forcing
guard only matched the kimi-k2 prefix — so a default
LANGCHAIN_TEMPERATURE=0.0 config fails on every request with kimi-k3.

Replace the hardcoded prefix tuple with a K-family regex
(kimi-k<digits> + kimi-for-coding) so kimi-k3 and future K-series
reasoning models are covered without another whack-a-mole patch.

Verified against the Kimi for Coding endpoint: both kimi-k3 and its
k3 alias return the temperature error; moonshot-v1-* models are
unaffected. Note: bare aliases like "k3" are intentionally out of
scope for the name-based guard.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-17 16:05:02 +08:00
sambazhu a6b82efba8 fix(frontend): add value investing locale parity 2026-07-07 12:58:22 +08:00
sambazhuandClaude 6c09d25c34 feat(skills): English skill bodies + macro constraints per upstream review
Responding to upstream review feedback:

1. All skill bodies converted to English (matching bundled skills like
   akshare). Some Chinese wording was ambiguous in an international project.
2. Added macro constraints (demographic clock / consumption trend /
   generational shift) per reviewer's point that a consumer-name pick
   should weigh long-term macro headwinds:
   - thesis-tracker: new red line on macro-trend reversal for
     consumer/property/education names.
   - value_investing_committee Li Lu agent: mandatory demographic-clock +
     consumption-trend + generational-shift section for consumer-dependent
     names; a consumer name cannot score high 10-year certainty without
     addressing demographics.

No structural changes; counts unchanged (85 skills, 70 tools, 30 presets).

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-06 17:25:39 +08:00
sambazhuandClaude 5d9fd088ea feat(frontend): add Value Investing examples to welcome screen
Adds a 'Value Investing' category to WelcomeScreen with 4 one-click
examples surfacing the ai-berkshire toolkit:
- Value Investing Committee (run_swarm value_investing_committee, Tencent)
- Supply-Chain Bottleneck Hunter (bottleneck-hunter, AI infra)
- Investment Thesis Tracker (thesis-tracker, Moutai)
- Exact Valuation Check (financial_rigor PE/PB/ROE + three-scenario)

i18n: en + zh-CN (title + desc + prompt). dist is gitignored — CI builds it.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-06 15:35:36 +08:00
sambazhuandClaude bab15351f1 feat(skills): add deep-company-series (P3)
An 8-part publication-grade deep-dive on a single company (~120k words):
cognitive reset / moat / profit engine / hidden assets / era variable /
financials / management / valuation+redlines. The core IP is the strict
fact-check checklist (5 pseudo-precision traps + 7 revision checks) and
the cross-article consistency scan.

Adapted from ai-berkshire's deep-company-series.md. Cross-article scan
reuses report_audit (extract numbers across 8 articles) + financial_rigor
cross_validate (flag >1% deviations) — closes the loop with P1's tools.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-06 15:02:09 +08:00
sambazhuandClaude fdc7e198d1 feat(skills): add data verification discipline + research bias self-check (P3)
P3 of the ai-berkshire fusion — small, broad-impact methodology additions:

- data-routing: add a 'Data Verification Discipline' section — cross-check
  material figures across >=2 sources, flag >1% deviations as caliber
  mismatches, use financial_rigor's cross_validate for exact comparison,
  mark unverified numbers. Pairs with the cross_validate tool added in P1.
- research-discipline (new skill, analysis): a 60-second self-bias checklist
  run at the start of any research task — leader-bias, English-bias,
  narrative-bias, confirmation-bias, recency-bias, with concrete corrections.
  Covers the reasoning layer (vs cross_validate=numbers, report_audit=output).

No code changes, no new deps. Existing data-routing tests still pass (4/4).

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-06 14:46:41 +08:00
sambazhuandClaude 5c438c0d37 fix(swarm): register value_investing_committee in the routing table
The preset YAML was on disk and loadable (inspect_preset valid=True), but
run_swarm refused preset_name='value_investing_committee' as 'Unknown preset'
because _PRESET_NAMES is derived from _PRESET_KEYWORDS, which the new preset
was not added to. The LLM then fuzzy-matched to the similarly-named built-in
investment_committee and ran the wrong team.

Register value_investing_committee in _PRESET_KEYWORDS (value-investing /
Buffett / Munger / Duan Yongping / Li Lu keywords) and add its
{company}/{market} variables to _build_variables.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-06 12:15:04 +08:00
sambazhuandClaude 93da172460 fix(tools): normalize three_scenario growth > 1 as percent
LLMs routinely pass '15%' as 15 instead of 0.15, which made
three_scenario_valuation compound at 1500% and return absurd target prices
(23.5 x 16^3 = 96256 instead of 35.74). The math was correct for the input
given, but the tool silently accepted an unreasonable growth rate.

Now |growth| > 1 is treated as a percent and divided by 100, with a
growth_normalized_from_percent flag and note in the result. Description
also clarified ('0.15 for 15%').

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-06 09:11:15 +08:00
sambazhuandClaude 366e82385b fix(tools): make financial_rigor + report_audit repeatable
loop.py dedups non-repeatable tools by name (a tool already in _called_ok
is refused on a second call). Both tools are read-only and idempotent but
were left at the default repeatable=False, so calling financial_rigor
twice in one session (e.g. verify_valuation then three_scenario) hit a
'cached result, cannot re-invoke' refusal. Set repeatable=True on both.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-06 08:55:26 +08:00
sambazhuandClaude ef74a22370 feat(skills): add value-investing toolkit (rigor + audit + 4 skills + committee preset)
Ports the ai-berkshire value-investing methodology into first-class
Vibe-Trading tools / skills / swarm preset, rewritten for the BaseTool +
SKILL.md + swarm model (no Claude Code slash-commands or TeamCreate).

Tools (auto-discovered BaseTool subclasses, pure stdlib):
- financial_rigor: exact-decimal verification — verify_market_cap,
  verify_valuation, cross_validate, benford, calc, three_scenario. The calc
  evaluator walks an AST in the Decimal domain (0.1 + 0.2 == 0.3 exactly),
  so there is no eval and no IEEE-754 drift.
- report_audit: markdown data-point extraction -> random sample -> PASS/FAIL
  verdict gate. A single-source failure now correctly FAILs the report
  (the source logic silently WARNed instead).

Skills (markdown methodology):
- bottleneck-hunter: supply-chain bottleneck arbitrage — decompose a
  super-trend to Layer 2/3 choke points with mandatory valuation gates.
- thesis-tracker: post-buy discipline — 5-sentence thesis, falsifiable
  assumptions, red lines, 1-10 health score.
- management-deep-dive: management integrity / ability / capital-allocation
  / governance with Duan Yongping's 3-question verdict.
- private-company-research: 6-lens pre-IPO framework (business / financial /
  competitive / risk / tech / alternative-data) with confidence labeling
  and signal-consistency cross-validation.

Swarm preset:
- value_investing_committee: four adversarial master perspectives
  (Buffett / Munger / Duan Yongping / Li Lu) plus a chair synthesizing
  consensus and contradictions into a verdict.

63 new tests; EXPECTED_PRESET_COUNT bumped 29 -> 30.

Inspired by https://github.com/xbtlin/ai-berkshire.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-05 13:39:34 +08:00