Commit Graph

51 Commits

Author SHA1 Message Date
Yijia-Xiao
7c8fe2fe9f fix(data): normalize symbols on the identity and reflection paths
resolve_instrument_identity and the reflection return lookup queried Yahoo with
the raw ticker, so broker/forex/commodity symbols (XAUUSD, BTCUSD, EURUSD)
failed identity or could mismatch the priced instrument even though the price
path already normalized them. Route both through normalize_symbol (#983, #984).
2026-06-13 20:39:52 +00:00
Yijia-Xiao
2e67782f20 feat(cli): skip interactive LLM selection when configured via environment (#873)
Setting the LLM env vars now skips the matching CLI selection step and uses
the value, so OpenAI-compatible endpoints (opencode, LM Studio, etc.) and
unattended runs work without prompting. Unset vars are chosen interactively
as before.

  TRADINGAGENTS_LLM_PROVIDER -> skips provider step (still verifies API key)
  TRADINGAGENTS_LLM_BACKEND_URL -> custom endpoint (else provider default)
  TRADINGAGENTS_DEEP_THINK_LLM / _QUICK_THINK_LLM -> skips model step
  TRADINGAGENTS_OUTPUT_LANGUAGE -> skips language step

Builds on the existing TRADINGAGENTS_* config overrides (which already feed
DEFAULT_CONFIG); this wires the CLI to honor them instead of re-prompting.
2026-05-31 22:38:48 +00:00
Yijia-Xiao
1ff3f07a73 fix: support commodity/forex/crypto tickers and never invent prices (#781)
Analyzing a symbol Yahoo Finance does not recognize (e.g. XAUUSD+) could
produce an invented price instead of an error. The agent now either prices
the correct instrument or clearly reports that data is unavailable.

Ticker support:
- Commodities/forex/crypto resolve to the symbol Yahoo actually serves, so
  you can enter the common form and it just works:
    XAUUSD / XAUUSD+ / GOLD  -> GC=F   (gold)
    USOIL                    -> CL=F   (WTI crude)
    EURUSD                   -> EURUSD=X
    BTCUSD                   -> BTC-USD
    SPX500 / NAS100          -> ^GSPC / ^NDX
  Native Yahoo symbols (AAPL, GC=F, ^GSPC) keep working unchanged. New
  instruments are added by extending the alias table.

Reliability:
- Unknown or delisted symbols now return a clear "data unavailable" result
  the agent reports verbatim, instead of a value the model fills in.
- A failed fetch no longer leaves a broken symbol cached until the cache is
  cleared by hand.
2026-05-31 22:38:47 +00:00
Yijia-Xiao
2f85be624e chore(llm): add latest models and default to GPT-5.5
Add Claude Opus 4.8, Gemini 3.5 Flash, Grok 4.3, and Qwen3.7-Max; default
deep model is now GPT-5.5.
2026-05-31 08:01:03 +00:00
Yijia-Xiao
c93b92c7a4 feat(markets): add China A-share benchmarks and document non-US tickers
A-shares already resolve through the Yahoo Finance vendor (Shanghai .SS,
Shenzhen .SZ) with correct identity and indicators; add the SSE/SZSE
composite benchmarks so their alpha isn't measured against SPY, and
document the exchange-suffix tickers we support (incl. A-shares, crypto).
2026-05-31 07:29:19 +00:00
Yijia-Xiao
8694bd070d fix(llm): send MiniMax reasoning_split via extra_body so the openai SDK accepts it (#826) 2026-05-31 06:20:55 +00:00
Yijia-Xiao
2c9f1bfe65 fix(cli): consolidate duplicate get_ticker and only announce non-stock asset type 2026-05-31 06:13:35 +00:00
Yijia-Xiao
8a22594607 feat(config): expose sampling temperature and document reproducibility
Adds a cross-provider temperature config (and TRADINGAGENTS_TEMPERATURE),
forwarded to every LLM client when set, so runs can be made less variable
on models that honor it. Adds a README "Reproducibility" section that
separates the sources of run-to-run variation, what users can control
(temperature, non-reasoning model, pinned date), and what is inherent to
LLM-driven analysis, and notes that the identity and verified-data fixes
already removed the "different companies / fabricated prices" variance.

#178 #168
2026-05-31 03:51:50 +00:00
Yijia-Xiao
47cbb321fe feat(market): verified market-data snapshot to ground numeric claims
The market analyst could confabulate exact figures — citing a Bollinger
band or a "historically validated bounce" the data doesn't support (#830).
Add a deterministic get_verified_market_snapshot tool (latest OHLCV row,
common indicators, recent closes) the analyst must consult and treat as
the source of truth for any exact price/indicator claim, and instruct it
not to assert historical validation or support bounces without tool-backed
dates and prices.

#830
2026-05-31 01:58:32 +00:00
Yijia-Xiao
e80636fc0e feat(sentiment): structured output for the Sentiment Analyst
The analyst emitted free-form prose, so its sentiment header varied by
provider and run and downstream consumers needed drifting regex. Extend
the structured-output pattern the trio already uses: a SentimentReport
schema (band + 0-10 score + confidence + narrative) rendered to a
deterministic header, with a free-text fallback for providers that lack
native structured output.

#796
2026-05-31 01:45:25 +00:00
Yijia-Xiao
a66aa8fb94 fix(deps): require yfinance >=1.4.1 and tolerate non-Date index column
yfinance 1.4.0 regressed the daily-download index to unnamed, so
reset_index() produced an "index" column instead of "Date" and every
stockstats indicator silently failed (no SMA/RSI/MACD/Bollinger/ATR).
Verified across versions: 1.2.0 / 1.3.0 / 1.4.1 name it "Date"; only
1.4.0 is broken. Pin to >=1.4.1 (the upstream fix) and normalize the
date column defensively so a non-"Date" index can't silently drop
indicators on any build.

#890
2026-05-31 00:51:30 +00:00
Yijia-Xiao
3543e5397e fix(dataflows): fall back to Reddit RSS search when JSON 403s
Reddit blocks the anonymous JSON search endpoint, which silently emptied
the sentiment analyst's Reddit source. Fall back to the public RSS search
feed when JSON fails. RSS lacks score/comment counts, so those posts are
marked "via RSS feed" rather than shown with fake zeros.

#862
2026-05-31 00:14:37 +00:00
Yijia-Xiao
d7b40a2a5c fix(graph): resolve instrument identity to stop wrong-company hallucination
Agents had no ground-truth ticker→company mapping, so the market analyst
could pattern-match a price chart to the wrong company (e.g. TOTDY read as
"TotalEnergies"), and every downstream agent inherited the bad framing.

Resolve identity once at run start via a cached, fail-open yfinance lookup
and inject company/sector/exchange into the shared instrument context that
all twelve agents consume, with an explicit do-not-substitute instruction.
Resolution runs on both the propagate() and CLI entry points.

Also replaces the bare "Continue" message-clear placeholder, which some
OpenAI-compatible providers interpreted as the user task, with a
context-anchored placeholder carrying the resolved identity and date.

#814 #888
2026-05-30 23:56:32 +00:00
Yijia-Xiao
61522e103e fix(llm): skip Anthropic effort kwarg on non-supporting models (#831)
Haiku 4.5 rejects the effort parameter with 400. AnthropicClient.get_llm()
now drops effort when the model isn't in the supported set (Opus 4.5+,
Sonnet 4.5+, mythos-preview). Forward-compat regex catches future
claude-{opus,sonnet}-X-Y releases automatically; Haiku and unknown
models stay excluded conservatively.

14 tests cover Haiku exclusion, current Opus/Sonnet inclusion, future-
version inheritance via pattern, mythos-preview, unknown-default
exclusion, and other passthrough kwargs surviving the effort-skip path.
2026-05-17 07:54:06 +00:00
Yijia-Xiao
e848b5e812 fix(llm): gate MiniMax reasoning_split by model capability (#826)
MinimaxChatOpenAI unconditionally set reasoning_split=True, but the
kwarg is only valid on M2.x reasoning models. The openai SDK's strict
kwarg validation raised TypeError for Coding Plan and any other non-
reasoning MiniMax model.

Adds requires_reasoning_split to ModelCapabilities, gates the payload
injection on it, and only sets True for _MINIMAX_THINKING (M2.x exact
IDs and the ^MiniMax-M\d forward-compat pattern). Same shape as the
existing supports_tool_choice gate.

Regression tests cover both halves: M2.x models still receive the flag,
non-reasoning MiniMax models do not.
2026-05-17 07:49:42 +00:00
Yijia-Xiao
3e5e99b368 fix(graph): integrate #487 + #567 — sentiment label, route, propagate asset_type
- analyst_execution.py: rename "Social Analyst" / "Msg Clear Social"
  to "Sentiment Analyst" / "Msg Clear Sentiment" to match v0.2.5.
- conditional_logic.should_continue_social returns the renamed route.
- TradingAgentsGraph.propagate accepts asset_type and threads through
  to Propagator.create_initial_state.
- Regression test on the Sentiment Analyst label.

Verified end-to-end (NVDA stock + BTC-USD crypto) on gpt-5.4-mini.
2026-05-17 07:25:59 +00:00
Yijia Xiao
a2e7ac1599 Merge #567 — analysis-only crypto asset mode
feat: add analysis-only crypto asset mode
2026-05-17 00:01:49 -07:00
Yijia Xiao
b16fe53efe Merge #487 — analyst execution planning and timing hooks
refactor(graph): add analyst execution planning and timing hooks
2026-05-17 00:01:46 -07:00
Yijia-Xiao
78d063dc5c feat(reflection): configurable alpha benchmark for non-US tickers
SPY was hardcoded as the alpha benchmark in both the return-fetch
path and the reflection label, which produced meaningless alpha for
.NS / .T / .HK / .L / .TO / .AX / .BO listings — FX drift between a
local-currency stock and a USD index dominates the spread.

DEFAULT_CONFIG now exposes benchmark_ticker (explicit override) and
benchmark_map (suffix → regional index, with SPY as the empty-suffix
default). TRADINGAGENTS_BENCHMARK_TICKER joins the env-overlay table.
Trading graph resolves the benchmark once per ticker and threads it
through to both _fetch_returns and reflect_on_final_decision, so the
alpha label reads "Alpha vs ^N225" for Tokyo listings, "Alpha vs ^HSI"
for Hong Kong, etc., instead of the misleading "Alpha vs SPY".
2026-05-11 09:14:28 +00:00
Yijia-Xiao
800862405d feat(ollama): allow Custom model ID in the CLI dropdown
Users with other models pulled via `ollama pull` (beyond the three
suggested defaults) can now select "Custom model ID" and type any
model name. Matches the same pattern used for DeepSeek, GLM, Qwen,
and MiniMax — the existing _prompt_custom_model_id flow handles the
"custom" value generically, so this is a one-row catalog addition
plus regression coverage.
2026-05-11 09:03:06 +00:00
Yijia-Xiao
f10daa2824 feat(ollama): OLLAMA_BASE_URL end-to-end with endpoint confirmation
OLLAMA_BASE_URL now flows through both the CLI dropdown and the
programmatic client (call-time evaluation so tests behave). After
provider selection, the CLI prints the resolved endpoint and marks
when it came from the env var, plus a soft warning when the URL is
missing a scheme or non-default port. Drops the stale "(local)"
suffix from Ollama model labels since the endpoint is now dynamic.
2026-05-11 08:46:21 +00:00
CadeYu
249caba06f Merge remote-tracking branch 'upstream/main' into analyst-phase1-observability
# Conflicts:
#	tradingagents/default_config.py
#	tradingagents/graph/setup.py
2026-05-11 16:44:00 +08:00
CadeYu
a2f343bb54 Merge remote-tracking branch 'upstream/main' into crypto-analysis-mvp
# Conflicts:
#	cli/utils.py
#	tradingagents/agents/analysts/social_media_analyst.py
#	tradingagents/agents/researchers/bear_researcher.py
2026-05-11 16:41:09 +08:00
Yijia-Xiao
9f7abfcbd5 feat(cli): detect missing provider API keys and persist to .env
Adds a canonical PROVIDER_API_KEY_ENV mapping (14 providers including
the three dual-region pairs) and an ensure_api_key() helper. When the
selected provider's key is absent from the environment, the CLI prompts
via questionary.password, writes the value to .env via python-dotenv's
set_key (preserves existing lines), and exports it into os.environ so
the run continues without restart. Wired into cli/main.py right after
the region prompts so qwen-cn, glm-cn, and minimax-cn each check their
own region-specific key. openai_client refactored to consult the same
mapping, eliminating its private duplicate of provider→env-var data.
2026-05-11 06:12:34 +00:00
Yijia-Xiao
d13e9b7946 feat(config): TRADINGAGENTS_* env-var overlay for DEFAULT_CONFIG
Adds a single _ENV_OVERRIDES table in default_config.py with type-aware
coercion (str/int/bool), so users can switch llm_provider, deep/quick
models, backend URL, output language, debate rounds, and the checkpoint
flag purely via .env. Centralizes load_dotenv in the package __init__
so the overlay applies for every entry point (CLI, main.py, programmatic).
Drops the hardcoded model assignments and duplicate dotenv loads in
main.py and cli/main.py. Verified live with OpenAI and Gemini.

#602
2026-05-11 06:12:31 +00:00
Yijia-Xiao
d0dd0420ad feat(llm): GLM dual-region split + catalog refresh
Zhipu serves GLM under two brands with separate accounts (Z.AI
international vs BigModel China); the CLI URL pointed at one while
the openai_client default pointed at the other. Split into glm +
glm-cn with secondary region prompt (same UX as Qwen + MiniMax).
Catalog adds glm-5-turbo and glm-4.5-air per docs.z.ai.
2026-05-11 04:19:50 +00:00
Yijia-Xiao
e1316686f8 fix(llm): MiniMax integration polish vs official docs
M2.x tool_choice is enum-only (none/auto), so route through the
no-tool_choice dispatch. MinimaxChatOpenAI injects reasoning_split
so <think> blocks stay out of content. Catalog rounded out to the
full official M2.x lineup plus forward-compat regex.
2026-05-11 02:40:33 +00:00
Yijia-Xiao
9482cae188 fix: bundle config/recursion/missing-key fixes
- dataflows/config: deepcopy + one-level dict merge so a partial
  set_config doesn't clobber sibling defaults
- graph: thread max_recur_limit from config to Propagator
- openai_client: name the missing env var in the API-key error

#788 #764 #680
2026-05-11 02:30:24 +00:00
Yijia-Xiao
22bb91bd83 fix(llm): structured output for DeepSeek V4 and reasoner
DeepSeek V4 and reasoner reject tool_choice but accept tools.
Route via a per-model capability table that suppresses tool_choice
for thinking-mode models.

#678 #689
2026-05-11 01:12:28 +00:00
CadeYu
5bae826749 Merge remote-tracking branch 'upstream/main' into crypto-analysis-mvp
# Conflicts:
#	tradingagents/agents/researchers/bear_researcher.py
#	tradingagents/agents/researchers/bull_researcher.py
#	tradingagents/graph/propagation.py
2026-05-08 18:57:09 +08:00
Yijia-Xiao
7e9e7b83c7 feat: DeepSeek V4 thinking-mode round-trip via DeepSeekChatOpenAI subclass
Resolves #599: thinking-mode models require reasoning_content to be
echoed back across turns; multi-turn agent runs failed with HTTP 400.

The fix isolates DeepSeek's quirks (reasoning_content round-trip and
the deepseek-reasoner no-tool_choice limitation) into a subclass so
the general OpenAI-compatible client stays untouched. Adds DeepSeek
V4 Pro/Flash to the catalog. 9 new tests; rationale documented in
the class docstrings.

Design adapted from #600; #611 closed in favour of this approach.
2026-05-01 19:23:23 +00:00
Yijia-Xiao
2c97bad45c fix(security): validate ticker before using as path component (#618)
The ticker symbol reaches three filesystem-path construction sites
(load_ohlcv cache filename, checkpointer DB path, _log_state results
directory) without validation. A value containing path separators or
"../" escapes the configured cache / checkpoints / results directory.

Two attack vectors:
- Programmatic callers passing arbitrary ticker to propagate()
- Prompt injection via fetched news content steering the LLM into
  tool calls with attacker-chosen ticker

Fix: new safe_ticker_component() validator in tradingagents/dataflows/
utils.py applied at all three sites. Allows the standard ticker
character set ([A-Za-z0-9._\-\^], up to 32 chars) and explicitly
rejects dot-only values like "." and ".." which would otherwise pass
the regex but traverse parent directories. Seven test cases cover
the accepted formats (BRK-B, 7203.T, ^GSPC, etc.) and the rejected
inputs (path separators, null bytes, whitespace, empty values,
overlong strings, dot-only values).

Closes #618.
2026-05-01 18:56:36 +00:00
Yijia-Xiao
7c37249f80 chore: release v0.2.4 — structured agents, checkpoint, memory log, providers
This release bundles substantial work since v0.2.3:

- Structured-output Research Manager, Trader, and Portfolio Manager
  (canonical with_structured_output pattern, single LLM call per agent,
  rendered markdown preserves the existing report shape).
- LangGraph checkpoint resume for crash recovery (--checkpoint flag).
- Persistent decision log replacing the per-agent BM25 memory, with
  deferred reflection driven by yfinance returns + alpha vs SPY.
- DeepSeek, Qwen, GLM, and Azure OpenAI provider support; dynamic
  OpenRouter model selection.
- Docker support; cache and logs moved to ~/.tradingagents/ to fix
  Docker permission issues.
- Windows UTF-8 encoding fix on every file I/O site.
- 5-tier rating consistency (Buy / Overweight / Hold / Underweight / Sell)
  across Research Manager, Portfolio Manager, signal processor, memory log.

Plus the small quality items in this commit:

1. Suppress noisy Pydantic serializer warnings from OpenAI Responses-API
   parse path by defaulting structured-output to method="function_calling"
   (root-cause fix, not a warnings filter — same typed result, no warnings).
2. Ship scripts/smoke_structured_output.py so contributors can verify
   their provider's structured-output path with one command.
3. Add opt-in memory_log_max_entries config — when set, oldest resolved
   memory log entries are pruned once the cap is exceeded; pending
   entries (unresolved) are never pruned.
4. backend_url default changed from the OpenAI URL to None so the
   per-provider client falls back to its native endpoint instead of
   leaking OpenAI's URL into Gemini / other clients.

CHANGELOG.md added with the full v0.2.4 entry. 92 tests pass without API keys.
2026-04-25 22:16:09 +00:00
Yijia-Xiao
bba147798f feat: structured-output Trader and Research Manager (#434, finishes the trio)
Extends the canonical structured-output pattern from the Portfolio Manager
to the other two decision-making agents.  Each of the three agents now
returns a typed Pydantic instance via llm.with_structured_output() in a
single primary call, and a render helper turns the result into the same
markdown shape downstream agents and saved reports already consume.

- ResearchPlan: 5-tier recommendation, conversational rationale, concrete
  strategic actions for the trader.
- TraderProposal: 3-tier action (transaction direction is naturally Buy /
  Hold / Sell — position sizing happens later at the Portfolio Manager),
  reasoning, and optional entry_price / stop_loss / position_sizing.
  Rendered output preserves the trailing "FINAL TRANSACTION PROPOSAL:
  **BUY/HOLD/SELL**" line for backward compatibility with the analyst
  stop-signal text.
- PortfolioDecision: 5-tier rating, executive summary, investment thesis,
  optional price_target / time_horizon (unchanged).

The shared try-structured-then-fallback pattern is extracted into
tradingagents/agents/utils/structured.py (bind_structured +
invoke_structured_or_freetext) so all three agents go through the same
code path and log the same warning when a provider lacks structured
output and the agent falls back to free-text generation.

Net effect for users: every saved markdown report (research/manager.md,
trading/trader.md, portfolio/decision.md) now has consistent section
headers across runs and providers, easier to scan.

Net effect for the runtime: the rating extraction round-trip is gone —
the rating comes from the structured response itself, not a second
LLM call. SignalProcessor was already simplified to a heuristic adapter
in the previous commit.

11 new tests in tests/test_structured_agents.py cover the Trader and
Research Manager render functions, structured-output happy paths, and
free-text fallback. Full suite: 88 tests pass in ~2s without API keys.
2026-04-25 20:27:23 +00:00
Yijia-Xiao
0fda24515f feat: structured-output Portfolio Manager + 5-tier rating consistency (#434)
Three related changes that take the rating pipeline from heuristic-only
to type-safe at the source.

1) Research Manager prompt now uses the same 5-tier scale (Buy /
   Overweight / Hold / Underweight / Sell) as the Portfolio Manager,
   signal_processing, and the memory log.  The prior 3-tier wording
   (Buy / Sell / Hold) was the only remaining inconsistency in the
   pipeline.

2) Centralise the 5-tier vocabulary and the heuristic prose-rating
   parser into tradingagents/agents/utils/rating.py.  Both the memory
   log and the signal processor now share the same parser instead of
   duplicating regex and word-walker logic.

3) Make structured output a first-class part of the Portfolio Manager's
   primary call.  The PM uses llm.with_structured_output(PortfolioDecision)
   so each provider's native structured-output mode (json_schema for
   OpenAI/xAI, response_schema for Gemini, tool-use for Anthropic,
   function_calling for OpenAI-compatible providers) yields a typed
   Pydantic instance directly.  A render helper turns that instance back
   into the same markdown shape downstream consumers (memory log, CLI
   display, saved reports) already expect, so no other code has to know
   the PM now produces structured output.  Providers without structured
   support fall back gracefully to free-text + the deterministic
   heuristic.

   The previous SignalProcessor had been making a second LLM call to
   re-extract the rating from the PM's prose; that round-trip is now
   eliminated.  SignalProcessor is a thin adapter over parse_rating(),
   makes zero LLM calls, and stays for backwards compatibility with
   process_signal() callers.

Schema (PortfolioDecision) captures rating + executive_summary +
investment_thesis + optional price_target + time_horizon, with field
descriptions doubling as output instructions.  Agent prose remains the
primary artifact; structured output is layered onto the PM only because
it is the one agent whose output has machine-readable downstream
consumers.

15 new tests cover the heuristic parser (markdown-bold edge cases that
had no coverage before), the structured PM happy path, the free-text
fallback path, and that SignalProcessor never invokes the LLM.  Full
suite: 77 tests pass in ~2s without API keys.
2026-04-25 19:57:26 +00:00
Yijia-Xiao
4cbd4b086f feat: add LangGraph checkpoint resume for crash recovery (#594)
Long analyses can take many minutes; a crash or interruption forced users
to re-run from scratch and re-pay every LLM call.  This adds an opt-in
checkpoint layer backed by per-ticker SQLite databases so the graph
resumes from the last successful node.

How to use:
- CLI:    tradingagents analyze --checkpoint
- CLI:    tradingagents analyze --clear-checkpoints
- Python: config["checkpoint_enabled"] = True

Lifecycle:
- propagate() recompiles the graph with a SqliteSaver when enabled and
  injects a deterministic thread_id derived from ticker+date so the
  same ticker+date resumes while a different date starts fresh.
- On successful completion the per-thread checkpoint rows are cleared.
- The context manager is closed in a try/finally so a crash never
  leaks the SQLite connection or leaves the graph in checkpoint mode.

Storage: ~/.tradingagents/cache/checkpoints/<TICKER>.db
(override via TRADINGAGENTS_CACHE_DIR).

The checkpointer module is new (tradingagents/graph/checkpointer.py)
and the GraphSetup now returns the uncompiled workflow so it can be
recompiled with a saver when needed.

Adds langgraph-checkpoint-sqlite>=2.0.0 dependency. 3 new tests verify
the crash/resume cycle and that a different date starts fresh.
2026-04-25 08:47:15 +00:00
Yijia-Xiao
ebd2e12e67 feat: replace per-agent BM25 memory with persistent decision log (#578, #563, #564, #579)
The previous per-agent BM25 memory was effectively dead code — its only
caller was a commented-out line in main.py. Replace it with a single
append-only markdown decision log driven by the propagate() lifecycle.

Lifecycle:
- store_decision() appends a pending entry at the end of every run
- _resolve_pending_entries() runs at the start of the next same-ticker
  run, fetches yfinance returns + alpha vs SPY, and writes one LLM
  reflection per resolved entry through an atomic temp-file rename
- Portfolio Manager consumes state["past_context"] (5 most recent
  same-ticker entries plus 3 cross-ticker reflection-only excerpts)

Storage at ~/.tradingagents/memory/trading_memory.md
(override: TRADINGAGENTS_MEMORY_LOG_PATH).

Tag schema:
- Pending:  [YYYY-MM-DD | TICKER | Rating | pending]
- Resolved: [YYYY-MM-DD | TICKER | Rating | +X.X% | +Y.Y% | Nd]

Removes rank-bm25 dependency and the legacy reflect_and_remember()
plumbing across reflection.py, trading_graph.py, and the agent factories.

49 new tests in tests/test_memory_log.py cover the storage, deferred
reflection, prompt injection, and legacy-removal paths. Full suite
(58 tests) passes in under 2 seconds without API keys.
2026-04-25 08:24:03 +00:00
Yijia-Xiao
f85f5d9f5d test: lazy-load LLM provider clients and add API-key fixtures so the test suite runs cleanly without credentials (#588) 2026-04-25 07:41:36 +00:00
Zhigong Liu
6abc768c1d feat: replace per-agent BM25 memory with persistent append-only decision log
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-19 22:43:14 -04:00
CadeYu
99ec63f966 merge upstream main into crypto-analysis-mvp 2026-04-18 21:07:54 +08:00
CadeYu
e7ec980021 feat: add analysis-only crypto asset mode 2026-04-18 20:42:11 +08:00
CadeYu
f4519bcb84 use execution plan metadata for first analyst 2026-03-31 10:09:57 +08:00
CadeYu
4300b68f19 merge upstream main into analyst-phase1-observability 2026-03-31 10:04:35 +08:00
CadeYu
2d2c9e6d66 add analyst execution planning and timing hooks 2026-03-31 09:55:33 +08:00
Yijia Xiao
c61242a28c Merge pull request #464 from CadeYu/sync-validator-models
sync model validation with cli catalog
2026-03-29 11:07:51 -07:00
CadeYu
8793336dad sync model validation with cli catalog 2026-03-25 21:23:02 +08:00
javierdejesusda
047b38971c refactor: simplify api_key mapping and consolidate tests
Apply review suggestions: use concise `or` pattern for API key
resolution, consolidate tests into parameterized subTest, move
import to module level per PEP 8.
2026-03-24 14:52:51 +01:00
javierdejesusda
f5026009f9 fix(llm_clients): standardize Google API key to unified api_key param
GoogleClient now accepts the unified `api_key` parameter used by
OpenAI and Anthropic clients, mapping it to the provider-specific
`google_api_key` that ChatGoogleGenerativeAI expects. Legacy
`google_api_key` still works for backward compatibility.

Resolves TODO.md item #2 (inconsistent parameter handling).
2026-03-24 14:35:02 +01:00
CadeYu
08bfe70a69 fix: preserve exchange-qualified tickers across agent prompts 2026-03-21 21:10:13 +08:00
Yijia Xiao
26c5ba5a78 Revert "Docker support and Ollama support (#47)" (#57)
This reverts commit 78ea029a0b.
2025-06-26 00:07:58 -04:00