erlangshen 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/agents/equity-agent.md +26 -0
- package/.claude/agents/macro-agent.md +25 -0
- package/.claude/commands/analyze.md +40 -0
- package/.claude/commands/macro.md +29 -0
- package/.claude/settings.json +12 -0
- package/CODEX_GOAL.md +46 -0
- package/README.md +206 -0
- package/bin/cli.js +67 -0
- package/bin/erlangshen +2 -0
- package/bin/xiaoergod +2 -0
- package/frontend/index.html +700 -0
- package/knowledge/crypto_guide.md +147 -0
- package/knowledge/economic_indicators.md +125 -0
- package/knowledge/financial_glossary.md +148 -0
- package/knowledge/first_principles.md +50 -0
- package/knowledge/first_principles_deep.md +115 -0
- package/knowledge/global_markets.md +173 -0
- package/knowledge/insights.md +141 -0
- package/knowledge/market_basics.md +116 -0
- package/knowledge/memos/session_20260513_003616.json +6 -0
- package/knowledge/memos/session_20260513_003822.json +6 -0
- package/knowledge/risk_management.md +151 -0
- package/knowledge/team_context.md +42 -0
- package/knowledge/trading_strategies.md +114 -0
- package/package.json +42 -0
- package/requirements.txt +14 -0
- package/scripts/postinstall.js +188 -0
- package/scripts/preuninstall.js +22 -0
- package/src/__init__.py +4 -0
- package/src/__pycache__/__init__.cpython-313.pyc +0 -0
- package/src/agents/__init__.py +3 -0
- package/src/agents/base.py +103 -0
- package/src/agents/base_agent.py +86 -0
- package/src/agents/equity.py +136 -0
- package/src/agents/equity_agent.py +91 -0
- package/src/agents/erlang.py +165 -0
- package/src/agents/macro.py +137 -0
- package/src/agents/macro_agent.py +81 -0
- package/src/agents/multi_asset.py +147 -0
- package/src/agents/multi_asset_agent.py +87 -0
- package/src/api/__init__.py +1 -0
- package/src/api/__pycache__/__init__.cpython-313.pyc +0 -0
- package/src/api/__pycache__/server.cpython-313.pyc +0 -0
- package/src/api/cli.py +435 -0
- package/src/api/cli_enhanced.py +537 -0
- package/src/api/server.py +266 -0
- package/src/brain.py +200 -0
- package/src/cli.py +153 -0
- package/src/commands/__init__.py +3 -0
- package/src/commands/analyze.py +131 -0
- package/src/commands/macro.py +100 -0
- package/src/commands/memo.py +216 -0
- package/src/commands/portfolio.py +154 -0
- package/src/commands/report.py +228 -0
- package/src/commands/risk.py +183 -0
- package/src/commands/search.py +183 -0
- package/src/commands/stock.py +124 -0
- package/src/config.py +327 -0
- package/src/core/__init__.py +1 -0
- package/src/core/brain.py +645 -0
- package/src/core/cerebellum.py +175 -0
- package/src/core/investment_universe.py +423 -0
- package/src/core/knowledge.py +207 -0
- package/src/core/memory.py +115 -0
- package/src/hooks/__init__.py +3 -0
- package/src/hooks/session_end.py +57 -0
- package/src/hooks/session_start.py +75 -0
- package/src/knowledge/__init__.py +1 -0
- package/src/mcp/__init__.py +3 -0
- package/src/mcp/feishu.py +331 -0
- package/src/mcp/fund_tools.py +323 -0
- package/src/mcp/macro.py +452 -0
- package/src/mcp/market.py +331 -0
- package/src/mcp/registry.py +168 -0
- package/src/network/__init__.py +15 -0
- package/src/network/detector.py +125 -0
- package/src/network/proxy.py +199 -0
- package/src/network/router.py +103 -0
- package/src/prompts/__init__.py +1 -0
- package/src/prompts/analysis_framework.md +164 -0
- package/src/prompts/persona.md +65 -0
- package/src/prompts/report_template.md +144 -0
- package/src/skills/__init__.py +3 -0
- package/src/skills/framework.py +105 -0
- package/src/skills/templates.py +342 -0
- package/src/tools/__init__.py +1 -0
- package/src/tools/file_tools.py +209 -0
- package/src/tools/macro_tools.py +152 -0
- package/src/tools/market_tools.py +1172 -0
- package/src/tools/registry.py +398 -0
- package/src/tools/search_tools.py +777 -0
- package/tests/__init__.py +1 -0
- package/tests/test_erlangshen.py +140 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Tests"""
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
"""
|
|
2
|
+
测试套件 - 二郎神核心功能测试
|
|
3
|
+
"""
|
|
4
|
+
import pytest
|
|
5
|
+
import asyncio
|
|
6
|
+
import sys
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
|
|
9
|
+
sys.path.insert(0, str(Path(__file__).parent.parent / "src"))
|
|
10
|
+
|
|
11
|
+
from src.core.brain import Brain
|
|
12
|
+
from src.core.memory import Memory
|
|
13
|
+
from src.core.knowledge import KnowledgeBase
|
|
14
|
+
from src.core.cerebellum import Cerebellum
|
|
15
|
+
from src.tools.market_tools import MarketTools
|
|
16
|
+
from src.tools.macro_tools import MacroTools
|
|
17
|
+
from src.tools.search_tools import SearchTools
|
|
18
|
+
from src.agents.erlang import 二郎神 as Erlangshen
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@pytest.fixture
|
|
22
|
+
def brain():
|
|
23
|
+
return Brain()
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@pytest.fixture
|
|
27
|
+
def memory():
|
|
28
|
+
return Memory()
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@pytest.fixture
|
|
32
|
+
def knowledge(tmp_path):
|
|
33
|
+
return KnowledgeBase(base_path=str(tmp_path))
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@pytest.fixture
|
|
37
|
+
def erlangshen(brain, memory, knowledge):
|
|
38
|
+
tools = {
|
|
39
|
+
"market_tools": MarketTools(),
|
|
40
|
+
"macro_tools": MacroTools(),
|
|
41
|
+
"search_tools": SearchTools(),
|
|
42
|
+
}
|
|
43
|
+
return Erlangshen(brain=brain, memory=memory, knowledge=knowledge, tools=tools)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class TestBrain:
|
|
47
|
+
def test_brain_init(self, brain):
|
|
48
|
+
assert brain.model is not None
|
|
49
|
+
assert brain.api_base is not None
|
|
50
|
+
|
|
51
|
+
@pytest.mark.asyncio
|
|
52
|
+
async def test_think(self, brain):
|
|
53
|
+
result = await brain.think("你好,请用一句话介绍自己")
|
|
54
|
+
assert isinstance(result, str)
|
|
55
|
+
assert len(result) > 0
|
|
56
|
+
|
|
57
|
+
@pytest.mark.asyncio
|
|
58
|
+
async def test_analyze(self, brain):
|
|
59
|
+
result = await brain.analyze("分析当前全球经济形势")
|
|
60
|
+
assert result.conclusion is not None
|
|
61
|
+
assert 0 <= result.confidence <= 1
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class TestMemory:
|
|
65
|
+
@pytest.mark.asyncio
|
|
66
|
+
async def test_add_message(self, memory):
|
|
67
|
+
await memory.add_message("user", "Hello")
|
|
68
|
+
context = await memory.get_context()
|
|
69
|
+
assert len(context) == 1
|
|
70
|
+
assert context[0].content == "Hello"
|
|
71
|
+
|
|
72
|
+
@pytest.mark.asyncio
|
|
73
|
+
async def test_add_interaction(self, memory):
|
|
74
|
+
await memory.add_interaction("Query", "Response")
|
|
75
|
+
events = await memory.get_recent_events(hours=1)
|
|
76
|
+
assert len(events) >= 1
|
|
77
|
+
|
|
78
|
+
@pytest.mark.asyncio
|
|
79
|
+
async def test_register_skill(self, memory):
|
|
80
|
+
async def dummy_skill():
|
|
81
|
+
return "done"
|
|
82
|
+
memory.register_skill("dummy", dummy_skill)
|
|
83
|
+
skill = memory.get_skill("dummy")
|
|
84
|
+
assert skill is not None
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
class TestKnowledgeBase:
|
|
88
|
+
@pytest.mark.asyncio
|
|
89
|
+
async def test_add_entry(self, knowledge):
|
|
90
|
+
entry = knowledge.add("Test knowledge", category="test")
|
|
91
|
+
assert entry.entry_id is not None
|
|
92
|
+
assert entry.content == "Test knowledge"
|
|
93
|
+
|
|
94
|
+
@pytest.mark.asyncio
|
|
95
|
+
async def test_search(self, knowledge):
|
|
96
|
+
knowledge.add("茅台是高端白酒", category="stock")
|
|
97
|
+
results = await knowledge.search("茅台", top_k=5)
|
|
98
|
+
assert len(results) >= 1
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
class TestMarketTools:
|
|
102
|
+
@pytest.mark.asyncio
|
|
103
|
+
async def test_get_stock_price(self):
|
|
104
|
+
tools = MarketTools()
|
|
105
|
+
result = await tools.get_stock_price("600519")
|
|
106
|
+
assert "symbol" in result
|
|
107
|
+
assert result["symbol"] == "600519"
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
class TestMacroTools:
|
|
111
|
+
@pytest.mark.asyncio
|
|
112
|
+
async def test_get_interest_rates(self):
|
|
113
|
+
tools = MacroTools()
|
|
114
|
+
result = await tools.get_interest_rates("CN")
|
|
115
|
+
assert "rates" in result
|
|
116
|
+
assert "CN" in result["country"]
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
class TestErlangshen:
|
|
120
|
+
@pytest.mark.asyncio
|
|
121
|
+
async def test_classify_query(self, erlangshen):
|
|
122
|
+
assert erlangshen._classify_query("分析茅台股票") == "equity"
|
|
123
|
+
assert erlangshen._classify_query("分析宏观经济") == "macro"
|
|
124
|
+
assert erlangshen._classify_query("资产配置建议") == "multi_asset"
|
|
125
|
+
|
|
126
|
+
@pytest.mark.asyncio
|
|
127
|
+
async def test_process(self, erlangshen):
|
|
128
|
+
result = await erlangshen.process("分析当前A股市场")
|
|
129
|
+
assert "query" in result
|
|
130
|
+
assert "erlangshen_insight" in result
|
|
131
|
+
|
|
132
|
+
@pytest.mark.asyncio
|
|
133
|
+
async def test_analyze_stock(self, erlangshen):
|
|
134
|
+
result = await erlangshen.analyze_stock("600519")
|
|
135
|
+
assert "query" in result
|
|
136
|
+
assert result["symbol"] == "600519"
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
if __name__ == "__main__":
|
|
140
|
+
pytest.main([__file__, "-v"])
|