Commit Graph

16 Commits

Author SHA1 Message Date
tinkle-community 966995fb88 refactor: remove BlockRun provider, retain Claw402 as sole x402 payment provider
Remove all BlockRun (Base + Solana wallet) references from codebase:
- Delete blockrun_base.go, blockrun_sol.go, wallet setup docs, icon
- Move shared EIP-712 signing code to x402.go for Claw402 reuse
- Clean up provider constants, model lists, UI components, translations
- Update all README files (EN + 6 i18n) and getting-started docs
2026-03-24 01:44:54 +08:00
tinkle-community 8e294a5eed refactor: restructure project directories for better modularity
- Delete llm/ dead code (3 files, zero references)
- Split mcp/ into sub-packages: mcp/provider/ (8 providers) and
  mcp/payment/ (4 payment clients) with registry pattern
- Export Client internal fields and ClientHooks interface for
  sub-package access
- Split api/server.go (3892 lines) into 8 domain-specific handler files
- Split trader/auto_trader.go (2296 lines) into 5 focused files
- Reorganize web/src/components/ flat files into auth/, charts/,
  trader/, common/, modals/, backtest/ subdirectories
- Update all consumer imports to use registry-based provider creation
2026-03-11 23:58:13 +08:00
tinkle-community 9c5c976d9a feat: Claw402 x402 payment provider + Telegram agent + x402 refactoring (#1409)
* feat(telegram): add AI agent bot with streaming and account context

- Add Telegram bot with long-polling and AI agent loop (api_call tool)
- SSE streaming with real-time message editing and  placeholder
- Account state injection at conversation start (models, exchanges,
  strategies, traders, per-trader PnL and statistics)
- Lane semaphore per chat serializes concurrent messages (60s timeout)
- Idle timeout watchdog (60s) prevents hung streaming connections
- Look-ahead buffer prevents partial <api_call> tag leaking to user
- Fix PUT /strategies/:id to merge config (read-then-merge pattern)
- Add route registry with full API schema for LLM documentation
- Add TelegramConfig store and Web UI config modal
- Add GetAnyEnabled to AIModel store for bot LLM client selection

* fix(telegram): eliminate narration, add full-setup workflow and tests

- Rewrite NO NARRATION rule: response is EITHER api_call tag alone OR
  final text reply — no text before api_call under any circumstances
- Ban all narration patterns: 现在我将/好的/正在/I will/Let me etc.
- Add 'create strategy + create trader + start' full setup workflow
- Add 12 automated tests covering:
  - No narration leaking to user (5 narration variants tested)
  - api_call tag never leaks to user
  - Full setup workflow: POST strategy → verify → POST trader → start
  - Start existing trader workflow
  - Max iterations safety, tag stripping, parser edge cases

* refactor(agent): replace XML api_call with native function calling

Migrate the Telegram bot agent from an XML tag hack (<api_call>) to
OpenAI-native function calling via CallWithRequestFull.

Key changes:
- mcp/interface.go: add parseMCPResponseFull to clientHooks interface
- mcp/client.go: route callWithRequestFull through hooks for overridability
- mcp/claude_client.go: override parseMCPResponseFull for Claude response
  format (tool_use blocks instead of choices[].message.tool_calls)
- telegram/agent/agent.go: rewrite Run() to use CallWithRequestFull;
  define api_request tool with JSON Schema; implement tool-call loop
  with role="tool" result messages; remove XML parsing entirely
- telegram/agent/apicall.go: remove parseAPICall (dead code)
- telegram/agent/prompt.go: simplify — remove XML format instructions,
  replace with concise api_request tool usage instructions
- telegram/agent/agent_test.go: rebuild all tests using LLMResponse
  objects; add TestNarrationStructurallyImpossible, TestOnChunkCalledWithFinalReply,
  TestToolCallIDPropagated; remove XML-specific tests

Architecture advantage: with native function calling, the LLM returns
EITHER ToolCalls OR Content — never both. Narration is now structurally
impossible at the protocol level, not just enforced by prompt rules.

All 11 agent tests pass. mcp package tests pass.

* refactor(mcp): route buildRequestBodyFromRequest through hooks + full Anthropic format

Problem: callWithRequest/Full/Stream all called client.buildRequestBodyFromRequest
directly (not via hooks), so ClaudeClient could never override it. This meant
tool calling sent OpenAI format to Anthropic (wrong field names, wrong roles).

Changes:

mcp/interface.go
- Add buildRequestBodyFromRequest(*Request) map[string]any to clientHooks
- Improve comments: document what each hook group does and why

mcp/client.go
- All three paths (callWithRequest, callWithRequestFull, CallWithRequestStream)
  now call client.hooks.buildRequestBodyFromRequest — ClaudeClient picks up

mcp/claude_client.go
- Full rewrite with format comparison table in package doc
- buildRequestBodyFromRequest: produces correct Anthropic wire format
    * system prompt → top-level "system" field
    * tools: parameters → input_schema, no "type:function" wrapper
    * tool_choice "auto" → {"type":"auto"} object
    * assistant tool calls → content[{type:tool_use, id, name, input}]
    * role=tool results → role=user content[{type:tool_result,...}]
    * consecutive tool results merged into single user turn
- convertMessagesToAnthropic: handles all three message types
- parseMCPResponseFull: extracts text + tool_use blocks
- parseMCPResponse: delegates to parseMCPResponseFull

All mcp and agent tests pass.

* fix(telegram): fix claude client dispatch + strategy creation workflow

- telegram/bot.go: clientForProvider now returns NewClaudeClient() for
  'claude' provider (was incorrectly falling back to DeepSeekClient which
  uses OpenAI wire format, breaking Anthropic API calls)

- api/server.go: fix scan_interval_minutes schema default (3, not 60);
  POST /api/strategies now clearly states config is OPTIONAL with complete
  working defaults; POST /api/traders removes redundant GET workflow note

- telegram/agent/prompt.go: simplify strategy creation — just POST {name}
  without config (backend applies full working defaults automatically);
  only include config when user requests custom settings

* test(mcp): add ClaudeClient wire format tests

Tests cover all Anthropic-specific format conversions:
- system prompt lifted to top-level field
- tools use input_schema (not parameters)
- tool_choice is object {type:auto} not string
- assistant tool calls → content[{type:tool_use}]
- consecutive tool results merged into single user turn
- parseMCPResponseFull: text, tool_use, and error cases
- x-api-key header (not Authorization: Bearer)
- /messages endpoint URL

* fix(telegram): clientForProvider returns correct client for all 7 providers

Previously qwen/kimi/grok/gemini all fell back to DeepSeekClient.
Each provider now gets its own dedicated client with correct default
base URL and model. All 7 providers now fully supported:
openai, deepseek, claude, qwen, kimi, grok, gemini

* fix(telegram): newLLMClient uses bound user's model, not any user's model

GetAnyEnabled() searched across all users in DB — if user B has an
enabled model, bot could use their API key while acting as user A.

Now uses GetDefault(botUserID) which only looks up the bound user's
enabled model, matching the same user scope as all API calls.

* fix(auth): single-user deployment by default, no open registration

Registration logic redesigned:
- Empty DB (first-time setup): registration always open, no config needed
- After first user exists: registration closed by default
- Multi-user opt-in: set REGISTRATION_ENABLED=true + MAX_USERS=N in .env

Config defaults changed:
- RegistrationEnabled: true → false (closed after first user)
- MaxUsers: 10 → 1 (single-user deployment default)

This eliminates the confusion of multiple users appearing in a personal
deployment where Telegram is bound to a single admin account.

* feat(solo): beginner-friendly onboarding — smart setup guide + direct config commands

start.sh:
- Interactive Telegram Bot Token prompt on first run
- Token format validation (must match 12345:ABC... pattern)
- Friendly step-by-step startup instructions after launch

telegram/bot.go:
- /start now shows context-aware setup guide based on actual config state:
  - No AI model → explains how to configure, lists all providers
  - AI model OK but no exchange → guides to configure exchange via chat
  - All configured → full capabilities welcome message
- New: direct setup commands ('配置 deepseek sk-xxx') bypass LLM entirely
  so AI model can be configured even before any model exists (bootstrap fix)
- All messages now in Chinese (匹配用户语言)

telegram/agent/prompt.go:
- Added first-time setup detection section
- Agent told to never ask user to visit web UI — everything via chat

* feat(i18n): bilingual EN/ZH setup guide with language selection

store/telegram_config.go:
- Add Language field to TelegramConfig (persisted in DB)
- Add SetLanguage(lang) and GetLanguage() methods
- Default language: English (en)

telegram/bot.go:
- First /start triggers language selection (1=English, 2=中文)
- /lang command to change language at any time
- awaitingLang state machine handles language choice before any other input
- buildSetupGuide() now fully bilingual (EN/ZH), context-aware:
  Step 1: configure AI model (no model yet)
  Step 2: configure exchange (model OK, no exchange)
  Ready: show full capabilities
- tryHandleSetupCommand() bilingual: 'configure/配置 <provider> <key>'
- helpMessage(lang) fully bilingual
- All error/status messages bilingual

Default: English. isLangDefault() detects whether user has explicitly
chosen a language vs falling back to the 'en' default.

* fix(telegram): use Markdown rendering + simplify language selection condition

- sendMarkdownMsg() helper: sends with ParseMode=Markdown, falls back to plain text
- All formatted messages (langSelectionMsg, buildSetupGuide, helpMessage) now render
  bold text and code blocks correctly in Telegram
- Simplify /start language check: isLangDefault(st) alone is sufficient
  (lang == 'en' && isLangDefault was redundant — GetLanguage returns 'en' when empty)

* fix(start.sh): translate all user-facing text to English

Entire script was in Chinese. Now English-first throughout:
- startup banner, prompts, success/error messages
- setup_telegram(): English instructions and validation messages
- start(): English next-steps after launch
- stop/restart/clean/update/regenerate-keys/show_help: all English

* fix(telegram): remove 'default' user fallback — resolve user dynamically

- botUserID no longer captured once at startup (was 'default' if no user yet)
- resolveBotUser() reads first registered user from DB on demand:
  * called on every /start (handles: registered after bot launch)
  * called before every AI message (handles mid-session registration)
- If no user registered: clear English error 'No account found. Please register on the web UI first'
- start.sh: fix set_env_var appending without newline (token was concatenated to prev line)

* refactor(telegram): clean onboarding — web UI for setup, Telegram for operations

- /start shows clean status: 'setup required → open web UI' or 'ready → examples'
- Removed tryHandleSetupCommand (no more CLI-style 'configure deepseek sk-xxx')
- Removed automatic language selection on /start (use /lang anytime instead)
- newLLMClient returns nil when no model → clear guard, not fallback
- statusMsg() replaces buildSetupGuide(): two states only (missing config / ready)
- Bot is now purely an operations interface; config lives in the web UI

* refactor: single-user web-based setup — replace env config with Settings UI

Move from multi-user env-var config to single-user web-first architecture:
- Add SetupPage for first-time initialization (replaces /register)
- Add SettingsPage for AI models, exchanges, Telegram, and password management
- Enrich all API route schemas with exact ID usage documentation
- Add PUT /user/password endpoint for in-app password changes
- Remove REGISTRATION_ENABLED, MAX_USERS, TELEGRAM_BOT_TOKEN from env config
- Simplify LoginPage design, remove admin mode and registration links
- Telegram bot now resolves user email for identity display
- start.sh no longer runs interactive Telegram setup

* feat: add blockRun (x402 USDC) support to all AI model consumers

- telegram/bot.go: add blockrun-base, blockrun-sol, minimax to
  clientForProvider; fix newLLMClient to prefer TelegramConfig.ModelID
  over GetDefault; log USDC payment provider usage
- debate/engine.go: add blockrun-base, blockrun-sol to InitializeClients
- api/strategy.go: add blockrun-base, blockrun-sol to runRealAITest
- backtest/ai_client.go: add blockrun-base, blockrun-sol to configureMCPClient

* feat: add Claw402 (claw402.ai) x402 USDC payment provider

Add Claw402Client for claw402.ai's x402 micropayment gateway (Base USDC).
Supports 15+ AI models (GPT-5.4, Claude Opus, DeepSeek, Qwen, Grok, etc.)
with per-model endpoint routing.

- mcp/claw402.go: new client with model→endpoint mapping, x402 v2 payment flow
- mcp/blockrun_base.go: extract shared signX402Payment() for reuse
- Register "claw402" provider in all 6 consumer switch statements:
  api/server.go, api/strategy.go, trader/auto_trader.go,
  telegram/bot.go, debate/engine.go, backtest/ai_client.go

* feat: redesign Claw402 model config UI — friendly wallet setup, USDC guide, official logo, nginx no-cache for index.html

* refactor: centralize x402 payment flow into shared mcp/x402.go

Extract duplicated doRequestWithPayment/call/CallWithRequestFull/buildRequest/
setAuthHeader (~165 lines x3) into shared helpers in mcp/x402.go. Consolidate
shared types (x402v2PaymentRequired, x402AcceptOption, x402Resource) and remove
duplicate Solana types. Fix validAfter to 0 (official SDK standard), drain 402
body before retry, log Payment-Response tx hash, check Payment-Required before
X-Payment-Required.

* fix: stop PR template bot from overwriting user-written descriptions

The pr-template-suggester workflow was triggered on opened/edited/synchronize
events and forcefully replaced the PR body with a template when body < 100 chars.
This caused user-written descriptions to be overwritten.

Replace with a lightweight labeler (OpenClaw-style) that:
- Only adds labels (backend/frontend/docs, size: XS/S/M/L/XL)
- Never modifies the PR body
- Simplified unified PR template at .github/pull_request_template.md

* chore: simplify PR template (OpenClaw-style)
2026-03-11 16:01:42 +08:00
ximi 8406f2f998 feat: add MiniMax provider support (#1406)
Add MiniMax as a new AI model provider with OpenAI-compatible API.

Supported models:
- MiniMax-M2.5 (default) - Peak Performance, Ultimate Value
- MiniMax-M2.5-highspeed - Same performance, faster and more agile

Changes:
- Add MiniMax client (mcp/minimax_client.go) with OpenAI-compatible API
- Add comprehensive unit tests (mcp/minimax_client_test.go)
- Add WithMiniMaxConfig option (mcp/options.go)
- Register MiniMax provider in trader, debate engine, backtest, and API
- Add MiniMax to frontend provider config and model icons
- Add MiniMax SVG icon

API Base URL: https://api.minimax.io/v1
2026-03-09 23:18:51 +08:00
tinkle-community 0275e23b7e feat: unify NofxOS data provider and fix language consistency
- Add unified NofxOS API key configuration in IndicatorEditor
- Add language field to StrategyConfig for consistent prompt generation
- Auto-update prompt sections when interface language changes
- Remove scattered URL inputs from CoinSourceEditor and IndicatorEditor
- Create nofxos provider package with formatted data output
- Update kernel engine to use config-based language setting
2026-01-04 00:59:07 +08:00
tinkle-community 13fda47151 refactor: rename decision package to kernel 2026-01-03 14:25:40 +08:00
tinkle-community 7f7c4ea2a7 fix: sanitize API error messages to prevent sensitive info exposure 2026-01-03 13:11:15 +08:00
tinkle-community 09117bb404 feat: add strategy market, login overlay, and registration limit page
- Add public strategy market API endpoint (/api/strategies/public)
- Add is_public and config_visible fields to Strategy model
- Add LoginRequiredOverlay component for unified auth prompts
- Add WhitelistFullPage for registration capacity limit
- Add StrategyMarketPage for browsing public strategies
- Unify navigation logic across HeaderBar, LandingPage, App
- Reduce klines API calls (fetch once on mount)
- Fix various page transition issues
2026-01-01 23:05:58 +08:00
tinkle-community 2d272bb7b8 feat: migrate store layer to GORM with PostgreSQL support
- Migrate all store packages from raw database/sql to GORM ORM
- Add PostgreSQL support alongside SQLite
- Move EncryptedString type to crypto package for cleaner architecture
- Add automatic encryption/decryption for sensitive fields (API keys, secrets)
- Fix PostgreSQL AutoMigrate conflicts by skipping existing tables
- Fix duplicate /klines route registration
- Update tests to use GORM database connections
- Add database configuration support in config package
2026-01-01 19:32:49 +08:00
tinkle-community cc390706d0 feat: add OI ranking data support and fix trader config update issues
- Add OI ranking data fetching and formatting for AI prompts
- Fix trader update not saving strategy_id, ai_model_id, initial_balance
- Fix AI API key not set for non-qwen/deepseek providers
- Add strategy_id to trader config API response
- Remove old trader from memory before reloading on update
- Clean up unused useTraderActions.ts
2025-12-12 16:08:21 +08:00
tinkle-community e5703ffab6 feat: add Grok, OpenAI, Claude, Gemini, Kimi AI providers
- Add new MCP clients for Grok (xAI), OpenAI, Claude, Gemini, Kimi
- Update auto_trader, backtest, and strategy to support all providers
- Add provider icons and fix SVG gradient conflicts
- Add API application links and hints in model config modal
- Show model version in AI model list cards
- Add Chinese/English translations for provider hints
- Remove deprecated traders component files
2025-12-11 15:16:59 +08:00
tinkle-community 319ccb8ca3 fix: initial balance calculation and UI improvements
- Fix initial balance using available_balance instead of total_equity
- Fix WSMonitor nil pointer by starting market monitor before loading traders
- Add strategy name display on traders list and dashboard pages
- Various position sync and trading improvements
2025-12-10 14:40:08 +08:00
tinkle-community 9c1a322901 fix: OI Top API response parsing and quant data URL validation
- Fix OITopAPIResponse struct to use Code int (0=success) instead of Success bool
- Add all response fields from actual API (time_range_param, rank_type, limit)
- Add {symbol} placeholder validation warning in FetchQuantData
- Add API-level validation in strategy create/update to warn about missing {symbol}
2025-12-08 12:49:49 +08:00
tinkle-community 4a0f56f1ee refactor: remove database pre-population and add i18n strategy templates
- Remove initDefaultData() for exchanges, ai_models, strategies tables
- Change supported exchanges/models API to return static lists
- Add GetDefaultStrategyConfig(lang) with Chinese/English prompt templates
- Frontend passes language parameter when creating new strategy
2025-12-08 02:37:29 +08:00
tinkle-community a12c0ae8c9 refactor: standardize code comments 2025-12-08 01:43:22 +08:00
tinkle-community 5cff32e4f2 Feature/custom strategy (#1172)
* feat: add Strategy Studio with multi-timeframe support
- Add Strategy Studio page with three-column layout for strategy management
- Support multi-timeframe K-line data selection (5m, 15m, 1h, 4h, etc.)
- Add GetWithTimeframes() function in market package for fetching multiple timeframes
- Add TimeframeSeriesData struct for storing per-timeframe technical indicators
- Update formatMarketData() to display all selected timeframes in AI prompt
- Add strategy API endpoints for CRUD operations and test run
- Integrate real AI test runs with configured AI models
- Support custom AI500 and OI Top API URLs from strategy config
* docs: add Strategy Studio screenshot to README files
* fix: correct strategy-studio.png filename case in README
* refactor: remove legacy signal source config and simplify trader creation
- Remove signal source configuration from traders page (now handled by strategy)
- Remove advanced options (legacy config) from TraderConfigModal
- Rename default strategy to "默认山寨策略" with AI500 coin pool URL
- Delete SignalSourceModal and SignalSourceWarning components
- Clean up related stores, hooks, and page components
2025-12-06 07:20:11 +08:00