Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/CONFIGURATION_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ models:

# Fallback models for different providers
provider_models:
siliconflow: "qwen/qwen-max"
siliconflow: "qwen/qwen3-max"
google: "gemini-2.5-flash"

# Model-specific parameters (override provider defaults)
Expand Down
6 changes: 3 additions & 3 deletions python/configs/providers/openrouter.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ connection:
api_key_env: "OPENROUTER_API_KEY"

# Default model if none specified
default_model: "qwen/qwen-max"
default_model: "qwen/qwen3-max"

# Model Parameters Defaults
defaults:
Expand All @@ -29,8 +29,8 @@ models:
name: "Claude Haiku 4.5"
- id: "x-ai/grok-4"
name: "Grok 4"
- id: "qwen/qwen-max"
name: "Qwen Max"
- id: "qwen/qwen3-max"
name: "Qwen3 Max"
- id: "openai/gpt-5"
name: "GPT-5"
- id: "google/gemini-2.5-flash"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

from loguru import logger

from valuecell.utils.ts import get_current_timestamp_ms
from valuecell.utils.uuid import generate_uuid

from ..decision import BaseComposer
Expand Down Expand Up @@ -37,7 +38,6 @@
from ..utils import (
extract_market_snapshot_features,
fetch_free_cash_from_gateway,
get_current_timestamp_ms,
)

# Core interfaces for orchestration and portfolio service.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
from loguru import logger

from valuecell.agents.common.trading import models as agent_models
from valuecell.agents.common.trading.utils import get_current_timestamp_ms
from valuecell.server.db.repositories.strategy_repository import get_strategy_repository
from valuecell.server.services import strategy_persistence
from valuecell.utils.ts import get_current_timestamp_ms

if TYPE_CHECKING:
from valuecell.agents.common.trading._internal.coordinator import (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from __future__ import annotations

import json
from datetime import datetime, timezone
from typing import Dict

from agno.agent import Agent as AgnoAgent
Expand Down Expand Up @@ -87,7 +86,9 @@ async def compose(self, context: ComposeContext) -> ComposeResult:
return ComposeResult(instructions=[], rationale=plan.rationale)
except Exception as exc: # noqa: BLE001
logger.error("LLM invocation failed: {}", exc)
return ComposeResult(instructions=[], rationale="LLM invocation failed")
return ComposeResult(
instructions=[], rationale=f"LLM invocation failed: {exc}"
)

# Optionally forward non-NOOP plan rationale to Discord webhook (env-driven)
try:
Expand Down Expand Up @@ -210,9 +211,13 @@ async def _call_llm(self, prompt: str) -> TradePlanProposal:

logger.error("LLM output failed validation: {}", content)
return TradePlanProposal(
ts=int(datetime.now(timezone.utc).timestamp() * 1000),
items=[],
rationale="LLM output failed validation",
rationale=(
"LLM output failed validation. The model you chose "
f"`{model_utils.describe_model(model)}` "
"may be incompatible or returned unexpected output. "
f"Raw output: {content}"
),
)

async def _send_plan_to_discord(self, plan: TradePlanProposal) -> None:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
InstrumentRef,
MarketSnapShotType,
)
from valuecell.agents.common.trading.utils import get_current_timestamp_ms
from valuecell.utils.ts import get_current_timestamp_ms


class MarketSnapshotFeatureComputer:
Expand Down
7 changes: 6 additions & 1 deletion python/valuecell/agents/common/trading/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

from pydantic import BaseModel, Field, field_validator, model_validator

from valuecell.utils.ts import get_current_timestamp_ms

from .constants import (
DEFAULT_AGENT_MODEL,
DEFAULT_CAP_FACTOR,
Expand Down Expand Up @@ -588,7 +590,10 @@ def _normalize_instrument(cls, data):
class TradePlanProposal(BaseModel):
"""Structured output before rule normalization."""

ts: int
ts: Optional[int] = Field(
default_factory=get_current_timestamp_ms,
description="Proposal timestamp in ms (if available)",
)
items: List[TradeDecisionItem] = Field(default_factory=list)
rationale: Optional[str] = Field(
default=None, description="Optional natural language rationale"
Expand Down
6 changes: 0 additions & 6 deletions python/valuecell/agents/common/trading/utils.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import os
from datetime import datetime, timezone
from typing import Dict, List, Optional, Tuple

import ccxt.pro as ccxtpro
Expand All @@ -13,11 +12,6 @@
from valuecell.agents.common.trading.models import FeatureVector


def get_current_timestamp_ms() -> int:
"""Get current timestamp in milliseconds."""
return int(datetime.now(timezone.utc).timestamp() * 1000)


async def fetch_free_cash_from_gateway(
execution_gateway, symbols: list[str]
) -> Tuple[float, float]:
Expand Down
11 changes: 9 additions & 2 deletions python/valuecell/utils/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
- Backward compatible: Environment variables still work for model_id override
"""

import logging
import os
from typing import Optional

Expand All @@ -19,6 +18,7 @@
from agno.models.openai import OpenAILike as AgnoOpenAILikeModel
from agno.models.openrouter import OpenRouter as AgnoOpenRouterModel
from agno.models.siliconflow import Siliconflow as AgnoSiliconflowModel
from loguru import logger

from valuecell.adapters.models.factory import (
create_embedder,
Expand All @@ -27,7 +27,14 @@
create_model_for_agent,
)

logger = logging.getLogger(__name__)

def describe_model(model: AgnoModel) -> str:
try:
model_description = f"{model.id} (via {model.provider})"
except Exception:
model_description = "unknown model/provider"

return model_description


def model_should_use_json_mode(model: AgnoModel) -> bool:
Expand Down
6 changes: 6 additions & 0 deletions python/valuecell/utils/ts.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from datetime import datetime, timezone


def get_current_timestamp_ms() -> int:
"""Get current timestamp in milliseconds."""
return int(datetime.now(timezone.utc).timestamp() * 1000)