Compare commits
1 Commits
fix/crypto
...
4cc0d982d6
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4cc0d982d6 |
@@ -32,7 +32,7 @@ MINIMAX_API_KEY=your-minimax-api-key
|
|||||||
|
|
||||||
# MiniMax model to use
|
# MiniMax model to use
|
||||||
# Common options: MiniMax-Text-01, MiniMax-M2.1
|
# Common options: MiniMax-Text-01, MiniMax-M2.1
|
||||||
MINIMAX_MODEL=MiniMax-M2.7
|
MINIMAX_MODEL=MiniMax-Text-01
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# AVE CLOUD API
|
# AVE CLOUD API
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ def get_current_user(
|
|||||||
|
|
||||||
|
|
||||||
@router.post(
|
@router.post(
|
||||||
"/register", response_model=Token, status_code=status.HTTP_201_CREATED
|
"/register", response_model=UserResponse, status_code=status.HTTP_201_CREATED
|
||||||
)
|
)
|
||||||
def register(user: UserCreate, db: Session = Depends(get_db)):
|
def register(user: UserCreate, db: Session = Depends(get_db)):
|
||||||
existing_user = db.query(User).filter(User.email == user.email).first()
|
existing_user = db.query(User).filter(User.email == user.email).first()
|
||||||
@@ -75,10 +75,7 @@ def register(user: UserCreate, db: Session = Depends(get_db)):
|
|||||||
db.add(db_user)
|
db.add(db_user)
|
||||||
db.commit()
|
db.commit()
|
||||||
db.refresh(db_user)
|
db.refresh(db_user)
|
||||||
|
return db_user
|
||||||
# Generate and return access token so frontend can proceed immediately
|
|
||||||
access_token = create_access_token(data={"sub": db_user.id})
|
|
||||||
return Token(access_token=access_token, token_type="bearer")
|
|
||||||
|
|
||||||
|
|
||||||
@router.post("/login", response_model=Token)
|
@router.post("/login", response_model=Token)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
from typing import List, Optional, Dict, Any
|
from typing import List, Optional, Dict, Any
|
||||||
from crewai import Agent, Task, Crew, LLM
|
from crewai import Agent, Task, Crew
|
||||||
from .llm_connector import MiniMaxConnector
|
from .llm_connector import MiniMaxConnector, MiniMaxLLM
|
||||||
from ...core.config import get_settings
|
from ...core.config import get_settings
|
||||||
|
|
||||||
|
|
||||||
@@ -120,7 +120,7 @@ class StrategyExplainer:
|
|||||||
|
|
||||||
|
|
||||||
def create_trading_designer_agent(
|
def create_trading_designer_agent(
|
||||||
api_key: str, model: str = "MiniMax-M2.7"
|
api_key: str, model: str = "MiniMax-Text-01"
|
||||||
) -> Agent:
|
) -> Agent:
|
||||||
connector = MiniMaxConnector(api_key=api_key, model=model)
|
connector = MiniMaxConnector(api_key=api_key, model=model)
|
||||||
|
|
||||||
@@ -141,13 +141,13 @@ def create_trading_designer_agent(
|
|||||||
role="Trading Strategy Designer",
|
role="Trading Strategy Designer",
|
||||||
goal="Convert natural language trading requests into precise strategy configurations",
|
goal="Convert natural language trading requests into precise strategy configurations",
|
||||||
backstory=system_prompt,
|
backstory=system_prompt,
|
||||||
llm=LLM(model=model, api_key=api_key, api_base="https://api.minimax.io/v1"),
|
llm=MiniMaxLLM(api_key=api_key, model=model),
|
||||||
verbose=True,
|
verbose=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def create_strategy_validator_agent(
|
def create_strategy_validator_agent(
|
||||||
api_key: str, model: str = "MiniMax-M2.7"
|
api_key: str, model: str = "MiniMax-Text-01"
|
||||||
) -> Agent:
|
) -> Agent:
|
||||||
return Agent(
|
return Agent(
|
||||||
role="Strategy Validator",
|
role="Strategy Validator",
|
||||||
@@ -155,13 +155,13 @@ def create_strategy_validator_agent(
|
|||||||
backstory="""You are a meticulous strategy validator with expertise in trading systems.
|
backstory="""You are a meticulous strategy validator with expertise in trading systems.
|
||||||
You check that all required parameters are present, values are reasonable, and the
|
You check that all required parameters are present, values are reasonable, and the
|
||||||
strategy makes logical sense. You never approve strategies with missing or invalid data.""",
|
strategy makes logical sense. You never approve strategies with missing or invalid data.""",
|
||||||
llm=LLM(model=model, api_key=api_key, api_base="https://api.minimax.io/v1"),
|
llm=MiniMaxLLM(api_key=api_key, model=model),
|
||||||
verbose=True,
|
verbose=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def create_strategy_explainer_agent(
|
def create_strategy_explainer_agent(
|
||||||
api_key: str, model: str = "MiniMax-M2.7"
|
api_key: str, model: str = "MiniMax-Text-01"
|
||||||
) -> Agent:
|
) -> Agent:
|
||||||
return Agent(
|
return Agent(
|
||||||
role="Strategy Explainer",
|
role="Strategy Explainer",
|
||||||
@@ -169,13 +169,13 @@ def create_strategy_explainer_agent(
|
|||||||
backstory="""You are a patient trading strategy explainer. You translate complex
|
backstory="""You are a patient trading strategy explainer. You translate complex
|
||||||
strategy configurations into easy-to-understand language. You help users understand
|
strategy configurations into easy-to-understand language. You help users understand
|
||||||
exactly what their strategies will do when triggered.""",
|
exactly what their strategies will do when triggered.""",
|
||||||
llm=LLM(model=model, api_key=api_key, api_base="https://api.minimax.io/v1"),
|
llm=MiniMaxLLM(api_key=api_key, model=model),
|
||||||
verbose=True,
|
verbose=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class TradingCrew:
|
class TradingCrew:
|
||||||
def __init__(self, api_key: str, model: str = "MiniMax-M2.7"):
|
def __init__(self, api_key: str, model: str = "MiniMax-Text-01"):
|
||||||
self.api_key = api_key
|
self.api_key = api_key
|
||||||
self.model = model
|
self.model = model
|
||||||
self.validator = StrategyValidator()
|
self.validator = StrategyValidator()
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
from typing import Optional, List, Dict, Any
|
from typing import Optional, List, Dict, Any
|
||||||
import httpx
|
import httpx
|
||||||
|
from crewai import LLM
|
||||||
|
|
||||||
|
|
||||||
class MiniMaxLLM:
|
class MiniMaxLLM(LLM):
|
||||||
def __init__(self, api_key: str, model: str = "MiniMax-M2.7", **kwargs):
|
def __init__(self, api_key: str, model: str = "MiniMax-Text-01", **kwargs):
|
||||||
|
super().__init__(**kwargs)
|
||||||
self.api_key = api_key
|
self.api_key = api_key
|
||||||
self.model = model
|
self.model = model
|
||||||
self.base_url = "https://api.minimax.io/v1"
|
self.base_url = "https://api.minimax.io/v1"
|
||||||
@@ -21,7 +23,7 @@ class MiniMaxLLM:
|
|||||||
}
|
}
|
||||||
with httpx.Client(timeout=60.0) as client:
|
with httpx.Client(timeout=60.0) as client:
|
||||||
response = client.post(
|
response = client.post(
|
||||||
f"{self.base_url}/text/chatcompletion_v2",
|
f"{self.base_url}/chat/completions",
|
||||||
headers=headers,
|
headers=headers,
|
||||||
json=payload,
|
json=payload,
|
||||||
)
|
)
|
||||||
@@ -33,7 +35,7 @@ class MiniMaxLLM:
|
|||||||
|
|
||||||
|
|
||||||
class MiniMaxConnector:
|
class MiniMaxConnector:
|
||||||
def __init__(self, api_key: str, model: str = "MiniMax-M2.7"):
|
def __init__(self, api_key: str, model: str = "MiniMax-Text-01"):
|
||||||
self.api_key = api_key
|
self.api_key = api_key
|
||||||
self.model = model
|
self.model = model
|
||||||
|
|
||||||
|
|||||||
@@ -104,12 +104,11 @@ export const api = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
async chat(id: string, message: string, signal?: AbortSignal): Promise<BotChatResponse> {
|
async chat(id: string, message: string): Promise<BotChatResponse> {
|
||||||
const response = await fetch(`${API_URL}/bots/${id}/chat`, {
|
const response = await fetch(`${API_URL}/bots/${id}/chat`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: getAuthHeaders(),
|
headers: getAuthHeaders(),
|
||||||
body: JSON.stringify({ message } as BotChatRequest),
|
body: JSON.stringify({ message } as BotChatRequest)
|
||||||
signal
|
|
||||||
});
|
});
|
||||||
return handleResponse<BotChatResponse>(response);
|
return handleResponse<BotChatResponse>(response);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -8,25 +8,12 @@ export interface ChatMessage {
|
|||||||
timestamp: Date;
|
timestamp: Date;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fallback UUID generator for environments where crypto.randomUUID is not available
|
|
||||||
function generateId(): string {
|
|
||||||
if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {
|
|
||||||
return crypto.randomUUID();
|
|
||||||
}
|
|
||||||
// Fallback: simple UUID v4 implementation
|
|
||||||
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
|
|
||||||
const r = (Math.random() * 16) | 0;
|
|
||||||
const v = c === 'x' ? r : (r & 0x3) | 0x8;
|
|
||||||
return v.toString(16);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export const chatStore = writable<ChatMessage[]>([]);
|
export const chatStore = writable<ChatMessage[]>([]);
|
||||||
|
|
||||||
export function addMessage(message: Omit<ChatMessage, 'id' | 'timestamp'>) {
|
export function addMessage(message: Omit<ChatMessage, 'id' | 'timestamp'>) {
|
||||||
const newMessage: ChatMessage = {
|
const newMessage: ChatMessage = {
|
||||||
...message,
|
...message,
|
||||||
id: generateId(),
|
id: crypto.randomUUID(),
|
||||||
timestamp: new Date()
|
timestamp: new Date()
|
||||||
};
|
};
|
||||||
chatStore.update(messages => [...messages, newMessage]);
|
chatStore.update(messages => [...messages, newMessage]);
|
||||||
|
|||||||
@@ -44,17 +44,8 @@
|
|||||||
|
|
||||||
isSending = true;
|
isSending = true;
|
||||||
|
|
||||||
// Add user's message immediately so it shows even before API response
|
|
||||||
addMessage({ role: 'user', content: message });
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Add timeout to prevent hanging requests
|
const response = await api.bots.chat(botId, message);
|
||||||
const controller = new AbortController();
|
|
||||||
const timeoutId = setTimeout(() => controller.abort(), 30000);
|
|
||||||
|
|
||||||
const response = await api.bots.chat(botId, message, controller.signal);
|
|
||||||
clearTimeout(timeoutId);
|
|
||||||
|
|
||||||
addMessage({ role: 'assistant', content: response.response });
|
addMessage({ role: 'assistant', content: response.response });
|
||||||
|
|
||||||
if (response.strategy_config) {
|
if (response.strategy_config) {
|
||||||
@@ -62,11 +53,7 @@
|
|||||||
setCurrentBot(bot);
|
setCurrentBot(bot);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e instanceof Error && e.name === 'AbortError') {
|
addMessage({ role: 'assistant', content: 'Sorry, I encountered an error. Please try again.' });
|
||||||
addMessage({ role: 'assistant', content: 'Request timed out. Please try again.' });
|
|
||||||
} else {
|
|
||||||
addMessage({ role: 'assistant', content: 'Sorry, I encountered an error. Please try again.' });
|
|
||||||
}
|
|
||||||
} finally {
|
} finally {
|
||||||
isSending = false;
|
isSending = false;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user