diff --git a/README.md b/README.md index 313dd21f..eb9e3ad9 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,20 @@ Open **http://127.0.0.1:3000**. Done. --- +## Quick Demo + +
+
+
+
+
+ Click the cover image to watch the demo video. +
+ +--- + ## How x402 Works Traditional flow: register account → buy credits → get API key → manage quota → rotate keys. @@ -59,22 +73,22 @@ No accounts. No API keys. No prepaid credits. One wallet, every model. ### Built-in x402 Providers -| Provider | Chain | Models | -|:---------|:------|:-------| -|
|
|
+
|
|
-| Trading Stats | Position History |
-|:---:|:---:|
+| Trading Stats | Position History |
+| :--------------------------------------------------------------: | :-----------------------------------------------------------------: |
|
|
|
-| Positions | Trader Details |
-|:---:|:---:|
+| Positions | Trader Details |
+| :----------------------------------------------------------: | :---------------------------------------------------: |
|
|
|
+
|
|
+
|
+
+
+
+
+
+ カバー画像をクリックするとデモ動画を視聴できます。 +
+ +--- + ## x402 の仕組み 従来のフロー:アカウント登録 → クレジット購入 → API キー取得 → クォータ管理 → キーのローテーション。 diff --git a/docs/i18n/ko/README.md b/docs/i18n/ko/README.md index 41b30697..e2833e2c 100644 --- a/docs/i18n/ko/README.md +++ b/docs/i18n/ko/README.md @@ -45,6 +45,20 @@ curl -fsSL https://raw.githubusercontent.com/NoFxAiOS/nofx/main/install.sh | bas --- +## 빠른 데모 + +
+
+
+
+
+ 커버 이미지를 클릭하면 데모 영상을 볼 수 있습니다. +
+ +--- + ## x402 작동 방식 기존 플로우: 계정 등록 → 크레딧 구매 → API 키 받기 → 쿼터 관리 → 키 교체. diff --git a/docs/i18n/ru/README.md b/docs/i18n/ru/README.md index bded307f..cc27a119 100644 --- a/docs/i18n/ru/README.md +++ b/docs/i18n/ru/README.md @@ -45,6 +45,20 @@ curl -fsSL https://raw.githubusercontent.com/NoFxAiOS/nofx/main/install.sh | bas --- +## Быстрое демо + +
+
+
+
+
+ Нажмите на изображение обложки, чтобы посмотреть демо-видео. +
+ +--- + ## Как работает x402 Традиционный процесс: регистрация → покупка кредитов → получение API ключа → управление квотой → ротация ключей. diff --git a/docs/i18n/uk/README.md b/docs/i18n/uk/README.md index 30a8b2ce..2605ff82 100644 --- a/docs/i18n/uk/README.md +++ b/docs/i18n/uk/README.md @@ -45,6 +45,20 @@ curl -fsSL https://raw.githubusercontent.com/NoFxAiOS/nofx/main/install.sh | bas --- +## Швидке демо + +
+
+
+
+
+ Натисніть на зображення обкладинки, щоб переглянути демо-відео. +
+ +--- + ## Як працює x402 Традиційний процес: реєстрація → купівля кредитів → отримання API ключа → управління квотою → ротація ключів. diff --git a/docs/i18n/vi/README.md b/docs/i18n/vi/README.md index e91e4679..ccb711f0 100644 --- a/docs/i18n/vi/README.md +++ b/docs/i18n/vi/README.md @@ -45,6 +45,20 @@ Mở **http://127.0.0.1:3000**. Xong. --- +## Demo nhanh + +
+
+
+
+
+ Nhấp vào ảnh bìa để xem video demo. +
+ +--- + ## x402 hoạt động như thế nào Quy trình truyền thống: đăng ký tài khoản → mua credits → lấy API key → quản lý quota → xoay key. diff --git a/docs/i18n/zh-CN/README.md b/docs/i18n/zh-CN/README.md index eb224beb..48560f2e 100644 --- a/docs/i18n/zh-CN/README.md +++ b/docs/i18n/zh-CN/README.md @@ -47,6 +47,20 @@ curl -fsSL https://raw.githubusercontent.com/NoFxAiOS/nofx/main/install.sh | bas --- +## 快速演示 + +
+
+
+
+
+ 点击封面图即可观看 Demo 视频。 +
+ +--- + ## x402 如何工作 传统流程:注册账号 → 购买额度 → 获取 API Key → 管理配额 → 轮换密钥。 diff --git a/main.go b/main.go index f3e0e4d5..351fcce3 100644 --- a/main.go +++ b/main.go @@ -168,7 +168,7 @@ func main() { } logger.Info("✅ HTTP server stopped") - logger.Info("✅ NOFXi agent stopped") + // nofxiAgent.Stop() is handled by defer above // Stop all traders traderManager.StopAll() diff --git a/mcp/payment/claw402.go b/mcp/payment/claw402.go index f28ca1ca..38edbb6b 100644 --- a/mcp/payment/claw402.go +++ b/mcp/payment/claw402.go @@ -50,7 +50,7 @@ func shortAddr(addr string) string { const ( DefaultClaw402URL = "https://claw402.ai" - DefaultClaw402Model = "glm-5" + DefaultClaw402Model = "deepseek-v4-flash" ) // claw402ModelEndpoints maps user-friendly model names to claw402 API paths. @@ -65,6 +65,8 @@ var claw402ModelEndpoints = map[string]string{ // DeepSeek "deepseek": "/api/v1/ai/deepseek/chat", "deepseek-reasoner": "/api/v1/ai/deepseek/chat/reasoner", + "deepseek-v4-flash": "/api/v1/ai/deepseek/v4-flash", + "deepseek-v4-pro": "/api/v1/ai/deepseek/v4-pro", // Qwen "qwen-max": "/api/v1/ai/qwen/chat/max", "qwen-plus": "/api/v1/ai/qwen/chat/plus", @@ -223,18 +225,34 @@ func (c *Claw402Client) signPayment(paymentHeaderB64 string) (string, error) { // ── Format overrides for Anthropic endpoints ───────────────────────────────── +// stripMaxTokens removes per-call max_tokens caps from a body destined for +// claw402. The gateway already enforces a per-route default/floor/cap +// (see providers/*.yaml token_default_max_out / token_min_max_out / +// token_max_out_cap). Sending a small max_tokens here on a thinking model +// (Kimi K2.5, DeepSeek R1/V4) caused reasoning tokens to consume the entire +// budget and left `delta.content` empty, surfacing as "no content received". +// upto settles on real usage, so removing the cap costs nothing extra. +func stripMaxTokens(body map[string]any) map[string]any { + if body == nil { + return body + } + delete(body, "max_tokens") + delete(body, "max_completion_tokens") + return body +} + func (c *Claw402Client) BuildMCPRequestBody(systemPrompt, userPrompt string) map[string]any { if c.claudeProxy != nil { return c.claudeProxy.BuildMCPRequestBody(systemPrompt, userPrompt) } - return c.Client.BuildMCPRequestBody(systemPrompt, userPrompt) + return stripMaxTokens(c.Client.BuildMCPRequestBody(systemPrompt, userPrompt)) } func (c *Claw402Client) BuildRequestBodyFromRequest(req *mcp.Request) map[string]any { if c.claudeProxy != nil { return c.claudeProxy.BuildRequestBodyFromRequest(req) } - return c.Client.BuildRequestBodyFromRequest(req) + return stripMaxTokens(c.Client.BuildRequestBodyFromRequest(req)) } func (c *Claw402Client) ParseMCPResponse(body []byte) (string, error) { diff --git a/screenshots/demo-cover.png b/screenshots/demo-cover.png new file mode 100644 index 00000000..11ba7b8b Binary files /dev/null and b/screenshots/demo-cover.png differ diff --git a/store/ai_charge.go b/store/ai_charge.go index 99ff6301..340009e8 100644 --- a/store/ai_charge.go +++ b/store/ai_charge.go @@ -22,18 +22,20 @@ func (AICharge) TableName() string { return "ai_charges" } var modelPrices = map[string]float64{ "deepseek": 0.003, "deepseek-reasoner": 0.005, + "deepseek-v4-flash": 0.003, + "deepseek-v4-pro": 0.01, "gpt-5.4": 0.05, "gpt-5.4-pro": 0.50, "gpt-5.3": 0.01, "gpt-5-mini": 0.005, - "claude-opus": 0.12, - "qwen-max": 0.01, - "qwen-plus": 0.005, - "qwen-turbo": 0.002, - "qwen-flash": 0.002, - "grok-4.1": 0.06, - "gemini-3.1-pro": 0.03, - "kimi-k2.5": 0.008, + "claude-opus": 0.12, + "qwen-max": 0.01, + "qwen-plus": 0.005, + "qwen-turbo": 0.002, + "qwen-flash": 0.002, + "grok-4.1": 0.06, + "gemini-3.1-pro": 0.03, + "kimi-k2.5": 0.008, } // GetModelPrice returns the price per call for a given model diff --git a/store/ai_model.go b/store/ai_model.go index f991d540..15270a47 100644 --- a/store/ai_model.go +++ b/store/ai_model.go @@ -147,7 +147,7 @@ func (s *AIModelStore) GetDefault(userID string) (*AIModel, error) { func (s *AIModelStore) firstEnabledUsable(userID string) (*AIModel, error) { var models []AIModel - err := s.db.Where("user_id = ? AND enabled = ?", userID, true). + err := s.db.Where("user_id = ? AND enabled = ? AND api_key != ''", userID, true). Order("updated_at DESC, id ASC"). Find(&models).Error if err != nil { diff --git a/web/src/components/trader/model-constants.ts b/web/src/components/trader/model-constants.ts index 75c15414..9e0978e5 100644 --- a/web/src/components/trader/model-constants.ts +++ b/web/src/components/trader/model-constants.ts @@ -7,6 +7,7 @@ export interface Claw402Model { desc: string icon: string price: number // USD per call + isNew?: boolean } export interface AIProviderConfig { @@ -41,8 +42,12 @@ export function getShortName(fullName: string): string { return parts.length > 1 ? parts[parts.length - 1] : fullName } +export const DEFAULT_CLAW402_MODEL = 'deepseek-v4-flash' + // Models available through Claw402 (x402 USDC payment protocol) export const CLAW402_MODELS: Claw402Model[] = [ + { id: 'deepseek-v4-flash', name: 'DeepSeek V4 Flash', provider: 'DeepSeek', desc: '$0.003/call', icon: '⚡', price: 0.003, isNew: true }, + { id: 'deepseek-v4-pro', name: 'DeepSeek V4 Pro', provider: 'DeepSeek', desc: '$0.01/call', icon: '🧠', price: 0.01, isNew: true }, { id: 'deepseek', name: 'DeepSeek V3', provider: 'DeepSeek', desc: '$0.003/call', icon: '🔥', price: 0.003 }, { id: 'deepseek-reasoner', name: 'DeepSeek R1', provider: 'DeepSeek', desc: '$0.005/call', icon: '🤔', price: 0.005 }, { id: 'gpt-5-mini', name: 'GPT-5 Mini', provider: 'OpenAI', desc: '$0.005/call', icon: '🚀', price: 0.005 }, @@ -125,7 +130,7 @@ export const AI_PROVIDER_CONFIG: Record