agstack 1.0.0__tar.gz
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.
- agstack-1.0.0/PKG-INFO +238 -0
- agstack-1.0.0/README.md +199 -0
- agstack-1.0.0/agstack/__init__.py +2 -0
- agstack-1.0.0/agstack/config/__init__.py +2 -0
- agstack-1.0.0/agstack/config/logger.py +80 -0
- agstack-1.0.0/agstack/config/manager.py +131 -0
- agstack-1.0.0/agstack/config/types.py +94 -0
- agstack-1.0.0/agstack/decorators.py +65 -0
- agstack-1.0.0/agstack/events.py +91 -0
- agstack-1.0.0/agstack/exceptions.py +57 -0
- agstack-1.0.0/agstack/fastapi/__init__.py +42 -0
- agstack-1.0.0/agstack/fastapi/exception.py +125 -0
- agstack-1.0.0/agstack/fastapi/middleware.py +31 -0
- agstack-1.0.0/agstack/fastapi/offline.py +88 -0
- agstack-1.0.0/agstack/fastapi/sse.py +318 -0
- agstack-1.0.0/agstack/infra/db/__init__.py +33 -0
- agstack-1.0.0/agstack/infra/es/__init__.py +22 -0
- agstack-1.0.0/agstack/infra/mq/__init__.py +102 -0
- agstack-1.0.0/agstack/llm/__init__.py +2 -0
- agstack-1.0.0/agstack/llm/client.py +531 -0
- agstack-1.0.0/agstack/llm/flow/__init__.py +56 -0
- agstack-1.0.0/agstack/llm/flow/agent.py +241 -0
- agstack-1.0.0/agstack/llm/flow/context.py +121 -0
- agstack-1.0.0/agstack/llm/flow/events.py +45 -0
- agstack-1.0.0/agstack/llm/flow/exceptions.py +48 -0
- agstack-1.0.0/agstack/llm/flow/factory.py +61 -0
- agstack-1.0.0/agstack/llm/flow/flow.py +155 -0
- agstack-1.0.0/agstack/llm/flow/loader.py +63 -0
- agstack-1.0.0/agstack/llm/flow/records.py +48 -0
- agstack-1.0.0/agstack/llm/flow/registry.py +81 -0
- agstack-1.0.0/agstack/llm/flow/state.py +44 -0
- agstack-1.0.0/agstack/llm/flow/tool.py +78 -0
- agstack-1.0.0/agstack/llm/prompts.py +18 -0
- agstack-1.0.0/agstack/llm/token.py +18 -0
- agstack-1.0.0/agstack/registry.py +183 -0
- agstack-1.0.0/agstack/schema.py +87 -0
- agstack-1.0.0/agstack/security/__init__.py +2 -0
- agstack-1.0.0/agstack/security/casbin.py +131 -0
- agstack-1.0.0/agstack/security/crypt.py +132 -0
- agstack-1.0.0/agstack/status.py +21 -0
- agstack-1.0.0/agstack.egg-info/PKG-INFO +238 -0
- agstack-1.0.0/agstack.egg-info/SOURCES.txt +45 -0
- agstack-1.0.0/agstack.egg-info/dependency_links.txt +1 -0
- agstack-1.0.0/agstack.egg-info/requires.txt +17 -0
- agstack-1.0.0/agstack.egg-info/top_level.txt +1 -0
- agstack-1.0.0/pyproject.toml +112 -0
- agstack-1.0.0/setup.cfg +4 -0
agstack-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: agstack
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Production-ready toolkit for building FastAPI and LLM applications
|
|
5
|
+
Author-email: XtraVisions <gitadmin@xtravisions.com>, Chen Hao <chenhao@xtravisions.com>
|
|
6
|
+
Maintainer-email: XtraVisions <gitadmin@xtravisions.com>, Chen Hao <chenhao@xtravisions.com>
|
|
7
|
+
License-Expression: MIT
|
|
8
|
+
Keywords: fastapi,llm,agents,ai,infrastructure,framework,casbin,openai,logging,configuration
|
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
|
|
12
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
13
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
14
|
+
Classifier: Framework :: FastAPI
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
18
|
+
Classifier: Operating System :: OS Independent
|
|
19
|
+
Classifier: Typing :: Typed
|
|
20
|
+
Requires-Python: >=3.12
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
Requires-Dist: ag-ui-protocol>=0.1.10
|
|
23
|
+
Requires-Dist: aio-pika>=9.5.8
|
|
24
|
+
Requires-Dist: asyncpg>=0.30.0
|
|
25
|
+
Requires-Dist: elasticsearch[async]>=9.2.1
|
|
26
|
+
Requires-Dist: fastapi>=0.121.3
|
|
27
|
+
Requires-Dist: jwcrypto>=1.5.6
|
|
28
|
+
Requires-Dist: loguru>=0.7.3
|
|
29
|
+
Requires-Dist: openai>=2.16.0
|
|
30
|
+
Requires-Dist: passlib[bcrypt]>=1.7.4
|
|
31
|
+
Requires-Dist: pycasbin>=2.6.0
|
|
32
|
+
Requires-Dist: pydantic>=2.12.4
|
|
33
|
+
Requires-Dist: python-multipart>=0.0.20
|
|
34
|
+
Requires-Dist: requests>=2.32.5
|
|
35
|
+
Requires-Dist: sqlalchemy[asyncio]>=2.0.46
|
|
36
|
+
Requires-Dist: sqlobjects>=1.0.16
|
|
37
|
+
Requires-Dist: tiktoken>=0.12.0
|
|
38
|
+
Requires-Dist: uvicorn>=0.38.0
|
|
39
|
+
|
|
40
|
+
# AgStack
|
|
41
|
+
|
|
42
|
+
> Production-ready toolkit for building FastAPI and LLM applications
|
|
43
|
+
|
|
44
|
+
[](https://www.python.org/downloads/)
|
|
45
|
+
[](LICENSE)
|
|
46
|
+
[](https://github.com/xtravisions/agstack)
|
|
47
|
+
|
|
48
|
+
## 📖 Overview
|
|
49
|
+
|
|
50
|
+
AgStack is a comprehensive Python framework designed for building production-ready FastAPI applications with integrated LLM capabilities. It provides:
|
|
51
|
+
|
|
52
|
+
- 🚀 **FastAPI Integration** - Production-ready web framework setup
|
|
53
|
+
- 🤖 **LLM Flow System** - Orchestrate Agents, Tools, and Flows
|
|
54
|
+
- 📦 **Component Registry** - Unified registration and factory pattern
|
|
55
|
+
- 🔐 **Security** - Built-in authentication and authorization (Casbin)
|
|
56
|
+
- 🗄️ **Infrastructure** - Database, Elasticsearch, and Message Queue support
|
|
57
|
+
- 📊 **Schema System** - Unified Pydantic models with enhanced serialization
|
|
58
|
+
|
|
59
|
+
## 🚀 Quick Start
|
|
60
|
+
|
|
61
|
+
### Installation
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
pip install agstack
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Basic Usage
|
|
68
|
+
|
|
69
|
+
```python
|
|
70
|
+
from agstack.llm.flow import (
|
|
71
|
+
Tool,
|
|
72
|
+
FlowContext,
|
|
73
|
+
registry,
|
|
74
|
+
create_tool
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
# Define a tool
|
|
78
|
+
class MyTool(Tool):
|
|
79
|
+
def __init__(self):
|
|
80
|
+
super().__init__(
|
|
81
|
+
name="my_tool",
|
|
82
|
+
description="My custom tool",
|
|
83
|
+
function=self.execute
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
async def execute(self, context: FlowContext):
|
|
87
|
+
return "Tool result"
|
|
88
|
+
|
|
89
|
+
# Register the tool
|
|
90
|
+
registry.register_tool("my_tool", MyTool)
|
|
91
|
+
|
|
92
|
+
# Use the tool
|
|
93
|
+
context = FlowContext(session_id="test")
|
|
94
|
+
tool = create_tool("my_tool")
|
|
95
|
+
result = await tool.run(context)
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## 📚 Documentation
|
|
99
|
+
|
|
100
|
+
- **[Usage Guide](docs/USAGE_GUIDE.md)** - Learn how to use AgStack in your projects
|
|
101
|
+
- **[Development Rules](docs/DEVELOPMENT_RULES.md)** - Guidelines for contributing to AgStack
|
|
102
|
+
- **API Reference** - Coming soon
|
|
103
|
+
- **Examples** - Coming soon
|
|
104
|
+
|
|
105
|
+
## 🏗️ Architecture
|
|
106
|
+
|
|
107
|
+
### Project Structure
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
agstack/
|
|
111
|
+
├── schema.py # Base Pydantic models
|
|
112
|
+
├── registry.py # Global component registry
|
|
113
|
+
├── exceptions.py # Exception hierarchy
|
|
114
|
+
├── llm/ # LLM and AI features
|
|
115
|
+
│ ├── client.py # LLM client
|
|
116
|
+
│ └── flow/ # Flow execution framework
|
|
117
|
+
│ ├── agent.py # Agent definition
|
|
118
|
+
│ ├── tool.py # Tool definition
|
|
119
|
+
│ ├── flow.py # Flow orchestration
|
|
120
|
+
│ └── ...
|
|
121
|
+
├── fastapi/ # FastAPI integration
|
|
122
|
+
├── infra/ # Infrastructure components
|
|
123
|
+
│ ├── db/ # Database
|
|
124
|
+
│ ├── es/ # Elasticsearch
|
|
125
|
+
│ └── mq/ # Message Queue
|
|
126
|
+
└── security/ # Security features
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Core Concepts
|
|
130
|
+
|
|
131
|
+
- **Agent** - LLM-powered intelligent agents
|
|
132
|
+
- **Tool** - Functions that can be called by agents
|
|
133
|
+
- **Flow** - Orchestration of multiple agents and tools
|
|
134
|
+
- **Registry** - Centralized component management
|
|
135
|
+
- **BaseSchema** - Enhanced Pydantic models with unified configuration
|
|
136
|
+
|
|
137
|
+
## 🛠️ Development
|
|
138
|
+
|
|
139
|
+
### Requirements
|
|
140
|
+
|
|
141
|
+
- Python >= 3.12
|
|
142
|
+
- Dependencies listed in `pyproject.toml`
|
|
143
|
+
|
|
144
|
+
### Setup
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
# Clone the repository
|
|
148
|
+
git clone https://github.com/xtravisions/agstack.git
|
|
149
|
+
cd agstack
|
|
150
|
+
|
|
151
|
+
# Install dependencies
|
|
152
|
+
pip install -e ".[dev]"
|
|
153
|
+
|
|
154
|
+
# Install pre-commit hooks
|
|
155
|
+
pre-commit install
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### Code Quality
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
# Format code
|
|
162
|
+
ruff format .
|
|
163
|
+
|
|
164
|
+
# Lint
|
|
165
|
+
ruff check .
|
|
166
|
+
|
|
167
|
+
# Type check
|
|
168
|
+
pyright
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Contributing
|
|
172
|
+
|
|
173
|
+
Please read [DEVELOPMENT_RULES.md](docs/DEVELOPMENT_RULES.md) for development guidelines and coding standards.
|
|
174
|
+
|
|
175
|
+
## 📦 Features
|
|
176
|
+
|
|
177
|
+
### LLM Flow System
|
|
178
|
+
|
|
179
|
+
- **Agent System** - Create and manage LLM-powered agents
|
|
180
|
+
- **Tool System** - Define reusable tools for agents
|
|
181
|
+
- **Flow Orchestration** - Chain multiple agents and tools
|
|
182
|
+
- **Context Management** - Maintain state across execution
|
|
183
|
+
- **Event System** - AG-UI protocol support
|
|
184
|
+
|
|
185
|
+
### FastAPI Integration
|
|
186
|
+
|
|
187
|
+
- Production-ready setup
|
|
188
|
+
- Middleware support
|
|
189
|
+
- Exception handling
|
|
190
|
+
- Request/Response schemas
|
|
191
|
+
|
|
192
|
+
### Infrastructure
|
|
193
|
+
|
|
194
|
+
- **Database** - PostgreSQL with async support (asyncpg)
|
|
195
|
+
- **Elasticsearch** - Full-text search integration
|
|
196
|
+
- **Message Queue** - Async message processing (aio-pika)
|
|
197
|
+
|
|
198
|
+
### Security
|
|
199
|
+
|
|
200
|
+
- JWT authentication
|
|
201
|
+
- Casbin authorization
|
|
202
|
+
- Password hashing (bcrypt)
|
|
203
|
+
|
|
204
|
+
## 🤝 Contributing
|
|
205
|
+
|
|
206
|
+
We welcome contributions! Please see our [Development Rules](docs/DEVELOPMENT_RULES.md) for guidelines.
|
|
207
|
+
|
|
208
|
+
### Key Guidelines
|
|
209
|
+
|
|
210
|
+
- Use relative imports (not `from agstack...`)
|
|
211
|
+
- Inherit from `BaseSchema` for Pydantic models
|
|
212
|
+
- Use `ruff` and `pyright` for code quality
|
|
213
|
+
- Follow Python 3.12+ standards
|
|
214
|
+
- Write tests for new features
|
|
215
|
+
|
|
216
|
+
## 📄 License
|
|
217
|
+
|
|
218
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
219
|
+
|
|
220
|
+
## 👥 Authors
|
|
221
|
+
|
|
222
|
+
- **XtraVisions** - [gitadmin@xtravisions.com](mailto:gitadmin@xtravisions.com)
|
|
223
|
+
- **Chen Hao** - [chenhao@xtravisions.com](mailto:chenhao@xtravisions.com)
|
|
224
|
+
|
|
225
|
+
## 🔗 Links
|
|
226
|
+
|
|
227
|
+
- **Documentation**: [docs/](docs/)
|
|
228
|
+
- **GitHub**: (TBD)
|
|
229
|
+
- **Issues**: (TBD)
|
|
230
|
+
- **PyPI**: (TBD)
|
|
231
|
+
|
|
232
|
+
## 📝 Changelog
|
|
233
|
+
|
|
234
|
+
See [CHANGELOG.md](CHANGELOG.md) for release history.
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
**Note**: AgStack is under active development. APIs may change before the 1.0 stable release.
|
agstack-1.0.0/README.md
ADDED
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
# AgStack
|
|
2
|
+
|
|
3
|
+
> Production-ready toolkit for building FastAPI and LLM applications
|
|
4
|
+
|
|
5
|
+
[](https://www.python.org/downloads/)
|
|
6
|
+
[](LICENSE)
|
|
7
|
+
[](https://github.com/xtravisions/agstack)
|
|
8
|
+
|
|
9
|
+
## 📖 Overview
|
|
10
|
+
|
|
11
|
+
AgStack is a comprehensive Python framework designed for building production-ready FastAPI applications with integrated LLM capabilities. It provides:
|
|
12
|
+
|
|
13
|
+
- 🚀 **FastAPI Integration** - Production-ready web framework setup
|
|
14
|
+
- 🤖 **LLM Flow System** - Orchestrate Agents, Tools, and Flows
|
|
15
|
+
- 📦 **Component Registry** - Unified registration and factory pattern
|
|
16
|
+
- 🔐 **Security** - Built-in authentication and authorization (Casbin)
|
|
17
|
+
- 🗄️ **Infrastructure** - Database, Elasticsearch, and Message Queue support
|
|
18
|
+
- 📊 **Schema System** - Unified Pydantic models with enhanced serialization
|
|
19
|
+
|
|
20
|
+
## 🚀 Quick Start
|
|
21
|
+
|
|
22
|
+
### Installation
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pip install agstack
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Basic Usage
|
|
29
|
+
|
|
30
|
+
```python
|
|
31
|
+
from agstack.llm.flow import (
|
|
32
|
+
Tool,
|
|
33
|
+
FlowContext,
|
|
34
|
+
registry,
|
|
35
|
+
create_tool
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
# Define a tool
|
|
39
|
+
class MyTool(Tool):
|
|
40
|
+
def __init__(self):
|
|
41
|
+
super().__init__(
|
|
42
|
+
name="my_tool",
|
|
43
|
+
description="My custom tool",
|
|
44
|
+
function=self.execute
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
async def execute(self, context: FlowContext):
|
|
48
|
+
return "Tool result"
|
|
49
|
+
|
|
50
|
+
# Register the tool
|
|
51
|
+
registry.register_tool("my_tool", MyTool)
|
|
52
|
+
|
|
53
|
+
# Use the tool
|
|
54
|
+
context = FlowContext(session_id="test")
|
|
55
|
+
tool = create_tool("my_tool")
|
|
56
|
+
result = await tool.run(context)
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## 📚 Documentation
|
|
60
|
+
|
|
61
|
+
- **[Usage Guide](docs/USAGE_GUIDE.md)** - Learn how to use AgStack in your projects
|
|
62
|
+
- **[Development Rules](docs/DEVELOPMENT_RULES.md)** - Guidelines for contributing to AgStack
|
|
63
|
+
- **API Reference** - Coming soon
|
|
64
|
+
- **Examples** - Coming soon
|
|
65
|
+
|
|
66
|
+
## 🏗️ Architecture
|
|
67
|
+
|
|
68
|
+
### Project Structure
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
agstack/
|
|
72
|
+
├── schema.py # Base Pydantic models
|
|
73
|
+
├── registry.py # Global component registry
|
|
74
|
+
├── exceptions.py # Exception hierarchy
|
|
75
|
+
├── llm/ # LLM and AI features
|
|
76
|
+
│ ├── client.py # LLM client
|
|
77
|
+
│ └── flow/ # Flow execution framework
|
|
78
|
+
│ ├── agent.py # Agent definition
|
|
79
|
+
│ ├── tool.py # Tool definition
|
|
80
|
+
│ ├── flow.py # Flow orchestration
|
|
81
|
+
│ └── ...
|
|
82
|
+
├── fastapi/ # FastAPI integration
|
|
83
|
+
├── infra/ # Infrastructure components
|
|
84
|
+
│ ├── db/ # Database
|
|
85
|
+
│ ├── es/ # Elasticsearch
|
|
86
|
+
│ └── mq/ # Message Queue
|
|
87
|
+
└── security/ # Security features
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Core Concepts
|
|
91
|
+
|
|
92
|
+
- **Agent** - LLM-powered intelligent agents
|
|
93
|
+
- **Tool** - Functions that can be called by agents
|
|
94
|
+
- **Flow** - Orchestration of multiple agents and tools
|
|
95
|
+
- **Registry** - Centralized component management
|
|
96
|
+
- **BaseSchema** - Enhanced Pydantic models with unified configuration
|
|
97
|
+
|
|
98
|
+
## 🛠️ Development
|
|
99
|
+
|
|
100
|
+
### Requirements
|
|
101
|
+
|
|
102
|
+
- Python >= 3.12
|
|
103
|
+
- Dependencies listed in `pyproject.toml`
|
|
104
|
+
|
|
105
|
+
### Setup
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
# Clone the repository
|
|
109
|
+
git clone https://github.com/xtravisions/agstack.git
|
|
110
|
+
cd agstack
|
|
111
|
+
|
|
112
|
+
# Install dependencies
|
|
113
|
+
pip install -e ".[dev]"
|
|
114
|
+
|
|
115
|
+
# Install pre-commit hooks
|
|
116
|
+
pre-commit install
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Code Quality
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
# Format code
|
|
123
|
+
ruff format .
|
|
124
|
+
|
|
125
|
+
# Lint
|
|
126
|
+
ruff check .
|
|
127
|
+
|
|
128
|
+
# Type check
|
|
129
|
+
pyright
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Contributing
|
|
133
|
+
|
|
134
|
+
Please read [DEVELOPMENT_RULES.md](docs/DEVELOPMENT_RULES.md) for development guidelines and coding standards.
|
|
135
|
+
|
|
136
|
+
## 📦 Features
|
|
137
|
+
|
|
138
|
+
### LLM Flow System
|
|
139
|
+
|
|
140
|
+
- **Agent System** - Create and manage LLM-powered agents
|
|
141
|
+
- **Tool System** - Define reusable tools for agents
|
|
142
|
+
- **Flow Orchestration** - Chain multiple agents and tools
|
|
143
|
+
- **Context Management** - Maintain state across execution
|
|
144
|
+
- **Event System** - AG-UI protocol support
|
|
145
|
+
|
|
146
|
+
### FastAPI Integration
|
|
147
|
+
|
|
148
|
+
- Production-ready setup
|
|
149
|
+
- Middleware support
|
|
150
|
+
- Exception handling
|
|
151
|
+
- Request/Response schemas
|
|
152
|
+
|
|
153
|
+
### Infrastructure
|
|
154
|
+
|
|
155
|
+
- **Database** - PostgreSQL with async support (asyncpg)
|
|
156
|
+
- **Elasticsearch** - Full-text search integration
|
|
157
|
+
- **Message Queue** - Async message processing (aio-pika)
|
|
158
|
+
|
|
159
|
+
### Security
|
|
160
|
+
|
|
161
|
+
- JWT authentication
|
|
162
|
+
- Casbin authorization
|
|
163
|
+
- Password hashing (bcrypt)
|
|
164
|
+
|
|
165
|
+
## 🤝 Contributing
|
|
166
|
+
|
|
167
|
+
We welcome contributions! Please see our [Development Rules](docs/DEVELOPMENT_RULES.md) for guidelines.
|
|
168
|
+
|
|
169
|
+
### Key Guidelines
|
|
170
|
+
|
|
171
|
+
- Use relative imports (not `from agstack...`)
|
|
172
|
+
- Inherit from `BaseSchema` for Pydantic models
|
|
173
|
+
- Use `ruff` and `pyright` for code quality
|
|
174
|
+
- Follow Python 3.12+ standards
|
|
175
|
+
- Write tests for new features
|
|
176
|
+
|
|
177
|
+
## 📄 License
|
|
178
|
+
|
|
179
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
180
|
+
|
|
181
|
+
## 👥 Authors
|
|
182
|
+
|
|
183
|
+
- **XtraVisions** - [gitadmin@xtravisions.com](mailto:gitadmin@xtravisions.com)
|
|
184
|
+
- **Chen Hao** - [chenhao@xtravisions.com](mailto:chenhao@xtravisions.com)
|
|
185
|
+
|
|
186
|
+
## 🔗 Links
|
|
187
|
+
|
|
188
|
+
- **Documentation**: [docs/](docs/)
|
|
189
|
+
- **GitHub**: (TBD)
|
|
190
|
+
- **Issues**: (TBD)
|
|
191
|
+
- **PyPI**: (TBD)
|
|
192
|
+
|
|
193
|
+
## 📝 Changelog
|
|
194
|
+
|
|
195
|
+
See [CHANGELOG.md](CHANGELOG.md) for release history.
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
**Note**: AgStack is under active development. APIs may change before the 1.0 stable release.
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# Copyright (c) 2020-2026 XtraVisions, All rights reserved.
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
import sys
|
|
5
|
+
from datetime import time, timedelta
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
from loguru import RetentionFunction, RotationFunction, logger
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class InterceptHandler(logging.Handler):
|
|
12
|
+
"""拦截标准 logging 并重定向到 loguru"""
|
|
13
|
+
|
|
14
|
+
def emit(self, record: logging.LogRecord) -> None:
|
|
15
|
+
try:
|
|
16
|
+
level = logger.level(record.levelname).name
|
|
17
|
+
except ValueError:
|
|
18
|
+
level = record.levelno
|
|
19
|
+
|
|
20
|
+
# 直接使用 logging.LogRecord 的信息,避免栈帧查找
|
|
21
|
+
logger.patch(
|
|
22
|
+
lambda r: r.update(
|
|
23
|
+
name=record.name,
|
|
24
|
+
file={"name": record.pathname, "path": record.pathname}, # type: ignore[arg-type]
|
|
25
|
+
line=record.lineno,
|
|
26
|
+
function=record.funcName,
|
|
27
|
+
)
|
|
28
|
+
).log(level, record.getMessage())
|
|
29
|
+
|
|
30
|
+
# CRITICAL/FATAL 级别自动退出
|
|
31
|
+
if record.levelno >= logging.CRITICAL:
|
|
32
|
+
sys.exit(1)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def setup_logger(
|
|
36
|
+
appname: str,
|
|
37
|
+
output: str | Path,
|
|
38
|
+
level: str | int = "INFO",
|
|
39
|
+
rotation: str | int | time | timedelta | RotationFunction | None = "1 day",
|
|
40
|
+
retention: str | int | timedelta | RetentionFunction | None = "30 days",
|
|
41
|
+
) -> None:
|
|
42
|
+
"""初始化日志系统
|
|
43
|
+
|
|
44
|
+
:param appname: 应用名称
|
|
45
|
+
:param output: 日志输出目录
|
|
46
|
+
:param level: 日志级别(默认 INFO)
|
|
47
|
+
:param rotation: 日志轮转策略(默认每天轮转)
|
|
48
|
+
:param retention: 日志保留策略(默认保留 30 天)
|
|
49
|
+
"""
|
|
50
|
+
log_path = Path(output)
|
|
51
|
+
log_path.mkdir(parents=True, exist_ok=True)
|
|
52
|
+
|
|
53
|
+
log_format = "[{time:YYYY-MM-DD HH:mm:ss}] | {level: <8} | {name}:{line} - {message}"
|
|
54
|
+
|
|
55
|
+
# 移除默认 handler
|
|
56
|
+
logger.remove()
|
|
57
|
+
|
|
58
|
+
# 添加控制台 handler
|
|
59
|
+
logger.add(
|
|
60
|
+
sys.stderr,
|
|
61
|
+
format=log_format,
|
|
62
|
+
level=level,
|
|
63
|
+
colorize=True,
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
# 添加文件 handler(带轮转)
|
|
67
|
+
logger.add(
|
|
68
|
+
log_path / f"{appname}.log",
|
|
69
|
+
format=log_format,
|
|
70
|
+
level=level,
|
|
71
|
+
rotation=rotation,
|
|
72
|
+
retention=retention,
|
|
73
|
+
encoding="utf8",
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
# 拦截标准 logging
|
|
77
|
+
logging.basicConfig(handlers=[InterceptHandler()], level=0, force=True)
|
|
78
|
+
for name in logging.root.manager.loggerDict.keys():
|
|
79
|
+
logging.getLogger(name).handlers = []
|
|
80
|
+
logging.getLogger(name).propagate = True
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# Copyright (c) 2020-2026 XtraVisions, All rights reserved.
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
import os
|
|
5
|
+
import tomllib
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from typing import Any
|
|
8
|
+
|
|
9
|
+
from .logger import setup_logger
|
|
10
|
+
from .types import AppConfig
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def _load_config_file(config_path: Path) -> dict[str, Any]:
|
|
14
|
+
"""加载配置文件(容错处理)"""
|
|
15
|
+
if not config_path.exists():
|
|
16
|
+
return {}
|
|
17
|
+
|
|
18
|
+
try:
|
|
19
|
+
with open(config_path, "rb") as f:
|
|
20
|
+
return tomllib.load(f)
|
|
21
|
+
except Exception: # noqa
|
|
22
|
+
print(f"Failed to load config file: {config_path}")
|
|
23
|
+
return {}
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def _load_env_overrides(prefix: str = "APP") -> dict[str, Any]:
|
|
27
|
+
"""加载环境变量覆盖配置
|
|
28
|
+
|
|
29
|
+
支持格式:
|
|
30
|
+
- APP_DATABASE_HOST=localhost
|
|
31
|
+
- APP_WEBAPI_DEBUG=true
|
|
32
|
+
- APP_MODELS_EMBEDDING_ENGINE=bedrock
|
|
33
|
+
"""
|
|
34
|
+
config_data = {}
|
|
35
|
+
prefix = prefix.upper() + "_"
|
|
36
|
+
|
|
37
|
+
for key, value in os.environ.items():
|
|
38
|
+
if key.startswith(prefix):
|
|
39
|
+
config_key = key[len(prefix) :].lower()
|
|
40
|
+
_set_nested_value(config_data, config_key, _parse_env_value(value))
|
|
41
|
+
|
|
42
|
+
return config_data
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def _set_nested_value(data: dict[str, Any], key: str, value: Any) -> None:
|
|
46
|
+
"""设置嵌套字典值(支持下划线分隔)"""
|
|
47
|
+
if "_" in key:
|
|
48
|
+
parts = key.split("_", 1)
|
|
49
|
+
if parts[0] not in data:
|
|
50
|
+
data[parts[0]] = {}
|
|
51
|
+
_set_nested_value(data[parts[0]], parts[1], value)
|
|
52
|
+
else:
|
|
53
|
+
data[key] = value
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def _parse_env_value(value: str) -> Any:
|
|
57
|
+
"""解析环境变量值(自动类型转换)"""
|
|
58
|
+
# 布尔值
|
|
59
|
+
if value.lower() in ("true", "false"):
|
|
60
|
+
return value.lower() == "true"
|
|
61
|
+
|
|
62
|
+
# 数字
|
|
63
|
+
try:
|
|
64
|
+
if "." in value:
|
|
65
|
+
return float(value)
|
|
66
|
+
return int(value)
|
|
67
|
+
except ValueError:
|
|
68
|
+
pass
|
|
69
|
+
|
|
70
|
+
# JSON
|
|
71
|
+
if value.startswith(("{", "[")):
|
|
72
|
+
try:
|
|
73
|
+
return json.loads(value)
|
|
74
|
+
except json.JSONDecodeError:
|
|
75
|
+
pass
|
|
76
|
+
|
|
77
|
+
return value
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def _determine_log_level(config_data: dict[str, Any]) -> str:
|
|
81
|
+
"""确定日志级别(优先级:环境变量 > debug 模式 > 配置文件)"""
|
|
82
|
+
# 1. 环境变量优先级最高
|
|
83
|
+
env_level = os.environ.get("METAMATRIX_LOG_LEVEL")
|
|
84
|
+
if env_level:
|
|
85
|
+
level = env_level.upper()
|
|
86
|
+
if level in ("TRACE", "DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"):
|
|
87
|
+
return level
|
|
88
|
+
|
|
89
|
+
# 2. debug 模式强制使用 DEBUG
|
|
90
|
+
mode = config_data.get("mode", "").lower()
|
|
91
|
+
if mode == "dev":
|
|
92
|
+
return "DEBUG"
|
|
93
|
+
|
|
94
|
+
# 3. 使用配置文件中的级别
|
|
95
|
+
return config_data.get("logger", {}).get("level", "INFO")
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def setup_config(appname: str, envprefix: str = "APP") -> AppConfig:
|
|
99
|
+
"""初始化配置
|
|
100
|
+
|
|
101
|
+
Args:
|
|
102
|
+
appname: 应用名称
|
|
103
|
+
envprefix: 环境变量前缀
|
|
104
|
+
|
|
105
|
+
Returns:
|
|
106
|
+
AppConfig: 配置实例
|
|
107
|
+
"""
|
|
108
|
+
approot = Path.cwd()
|
|
109
|
+
config_path = approot / "config.toml"
|
|
110
|
+
|
|
111
|
+
# 1. 加载配置文件(容错)
|
|
112
|
+
config_data = _load_config_file(config_path)
|
|
113
|
+
|
|
114
|
+
# 2. 加载环境变量覆盖
|
|
115
|
+
env_overrides = _load_env_overrides(envprefix)
|
|
116
|
+
config_data.update(env_overrides)
|
|
117
|
+
|
|
118
|
+
# 3. 设置应用信息
|
|
119
|
+
config_data.update({"appname": appname, "approot": approot})
|
|
120
|
+
|
|
121
|
+
# 4. 确定日志级别(优先级处理)
|
|
122
|
+
log_level = _determine_log_level(config_data)
|
|
123
|
+
config_data.setdefault("logger", {})["level"] = log_level
|
|
124
|
+
|
|
125
|
+
# 5. 初始化日志(使用字典配置)
|
|
126
|
+
setup_logger(appname, **config_data["logger"])
|
|
127
|
+
|
|
128
|
+
# 8. 创建配置实例(最后验证)
|
|
129
|
+
config = AppConfig.model_validate(config_data)
|
|
130
|
+
|
|
131
|
+
return config
|