maki-framework 0.3.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.
- maki_framework-0.3.0/LICENSE +21 -0
- maki_framework-0.3.0/PKG-INFO +582 -0
- maki_framework-0.3.0/README.md +521 -0
- maki_framework-0.3.0/maki/__init__.py +57 -0
- maki_framework-0.3.0/maki/__main__.py +104 -0
- maki_framework-0.3.0/maki/agents/__init__.py +27 -0
- maki_framework-0.3.0/maki/agents/agent.py +388 -0
- maki_framework-0.3.0/maki/agents/agent_manager.py +791 -0
- maki_framework-0.3.0/maki/agents/agents.py +16 -0
- maki_framework-0.3.0/maki/agents/approvals.py +209 -0
- maki_framework-0.3.0/maki/agents/plugin_handler.py +582 -0
- maki_framework-0.3.0/maki/agents/protocols.py +49 -0
- maki_framework-0.3.0/maki/agents/reasoning.py +267 -0
- maki_framework-0.3.0/maki/agents/verification.py +174 -0
- maki_framework-0.3.0/maki/agents/workflow.py +271 -0
- maki_framework-0.3.0/maki/backend.py +155 -0
- maki_framework-0.3.0/maki/config.py +123 -0
- maki_framework-0.3.0/maki/connector.py +446 -0
- maki_framework-0.3.0/maki/distributed/__init__.py +16 -0
- maki_framework-0.3.0/maki/distributed/circuit_breaker.py +117 -0
- maki_framework-0.3.0/maki/distributed/config_loader.py +135 -0
- maki_framework-0.3.0/maki/distributed/proxy.py +346 -0
- maki_framework-0.3.0/maki/distributed/registry.py +89 -0
- maki_framework-0.3.0/maki/distributed/server.py +254 -0
- maki_framework-0.3.0/maki/distributed/state_store.py +230 -0
- maki_framework-0.3.0/maki/exceptions.py +30 -0
- maki_framework-0.3.0/maki/logging_config.py +39 -0
- maki_framework-0.3.0/maki/makiAnthropic.py +384 -0
- maki_framework-0.3.0/maki/makiHG.py +237 -0
- maki_framework-0.3.0/maki/makiLLama.py +580 -0
- maki_framework-0.3.0/maki/makiLlamaCpp.py +274 -0
- maki_framework-0.3.0/maki/makiOpenAI.py +383 -0
- maki_framework-0.3.0/maki/makiOpenRouter.py +147 -0
- maki_framework-0.3.0/maki/objects.py +389 -0
- maki_framework-0.3.0/maki/plugins/__init__.py +47 -0
- maki_framework-0.3.0/maki/plugins/_web_utils.py +100 -0
- maki_framework-0.3.0/maki/plugins/alpaca_data/__init__.py +3 -0
- maki_framework-0.3.0/maki/plugins/alpaca_data/alpaca_data.py +271 -0
- maki_framework-0.3.0/maki/plugins/alpaca_data/example_usage.py +34 -0
- maki_framework-0.3.0/maki/plugins/alpaca_data/test_alpaca_data.py +141 -0
- maki_framework-0.3.0/maki/plugins/alpaca_news/__init__.py +3 -0
- maki_framework-0.3.0/maki/plugins/alpaca_news/alpaca_news.py +184 -0
- maki_framework-0.3.0/maki/plugins/alpaca_news/example_usage.py +37 -0
- maki_framework-0.3.0/maki/plugins/alpaca_news/test_alpaca_news.py +96 -0
- maki_framework-0.3.0/maki/plugins/alpaca_stream/__init__.py +3 -0
- maki_framework-0.3.0/maki/plugins/alpaca_stream/alpaca_stream.py +152 -0
- maki_framework-0.3.0/maki/plugins/alpaca_stream/example_usage.py +42 -0
- maki_framework-0.3.0/maki/plugins/alpaca_stream/test_alpaca_stream.py +84 -0
- maki_framework-0.3.0/maki/plugins/alpaca_trading/__init__.py +3 -0
- maki_framework-0.3.0/maki/plugins/alpaca_trading/alpaca_trading.py +189 -0
- maki_framework-0.3.0/maki/plugins/alpaca_trading/example_usage.py +44 -0
- maki_framework-0.3.0/maki/plugins/alpaca_trading/test_alpaca_trading.py +24 -0
- maki_framework-0.3.0/maki/plugins/directory_reader/__init__.py +10 -0
- maki_framework-0.3.0/maki/plugins/directory_reader/directory_reader.py +239 -0
- maki_framework-0.3.0/maki/plugins/directory_reader/example_usage.py +41 -0
- maki_framework-0.3.0/maki/plugins/directory_reader/test_directory_reader.py +94 -0
- maki_framework-0.3.0/maki/plugins/file_reader/__init__.py +10 -0
- maki_framework-0.3.0/maki/plugins/file_reader/example_usage.py +58 -0
- maki_framework-0.3.0/maki/plugins/file_reader/file_reader.py +272 -0
- maki_framework-0.3.0/maki/plugins/file_reader/test_file_reader.py +74 -0
- maki_framework-0.3.0/maki/plugins/file_writer/__init__.py +10 -0
- maki_framework-0.3.0/maki/plugins/file_writer/example_usage.py +47 -0
- maki_framework-0.3.0/maki/plugins/file_writer/file_writer.py +332 -0
- maki_framework-0.3.0/maki/plugins/file_writer/test_file_writer.py +96 -0
- maki_framework-0.3.0/maki/plugins/ftp_client/__init__.py +10 -0
- maki_framework-0.3.0/maki/plugins/ftp_client/example_usage.py +116 -0
- maki_framework-0.3.0/maki/plugins/ftp_client/ftp_client.py +845 -0
- maki_framework-0.3.0/maki/plugins/ftp_client/test_ftp_client.py +251 -0
- maki_framework-0.3.0/maki/plugins/image_classifier/__init__.py +11 -0
- maki_framework-0.3.0/maki/plugins/image_classifier/example_usage.py +83 -0
- maki_framework-0.3.0/maki/plugins/image_classifier/image_classifier.py +116 -0
- maki_framework-0.3.0/maki/plugins/image_classifier/test_image_classifier.py +182 -0
- maki_framework-0.3.0/maki/plugins/json_reader/__init__.py +7 -0
- maki_framework-0.3.0/maki/plugins/json_reader/example_usage.py +18 -0
- maki_framework-0.3.0/maki/plugins/json_reader/json_reader.py +113 -0
- maki_framework-0.3.0/maki/plugins/json_reader/test_json_reader.py +37 -0
- maki_framework-0.3.0/maki/plugins/obsidian_memory/__init__.py +3 -0
- maki_framework-0.3.0/maki/plugins/obsidian_memory/example_usage.py +54 -0
- maki_framework-0.3.0/maki/plugins/obsidian_memory/obsidian_memory.py +221 -0
- maki_framework-0.3.0/maki/plugins/obsidian_memory/test_obsidian_memory.py +83 -0
- maki_framework-0.3.0/maki/plugins/ocr/__init__.py +10 -0
- maki_framework-0.3.0/maki/plugins/ocr/backends/__init__.py +17 -0
- maki_framework-0.3.0/maki/plugins/ocr/backends/base.py +48 -0
- maki_framework-0.3.0/maki/plugins/ocr/backends/docx_backend.py +69 -0
- maki_framework-0.3.0/maki/plugins/ocr/backends/image_backend.py +49 -0
- maki_framework-0.3.0/maki/plugins/ocr/backends/llm_backend.py +164 -0
- maki_framework-0.3.0/maki/plugins/ocr/backends/pdf_backend.py +73 -0
- maki_framework-0.3.0/maki/plugins/ocr/backends/xlsx_backend.py +59 -0
- maki_framework-0.3.0/maki/plugins/ocr/example_usage.py +79 -0
- maki_framework-0.3.0/maki/plugins/ocr/ocr.py +242 -0
- maki_framework-0.3.0/maki/plugins/ocr/test_ocr.py +273 -0
- maki_framework-0.3.0/maki/plugins/postgres_store/__init__.py +10 -0
- maki_framework-0.3.0/maki/plugins/postgres_store/example_usage.py +35 -0
- maki_framework-0.3.0/maki/plugins/postgres_store/postgres_store.py +271 -0
- maki_framework-0.3.0/maki/plugins/postgres_store/test_postgres_store.py +133 -0
- maki_framework-0.3.0/maki/plugins/provider_updates/__init__.py +7 -0
- maki_framework-0.3.0/maki/plugins/provider_updates/example_usage.py +14 -0
- maki_framework-0.3.0/maki/plugins/provider_updates/provider_updates.py +101 -0
- maki_framework-0.3.0/maki/plugins/provider_updates/test_provider_updates.py +51 -0
- maki_framework-0.3.0/maki/plugins/rag_memory/__init__.py +3 -0
- maki_framework-0.3.0/maki/plugins/rag_memory/backends/__init__.py +57 -0
- maki_framework-0.3.0/maki/plugins/rag_memory/backends/base.py +70 -0
- maki_framework-0.3.0/maki/plugins/rag_memory/backends/chroma.py +95 -0
- maki_framework-0.3.0/maki/plugins/rag_memory/backends/faiss_local.py +123 -0
- maki_framework-0.3.0/maki/plugins/rag_memory/backends/memory_numpy.py +101 -0
- maki_framework-0.3.0/maki/plugins/rag_memory/backends/pgvector.py +137 -0
- maki_framework-0.3.0/maki/plugins/rag_memory/backends/qdrant.py +108 -0
- maki_framework-0.3.0/maki/plugins/rag_memory/example_usage.py +71 -0
- maki_framework-0.3.0/maki/plugins/rag_memory/rag_memory.py +383 -0
- maki_framework-0.3.0/maki/plugins/rag_memory/test_rag_memory.py +275 -0
- maki_framework-0.3.0/maki/plugins/trend_search/__init__.py +7 -0
- maki_framework-0.3.0/maki/plugins/trend_search/example_usage.py +14 -0
- maki_framework-0.3.0/maki/plugins/trend_search/test_trend_search.py +81 -0
- maki_framework-0.3.0/maki/plugins/trend_search/trend_search.py +115 -0
- maki_framework-0.3.0/maki/plugins/web_search/__init__.py +11 -0
- maki_framework-0.3.0/maki/plugins/web_search/example_usage.py +48 -0
- maki_framework-0.3.0/maki/plugins/web_search/test_web_search.py +539 -0
- maki_framework-0.3.0/maki/plugins/web_search/web_search.py +699 -0
- maki_framework-0.3.0/maki/plugins/web_to_md/__init__.py +9 -0
- maki_framework-0.3.0/maki/plugins/web_to_md/example_usage.py +47 -0
- maki_framework-0.3.0/maki/plugins/web_to_md/test_web_to_md.py +159 -0
- maki_framework-0.3.0/maki/plugins/web_to_md/web_to_md.py +296 -0
- maki_framework-0.3.0/maki/py.typed +0 -0
- maki_framework-0.3.0/maki/session.py +88 -0
- maki_framework-0.3.0/maki/structured.py +148 -0
- maki_framework-0.3.0/maki/test/__init__.py +3 -0
- maki_framework-0.3.0/maki/test/test_agent_fixes.py +567 -0
- maki_framework-0.3.0/maki/test/test_agent_functionality.py +177 -0
- maki_framework-0.3.0/maki/test/test_agent_proxy.py +478 -0
- maki_framework-0.3.0/maki/test/test_agent_server.py +313 -0
- maki_framework-0.3.0/maki/test/test_async_rate_limiter.py +341 -0
- maki_framework-0.3.0/maki/test/test_backend_hierarchy.py +327 -0
- maki_framework-0.3.0/maki/test/test_backend_interface.py +402 -0
- maki_framework-0.3.0/maki/test/test_concurrency.py +509 -0
- maki_framework-0.3.0/maki/test/test_config_loader.py +98 -0
- maki_framework-0.3.0/maki/test/test_connector.py +429 -0
- maki_framework-0.3.0/maki/test/test_consistency_sweep.py +349 -0
- maki_framework-0.3.0/maki/test/test_conversation_memory.py +398 -0
- maki_framework-0.3.0/maki/test/test_distributed_workflow.py +560 -0
- maki_framework-0.3.0/maki/test/test_enhanced_workflow.py +153 -0
- maki_framework-0.3.0/maki/test/test_error_handling.py +171 -0
- maki_framework-0.3.0/maki/test/test_hardening.py +503 -0
- maki_framework-0.3.0/maki/test/test_history_cleanup.py +114 -0
- maki_framework-0.3.0/maki/test/test_logging.py +32 -0
- maki_framework-0.3.0/maki/test/test_makiAnthropic.py +267 -0
- maki_framework-0.3.0/maki/test/test_makiLLama.py +297 -0
- maki_framework-0.3.0/maki/test/test_makiLLama_unittest.py +252 -0
- maki_framework-0.3.0/maki/test/test_makiLlamaCpp.py +291 -0
- maki_framework-0.3.0/maki/test/test_makiOpenAI.py +255 -0
- maki_framework-0.3.0/maki/test/test_makiOpenRouter.py +270 -0
- maki_framework-0.3.0/maki/test/test_mixin_contracts.py +384 -0
- maki_framework-0.3.0/maki/test/test_native_tools.py +652 -0
- maki_framework-0.3.0/maki/test/test_plugin_structure.py +50 -0
- maki_framework-0.3.0/maki/test/test_security.py +705 -0
- maki_framework-0.3.0/maki/test/test_serialization.py +313 -0
- maki_framework-0.3.0/maki/test/test_session.py +65 -0
- maki_framework-0.3.0/maki/test/test_ssrp_protection.py +105 -0
- maki_framework-0.3.0/maki/test/test_structured_output.py +128 -0
- maki_framework-0.3.0/maki/test/test_verification_types.py +97 -0
- maki_framework-0.3.0/maki/test/test_verified_workflow.py +281 -0
- maki_framework-0.3.0/maki/test/test_workflow_approval.py +205 -0
- maki_framework-0.3.0/maki/utils.py +250 -0
- maki_framework-0.3.0/maki_framework.egg-info/PKG-INFO +582 -0
- maki_framework-0.3.0/maki_framework.egg-info/SOURCES.txt +168 -0
- maki_framework-0.3.0/maki_framework.egg-info/dependency_links.txt +1 -0
- maki_framework-0.3.0/maki_framework.egg-info/entry_points.txt +3 -0
- maki_framework-0.3.0/maki_framework.egg-info/requires.txt +58 -0
- maki_framework-0.3.0/maki_framework.egg-info/top_level.txt +1 -0
- maki_framework-0.3.0/pyproject.toml +104 -0
- maki_framework-0.3.0/setup.cfg +4 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Bowl of Data
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,582 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: maki-framework
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Summary: A Python framework for multi-agent LLM interactions
|
|
5
|
+
Author-email: Bowl of Data <bowlofdata@gmail.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Requires-Python: >=3.10
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
License-File: LICENSE
|
|
17
|
+
Requires-Dist: requests>=2.25.0
|
|
18
|
+
Requires-Dist: httpx>=0.23.0
|
|
19
|
+
Requires-Dist: python-dotenv>=1.0.0
|
|
20
|
+
Provides-Extra: postgres
|
|
21
|
+
Requires-Dist: psycopg[binary]>=3.1; extra == "postgres"
|
|
22
|
+
Requires-Dist: psycopg_pool>=3.2; extra == "postgres"
|
|
23
|
+
Provides-Extra: structured
|
|
24
|
+
Requires-Dist: pydantic>=2.0; extra == "structured"
|
|
25
|
+
Provides-Extra: dev
|
|
26
|
+
Requires-Dist: pytest>=6.0; extra == "dev"
|
|
27
|
+
Requires-Dist: pytest-asyncio>=0.21; extra == "dev"
|
|
28
|
+
Requires-Dist: black>=21.0; extra == "dev"
|
|
29
|
+
Requires-Dist: flake8>=3.8; extra == "dev"
|
|
30
|
+
Provides-Extra: openai
|
|
31
|
+
Requires-Dist: openai>=1.0; extra == "openai"
|
|
32
|
+
Provides-Extra: anthropic
|
|
33
|
+
Requires-Dist: anthropic>=0.20; extra == "anthropic"
|
|
34
|
+
Provides-Extra: openrouter
|
|
35
|
+
Requires-Dist: openai>=1.0; extra == "openrouter"
|
|
36
|
+
Provides-Extra: llamacpp
|
|
37
|
+
Requires-Dist: openai>=1.0; extra == "llamacpp"
|
|
38
|
+
Provides-Extra: distributed
|
|
39
|
+
Requires-Dist: fastapi>=0.100.0; extra == "distributed"
|
|
40
|
+
Requires-Dist: uvicorn>=0.20.0; extra == "distributed"
|
|
41
|
+
Requires-Dist: pyyaml>=6.0; extra == "distributed"
|
|
42
|
+
Provides-Extra: distributed-redis
|
|
43
|
+
Requires-Dist: redis>=4.5; extra == "distributed-redis"
|
|
44
|
+
Provides-Extra: gui
|
|
45
|
+
Requires-Dist: PySide6>=6.7.0; extra == "gui"
|
|
46
|
+
Provides-Extra: ftp
|
|
47
|
+
Requires-Dist: paramiko>=2.11.0; extra == "ftp"
|
|
48
|
+
Provides-Extra: web
|
|
49
|
+
Requires-Dist: feedparser>=6.0; extra == "web"
|
|
50
|
+
Requires-Dist: readability-lxml>=0.8; extra == "web"
|
|
51
|
+
Requires-Dist: html2text>=2020.1.16; extra == "web"
|
|
52
|
+
Provides-Extra: trends
|
|
53
|
+
Requires-Dist: pytrends>=4.9.0; extra == "trends"
|
|
54
|
+
Provides-Extra: alpaca
|
|
55
|
+
Requires-Dist: alpaca-py>=0.43.0; extra == "alpaca"
|
|
56
|
+
Requires-Dist: feedparser>=6.0; extra == "alpaca"
|
|
57
|
+
Requires-Dist: yfinance>=0.2.40; extra == "alpaca"
|
|
58
|
+
Provides-Extra: all
|
|
59
|
+
Requires-Dist: maki-framework[alpaca,anthropic,distributed,distributed-redis,ftp,gui,llamacpp,openai,openrouter,structured,trends,web]; extra == "all"
|
|
60
|
+
Dynamic: license-file
|
|
61
|
+
|
|
62
|
+
<p align="center">
|
|
63
|
+
<img src="img/logo.png" alt="Maki Logo" width="200" />
|
|
64
|
+
</p>
|
|
65
|
+
|
|
66
|
+
# Maki
|
|
67
|
+
|
|
68
|
+
[](https://www.python.org/)
|
|
69
|
+
[](LICENSE)
|
|
70
|
+
[](https://github.com/BowlOfData/maki/actions/workflows/python-package.yml)
|
|
71
|
+
[](https://ollama.ai/)
|
|
72
|
+
[](https://huggingface.co/)
|
|
73
|
+
[](https://github.com/)
|
|
74
|
+
|
|
75
|
+
**Maki is a Python framework for multi-agent LLM applications that run wherever your models do: on your own hardware (through Ollama or llama.cpp), on a hosted API (OpenAI, Anthropic, OpenRouter), or a mix of both, with the same agent code.**
|
|
76
|
+
|
|
77
|
+
It is for developers who want to build and run tool-using agents on local models first, keep the option of moving any task to a hosted model by swapping one object, and have guardrails switched on by default while those agents touch files, the web, or a broker account.
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Why Maki
|
|
82
|
+
|
|
83
|
+
- **Local and hosted models are equals.** Ollama and llama.cpp are built-in backends, not add-ons, and sit next to OpenAI, Anthropic, and OpenRouter behind the same `LLMBackend` contract. Agents, workflows, and plugins never know which one they are talking to. An in-process HuggingFace Transformers backend is also included (manual install, see [below](#huggingface-backend)).
|
|
84
|
+
- **Guardrails on by default.** Requests Maki makes itself (Ollama, remote agents, web plugins) go through a hardened connector. URLs that come from content, such as pages and feeds, are checked against private and reserved address ranges at connect time (redirect hops included); operator-configured endpoints like a LAN Ollama host are allowed. Plugins are fail-closed: a model can only call methods a plugin explicitly lists, and destructive ones (file writes, FTP transfers, trades) stay disabled until you pass `Agent(allow_dangerous_tools=True)`. The trading plugin runs in paper mode unless you opt in to live.
|
|
85
|
+
- **Small core.** The base install has three dependencies (`requests`, `httpx`, `python-dotenv`). Everything else is an opt-in extra.
|
|
86
|
+
- **Agents as services.** `maki serve` exposes any agent over HTTP, and `AgentProxy` lets another process use it as if it were local, with a circuit breaker and optional bearer-token auth.
|
|
87
|
+
- **Batteries included.** 16 built-in plugins (files, web, market data, memory) and a workflow engine with dependency resolution, retries, parallel execution, and checkpoint/resume.
|
|
88
|
+
|
|
89
|
+
### Who it is not for
|
|
90
|
+
|
|
91
|
+
Maki is young (0.x) and deliberately small. If you need a large catalog of third-party integrations, hosted tracing and observability, or a big community and ecosystem around your framework, one of the larger agent frameworks will serve you better.
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## Backends
|
|
96
|
+
|
|
97
|
+
| Backend | Where inference runs | Class | Requires |
|
|
98
|
+
|---|---|---|---|
|
|
99
|
+
| Ollama | Your machine or LAN | `MakiLLama` | a running Ollama server |
|
|
100
|
+
| llama.cpp | Your machine or LAN | `MakiLlamaCpp` | `maki-framework[llamacpp]` and a running `llama serve` |
|
|
101
|
+
| HuggingFace Transformers | In-process, on your CPU/GPU | `HFBackend` | `torch`, `transformers`, `accelerate` (manual install, see [HuggingFace Backend](#huggingface-backend)) |
|
|
102
|
+
| OpenAI | Hosted | `MakiOpenAI` | `maki-framework[openai]` |
|
|
103
|
+
| Anthropic | Hosted | `MakiAnthropic` | `maki-framework[anthropic]` |
|
|
104
|
+
| OpenRouter | Hosted, any vendor-namespaced model | `MakiOpenRouter` | `maki-framework[openrouter]` |
|
|
105
|
+
|
|
106
|
+
The same agent runs on any of them; only the backend object changes:
|
|
107
|
+
|
|
108
|
+
```python
|
|
109
|
+
from maki import MakiLLama, MakiLlamaCpp, MakiOpenAI, MakiAnthropic
|
|
110
|
+
from maki.agents import Agent
|
|
111
|
+
|
|
112
|
+
def reviewer(llm):
|
|
113
|
+
return Agent(
|
|
114
|
+
name="Reviewer",
|
|
115
|
+
maki_instance=llm,
|
|
116
|
+
role="code reviewer",
|
|
117
|
+
instructions="Focus on bugs, regressions, and missing validation.",
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
agent = reviewer(MakiLLama(model="gemma4:26b")) # local, via Ollama
|
|
121
|
+
# agent = reviewer(MakiLlamaCpp()) # local, via llama.cpp
|
|
122
|
+
# agent = reviewer(MakiOpenAI(model="gpt-4o")) # hosted
|
|
123
|
+
# agent = reviewer(MakiAnthropic(model="claude-sonnet-4-5")) # hosted
|
|
124
|
+
|
|
125
|
+
print(agent.execute_task("Review this design: a plugin system with file access."))
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## Features
|
|
131
|
+
|
|
132
|
+
- `MakiLLama` — Ollama chat API with synchronous, streaming, async, and vision-capable workflows
|
|
133
|
+
- `MakiLlamaCpp` — llama.cpp `llama serve` (GGUF models) with streaming, async, vision, tool calling, separate reasoning output, embeddings, and reranking
|
|
134
|
+
- `MakiOpenAI` — OpenAI chat completions, including reasoning models (o3/o4)
|
|
135
|
+
- `MakiAnthropic` — Anthropic messages API (Claude Sonnet, Haiku, Opus)
|
|
136
|
+
- `HFBackend` — direct HuggingFace Transformers integration with quantization and device selection
|
|
137
|
+
- `Agent` — role-based agents with task execution, memory, reasoning, and plugin support; per-agent execution lock for concurrent safety
|
|
138
|
+
- `AgentManager` — multi-agent orchestration: sequential pipelines, collaborative tasks, and dependency-aware workflows with parallel batching and checkpoint/resume
|
|
139
|
+
- `ConversationMemory` — token-budgeted, pair-based conversation history shared by `Agent` (stateful mode) and `ChatSession`
|
|
140
|
+
- Native tool-calling for all backends (Ollama `tools=`, llama.cpp, OpenAI, Anthropic tool use) with multi-round execution and self-correction
|
|
141
|
+
- 16 built-in plugins covering files, web content, search, trading, and memory
|
|
142
|
+
- Distributed agent serving: `maki serve` exposes any agent over HTTP; `AgentProxy` consumes remote agents transparently
|
|
143
|
+
- Hardened HTTP connector: URL validation, private-address blocking, DNS pinning on the default path, typed error classification, and configurable timeouts (hosted-model traffic goes through the vendors' own SDKs)
|
|
144
|
+
- Fail-closed plugin security: every plugin declares `ALLOWED_METHODS`; destructive methods require explicit opt-in
|
|
145
|
+
- Explicit logging setup and a typed exception hierarchy
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## Installation
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
curl -fsSL https://raw.githubusercontent.com/BowlOfData/maki/main/install.sh | bash
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
This clones the repo into `~/.maki`, installs it into an isolated virtual environment, and symlinks the `maki` command into `~/.local/bin` (override with the `MAKI_INSTALL_DIR` / `MAKI_BIN_DIR` env vars). Re-run it any time to update to the latest `main`.
|
|
156
|
+
|
|
157
|
+
### From source
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
pip install -e .
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
For development tools:
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
pip install -e ".[dev]"
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
Some built-in plugins and backends rely on optional extras (defined in [pyproject.toml](pyproject.toml)):
|
|
170
|
+
|
|
171
|
+
- `maki-framework[web]` — `feedparser`, `readability-lxml`, `html2text` (web search / web-to-Markdown)
|
|
172
|
+
- `maki-framework[trends]` — `pytrends` (Google Trends)
|
|
173
|
+
- `maki-framework[alpaca]` — `alpaca-py` (market data, news, trading, streaming)
|
|
174
|
+
- `maki-framework[ftp]` — `paramiko` (FTP/SFTP)
|
|
175
|
+
- `maki-framework[gui]` — `PySide6` (desktop GUI)
|
|
176
|
+
- `maki-framework[openai]` — `openai` (OpenAI backend)
|
|
177
|
+
- `maki-framework[anthropic]` — `anthropic` (Anthropic backend)
|
|
178
|
+
- `maki-framework[openrouter]` — `openai` (OpenRouter backend, via its OpenAI-compatible API)
|
|
179
|
+
- `maki-framework[llamacpp]` — `openai` (llama.cpp backend, via the `llama serve` OpenAI-compatible API)
|
|
180
|
+
- `maki-framework[distributed]` — `fastapi`, `uvicorn`, `pyyaml` (agent server and proxies)
|
|
181
|
+
- `maki-framework[distributed-redis]` — `redis` (Redis workflow checkpoints)
|
|
182
|
+
|
|
183
|
+
Install everything with `pip install -e ".[all]"`.
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
## Configuration
|
|
188
|
+
|
|
189
|
+
Shared runtime defaults live in [maki/config.py](maki/config.py). All values are overridable via environment variables or a `.env` file (`python-dotenv` is supported).
|
|
190
|
+
|
|
191
|
+
| Variable | Description |
|
|
192
|
+
|---|---|
|
|
193
|
+
| `MAKI_OLLAMA_BASE_URL` | Full Ollama base URL |
|
|
194
|
+
| `MAKI_OLLAMA_HOST` | Ollama hostname |
|
|
195
|
+
| `MAKI_OLLAMA_PORT` | Ollama port |
|
|
196
|
+
| `MAKI_LLAMACPP_BASE_URL` | llama.cpp server URL (default `http://127.0.0.1:8080/v1`) |
|
|
197
|
+
| `MAKI_LLAMACPP_MODEL` | llama.cpp model name (default `local-model`; set it in router mode) |
|
|
198
|
+
| `LLAMACPP_API_KEY` | llama.cpp API key, only if the server was started with `--api-key` |
|
|
199
|
+
| `MAKI_DEFAULT_MODEL` | Default model name |
|
|
200
|
+
| `MAKI_DEFAULT_TEMPERATURE` | Sampling temperature |
|
|
201
|
+
| `MAKI_REQUEST_TIMEOUT` | Per-request timeout (seconds) |
|
|
202
|
+
| `MAKI_HTTP_TIMEOUT` | Low-level HTTP timeout |
|
|
203
|
+
| `MAKI_LOG_LEVEL` | Logging level |
|
|
204
|
+
| `MAKI_WEB_USER_AGENT` | User-agent string for web plugins |
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## Quick Start
|
|
209
|
+
|
|
210
|
+
### Basic request
|
|
211
|
+
|
|
212
|
+
```python
|
|
213
|
+
from maki import MakiLLama
|
|
214
|
+
|
|
215
|
+
llm = MakiLLama(model="gemma4:26b")
|
|
216
|
+
response = llm.chat("Explain recursion in one sentence.")
|
|
217
|
+
print(response.content)
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### Chat, streaming, and async
|
|
221
|
+
|
|
222
|
+
```python
|
|
223
|
+
import asyncio
|
|
224
|
+
from maki import MakiLLama
|
|
225
|
+
from maki.objects import GenerationConfig
|
|
226
|
+
|
|
227
|
+
config = GenerationConfig(temperature=0.7, max_tokens=512)
|
|
228
|
+
llm = MakiLLama(model="gemma4:26b", config=config)
|
|
229
|
+
|
|
230
|
+
reply = llm.chat("Give me three project naming ideas.")
|
|
231
|
+
print(reply.content)
|
|
232
|
+
|
|
233
|
+
for chunk in llm.stream("Write a short haiku about testing"):
|
|
234
|
+
print(chunk, end="", flush=True)
|
|
235
|
+
|
|
236
|
+
async def main():
|
|
237
|
+
response = await llm.async_chat("Summarize the benefits of type hints.")
|
|
238
|
+
print(response.content)
|
|
239
|
+
|
|
240
|
+
asyncio.run(main())
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### Stateful session
|
|
244
|
+
|
|
245
|
+
```python
|
|
246
|
+
from maki import MakiLLama
|
|
247
|
+
|
|
248
|
+
llm = MakiLLama(model="gemma4:26b")
|
|
249
|
+
session = llm.session(system="You are a concise engineering assistant.")
|
|
250
|
+
|
|
251
|
+
session.say("We are building a release checklist.")
|
|
252
|
+
response = session.say("What should we verify before publishing a Python package?")
|
|
253
|
+
print(response.content)
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
### Hosted backends
|
|
257
|
+
|
|
258
|
+
```python
|
|
259
|
+
from maki import MakiOpenAI, MakiAnthropic
|
|
260
|
+
|
|
261
|
+
# OpenAI
|
|
262
|
+
llm = MakiOpenAI(model="gpt-4o")
|
|
263
|
+
response = llm.chat("What is the capital of France?")
|
|
264
|
+
|
|
265
|
+
# Anthropic
|
|
266
|
+
llm = MakiAnthropic(model="claude-sonnet-4-5")
|
|
267
|
+
response = llm.chat("Summarize this code in one sentence.")
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
---
|
|
271
|
+
|
|
272
|
+
## Agents
|
|
273
|
+
|
|
274
|
+
### Basic agent
|
|
275
|
+
|
|
276
|
+
```python
|
|
277
|
+
from maki import MakiLLama
|
|
278
|
+
from maki.agents import Agent
|
|
279
|
+
|
|
280
|
+
llm = MakiLLama(model="gemma4:26b")
|
|
281
|
+
agent = Agent(
|
|
282
|
+
name="Reviewer",
|
|
283
|
+
maki_instance=llm,
|
|
284
|
+
role="code reviewer",
|
|
285
|
+
instructions="Focus on bugs, regressions, and missing validation.",
|
|
286
|
+
stateful=True,
|
|
287
|
+
)
|
|
288
|
+
|
|
289
|
+
result = agent.execute_task("Review this design: a plugin system with file access.")
|
|
290
|
+
print(result)
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
### Memory and reasoning helpers
|
|
294
|
+
|
|
295
|
+
```python
|
|
296
|
+
agent.remember("repo", "maki")
|
|
297
|
+
print(agent.recall("repo"))
|
|
298
|
+
|
|
299
|
+
steps = agent.think_step_by_step("How should we structure plugin validation?")
|
|
300
|
+
subtasks = agent.decompose_task("Prepare this repository for a public release")
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
### Streaming task execution
|
|
304
|
+
|
|
305
|
+
```python
|
|
306
|
+
for chunk in agent.stream_task("Draft a short changelog entry."):
|
|
307
|
+
print(chunk, end="", flush=True)
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
### Long-running tasks with `use_streaming`
|
|
311
|
+
|
|
312
|
+
By default, `execute_task` sends one blocking HTTP request. For tasks that exceed the configured timeout (default 120 s), set `use_streaming=True` — the timeout then applies per chunk rather than to the whole response.
|
|
313
|
+
|
|
314
|
+
```python
|
|
315
|
+
agent = Agent(
|
|
316
|
+
name="Ranker",
|
|
317
|
+
maki_instance=llm,
|
|
318
|
+
role="content ranker",
|
|
319
|
+
use_streaming=True,
|
|
320
|
+
)
|
|
321
|
+
|
|
322
|
+
result = agent.execute_task("Rank these 50 articles by relevance: ...")
|
|
323
|
+
print(result)
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
---
|
|
327
|
+
|
|
328
|
+
## Agent Manager and Workflows
|
|
329
|
+
|
|
330
|
+
`AgentManager` coordinates multiple agents and can run collaborative or dependency-aware workflows.
|
|
331
|
+
|
|
332
|
+
```python
|
|
333
|
+
from maki import MakiLLama
|
|
334
|
+
from maki.agents import AgentManager, WorkflowTask
|
|
335
|
+
|
|
336
|
+
llm = MakiLLama(model="gemma4:26b")
|
|
337
|
+
manager = AgentManager(llm)
|
|
338
|
+
|
|
339
|
+
manager.add_agent("Researcher", role="researcher")
|
|
340
|
+
manager.add_agent("Writer", role="writer")
|
|
341
|
+
|
|
342
|
+
workflow = [
|
|
343
|
+
WorkflowTask(
|
|
344
|
+
name="research",
|
|
345
|
+
agent="Researcher",
|
|
346
|
+
task="Find the main public-release risks for this repository.",
|
|
347
|
+
),
|
|
348
|
+
WorkflowTask(
|
|
349
|
+
name="summary",
|
|
350
|
+
agent="Writer",
|
|
351
|
+
task="Summarize the research into a release checklist.",
|
|
352
|
+
dependencies=["research"],
|
|
353
|
+
),
|
|
354
|
+
]
|
|
355
|
+
|
|
356
|
+
results = manager.run_workflow(workflow)
|
|
357
|
+
print(results["summary"]["result"])
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
Supported manager patterns:
|
|
361
|
+
|
|
362
|
+
| Method | Behaviour |
|
|
363
|
+
|---|---|
|
|
364
|
+
| `assign_task()` | Route a single task to one named agent |
|
|
365
|
+
| `coordinate_agents()` | Sequential multi-agent pipeline with optional synthesis step |
|
|
366
|
+
| `collaborative_task()` | All agents work on the same task independently |
|
|
367
|
+
| `run_workflow()` | Dependency-aware execution with retries and optional parallel batches |
|
|
368
|
+
|
|
369
|
+
---
|
|
370
|
+
|
|
371
|
+
## Distributed Layer
|
|
372
|
+
|
|
373
|
+
Serve any agent over HTTP with `maki serve`:
|
|
374
|
+
|
|
375
|
+
```bash
|
|
376
|
+
maki serve --config agent.yaml --host 127.0.0.1 --port 8100
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
```yaml
|
|
380
|
+
# agent.yaml
|
|
381
|
+
name: MyAgent
|
|
382
|
+
model: gemma4:26b
|
|
383
|
+
role: assistant
|
|
384
|
+
# backend: ollama | llamacpp | openai | anthropic | openrouter (default: ollama)
|
|
385
|
+
# base_url: http://127.0.0.1:8080/v1 # llamacpp only
|
|
386
|
+
plugins:
|
|
387
|
+
- web_search
|
|
388
|
+
- file_reader
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
Connect to a remote agent from another process:
|
|
392
|
+
|
|
393
|
+
```python
|
|
394
|
+
from maki.distributed.proxy import AgentProxy
|
|
395
|
+
|
|
396
|
+
agent = AgentProxy(name="MyAgent", base_url="http://127.0.0.1:8100")
|
|
397
|
+
result = agent.execute_task("Summarize the latest AI news.")
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
`DistributedAgentManager` lets you mix local and remote agents in the same workflow.
|
|
401
|
+
|
|
402
|
+
---
|
|
403
|
+
|
|
404
|
+
## Plugins
|
|
405
|
+
|
|
406
|
+
Built-in plugins are registered in [maki/plugins/\_\_init\_\_.py](maki/plugins/__init__.py):
|
|
407
|
+
|
|
408
|
+
| Plugin | Description | Extra |
|
|
409
|
+
|---|---|---|
|
|
410
|
+
| `directory_reader` | List and inspect directory contents | — |
|
|
411
|
+
| `file_reader` | Read files from disk | — |
|
|
412
|
+
| `file_writer` | Write files to disk | — |
|
|
413
|
+
| `json_reader` | Parse and query JSON files | — |
|
|
414
|
+
| `image_classifier` | Classify images via a local model | — |
|
|
415
|
+
| `ocr` | Extract text from images (not in the default registry; load via `plugin_path`) | — |
|
|
416
|
+
| `web_search` | RSS, HackerNews, Reddit, GitHub Trending, Lobste.rs | `web` |
|
|
417
|
+
| `web_to_md` | Fetch a URL and convert to Markdown | `web` |
|
|
418
|
+
| `provider_updates` | Fetch LLM provider release notes | `web` |
|
|
419
|
+
| `trend_search` | Google Trends queries | `trends` |
|
|
420
|
+
| `ftp_client` | FTP/SFTP file transfers | `ftp` |
|
|
421
|
+
| `alpaca_data` | Crypto, equity, and forex bar and quote data | `alpaca` |
|
|
422
|
+
| `alpaca_news` | Financial news from Alpaca and RSS | `alpaca` |
|
|
423
|
+
| `alpaca_trading` | Submit and manage Alpaca trades | `alpaca` |
|
|
424
|
+
| `alpaca_stream` | Live crypto data stream | `alpaca` |
|
|
425
|
+
| `obsidian_memory` | Persistent note-based memory (Obsidian vault) | — |
|
|
426
|
+
| `rag_memory` | Retrieval-augmented memory with pluggable vector backends | — |
|
|
427
|
+
|
|
428
|
+
### Loading a plugin in an agent
|
|
429
|
+
|
|
430
|
+
```python
|
|
431
|
+
from maki import MakiLLama
|
|
432
|
+
from maki.agents import Agent
|
|
433
|
+
|
|
434
|
+
llm = MakiLLama(model="gemma4:26b")
|
|
435
|
+
agent = Agent(name="ToolUser", maki_instance=llm, role="assistant")
|
|
436
|
+
agent.load_plugin("file_reader")
|
|
437
|
+
|
|
438
|
+
result = agent.execute_task(
|
|
439
|
+
"Read the first lines of README.md and summarize them.",
|
|
440
|
+
use_plugins=True,
|
|
441
|
+
)
|
|
442
|
+
print(result)
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
When `use_plugins=True` (or the backend supports native tool-calling), available plugin methods are advertised to the model and executed automatically. Destructive methods (file writes, trades, FTP deletes) require `Agent(allow_dangerous_tools=True)`.
|
|
446
|
+
|
|
447
|
+
---
|
|
448
|
+
|
|
449
|
+
## llama.cpp Backend
|
|
450
|
+
|
|
451
|
+
`MakiLlamaCpp` talks to a [llama.cpp](https://llama.app/docs/introduction) server, which runs GGUF models from Hugging Face or a local file. Install the extra and start a server:
|
|
452
|
+
|
|
453
|
+
```bash
|
|
454
|
+
pip install "maki-framework[llamacpp]"
|
|
455
|
+
llama serve -hf ggml-org/gemma-4-e4b-it-GGUF:Q4_0 # listens on http://127.0.0.1:8080
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
```python
|
|
459
|
+
from maki import MakiLlamaCpp
|
|
460
|
+
from maki.objects import GenerationConfig
|
|
461
|
+
|
|
462
|
+
llm = MakiLlamaCpp(config=GenerationConfig(temperature=0.7, top_k=40))
|
|
463
|
+
print(llm.health()) # False while the model is still loading
|
|
464
|
+
|
|
465
|
+
response = llm.chat("What is the capital of France?")
|
|
466
|
+
print(response.content)
|
|
467
|
+
print(response.reasoning) # thinking text from reasoning models, else None
|
|
468
|
+
|
|
469
|
+
for chunk in llm.stream("Tell me a joke"):
|
|
470
|
+
print(chunk, end="", flush=True)
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
- **Everything `MakiOpenAI` does** works unchanged: chat, streaming, async, vision (images as base64), sessions, and native tool calling with agents and plugins.
|
|
474
|
+
- **llama.cpp sampling settings** `top_k` and `repeat_penalty` from `GenerationConfig` are sent to the server.
|
|
475
|
+
- **Long generations:** `chat_collect()` (used by `Agent(use_streaming=True)`) streams internally, so the timeout applies per chunk instead of to the whole answer.
|
|
476
|
+
- **Router mode:** start `llama serve` without a model and pass the model name, e.g. `MakiLlamaCpp(model="ggml-org/gemma-3-4b-it-qat-GGUF:Q4_0")`. The server loads it on demand.
|
|
477
|
+
- **Other servers:** pass `base_url="http://192.168.1.20:8080/v1"` for a LAN host, and `api_key=` (or `LLAMACPP_API_KEY`) if it was started with `--api-key`.
|
|
478
|
+
|
|
479
|
+
Embeddings and reranking need a server started with `--embedding` or `--rerank`:
|
|
480
|
+
|
|
481
|
+
```python
|
|
482
|
+
from maki.plugins.rag_memory import RagMemory
|
|
483
|
+
|
|
484
|
+
embedder = MakiLlamaCpp() # llama serve -hf unsloth/embeddinggemma-300m-GGUF --embedding
|
|
485
|
+
rag = RagMemory(dsn="memory://", embedder=embedder.embed)
|
|
486
|
+
|
|
487
|
+
reranker = MakiLlamaCpp() # llama serve -m reranker.gguf --rerank
|
|
488
|
+
for hit in reranker.rerank("What is a panda?", ["hi", "The giant panda is a bear."], top_n=1):
|
|
489
|
+
print(hit["relevance_score"], hit["document"])
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
Chat requests go through the `openai` SDK; `health()`, `embed()` and `rerank()` go through Maki's connector, which allows loopback and LAN addresses for this operator-configured endpoint.
|
|
493
|
+
|
|
494
|
+
---
|
|
495
|
+
|
|
496
|
+
## HuggingFace Backend
|
|
497
|
+
|
|
498
|
+
`HFBackend` runs models directly via HuggingFace Transformers — no Ollama required.
|
|
499
|
+
|
|
500
|
+
`torch`, `transformers`, and `accelerate` are not installed with Maki (they are large and platform-specific), so install them first:
|
|
501
|
+
|
|
502
|
+
```bash
|
|
503
|
+
pip install torch transformers accelerate # add bitsandbytes for 4/8-bit quantization
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
```python
|
|
507
|
+
from maki import HFBackend
|
|
508
|
+
|
|
509
|
+
llm = HFBackend(model_id="mistralai/Mistral-7B-Instruct-v0.3", device="cuda")
|
|
510
|
+
response = llm.chat("Explain attention mechanisms.")
|
|
511
|
+
print(response.content)
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
Supports quantization (`load_in_4bit`, `load_in_8bit`) and device selection (`cpu`, `cuda`, `mps`; auto-detected when omitted). Remote model code is not executed unless you pass `trust_remote_code=True`.
|
|
515
|
+
|
|
516
|
+
---
|
|
517
|
+
|
|
518
|
+
## Architecture
|
|
519
|
+
|
|
520
|
+
<p align="center">
|
|
521
|
+
<img src="img/diagram.png" alt="Maki Architecture Diagram" width="900" />
|
|
522
|
+
</p>
|
|
523
|
+
|
|
524
|
+
The framework is organized into four layers on top of a shared infrastructure layer:
|
|
525
|
+
|
|
526
|
+
- **Public API** — `maki/__init__.py` lazy-loads all exports on first access
|
|
527
|
+
- **LLM Backends** — `MakiLLama`, `MakiOpenAI`, `MakiAnthropic`, `MakiOpenRouter`, `MakiLlamaCpp`, and `HFBackend` all implement the abstract `LLMBackend` contract
|
|
528
|
+
- **Agent System** — `Agent` composes `PluginHandler` and `ReasoningEngine` mixins; `AgentManager` orchestrates agents via `WorkflowTask` and `WorkflowState`
|
|
529
|
+
- **Distributed Layer** — `AgentServer` (FastAPI) exposes agents over HTTP; `AgentProxy` provides a remote-agent client with circuit-breaking; `DistributedAgentManager` mixes local and remote agents
|
|
530
|
+
- **Infrastructure** — `Connector` (hardened HTTP: URL validation, connect-time IP pinning by default), shared data classes, typed exceptions, runtime config, and structured logging
|
|
531
|
+
|
|
532
|
+
The Plugin System sits alongside the Agent layer: plugins are loaded on demand and invoked automatically when the LLM emits a `TOOL:` directive or via native tool-calling APIs (Ollama, OpenAI, Anthropic).
|
|
533
|
+
|
|
534
|
+
---
|
|
535
|
+
|
|
536
|
+
## Public API
|
|
537
|
+
|
|
538
|
+
Top-level imports exposed by `maki`:
|
|
539
|
+
|
|
540
|
+
- `MakiLLama`, `MakiOpenAI`, `MakiAnthropic`, `MakiOpenRouter`, `MakiLlamaCpp`, `HFBackend`
|
|
541
|
+
- `LLMBackend`, `BackendType`
|
|
542
|
+
- `Agent`, `AgentManager`
|
|
543
|
+
- `GenerationConfig`, `LLMResponse`, `Message`, `ToolCall`
|
|
544
|
+
- `ConversationMemory`, `RateLimiter`
|
|
545
|
+
- `Connector`, `Utils`
|
|
546
|
+
- `config`
|
|
547
|
+
|
|
548
|
+
All exports are lazy-loaded on first access.
|
|
549
|
+
|
|
550
|
+
---
|
|
551
|
+
|
|
552
|
+
## Desktop App
|
|
553
|
+
|
|
554
|
+
The repository includes a PySide6/QML desktop shell (requires `maki-framework[gui]`):
|
|
555
|
+
|
|
556
|
+
```bash
|
|
557
|
+
maki-gui
|
|
558
|
+
```
|
|
559
|
+
|
|
560
|
+
---
|
|
561
|
+
|
|
562
|
+
## Testing
|
|
563
|
+
|
|
564
|
+
```bash
|
|
565
|
+
pytest
|
|
566
|
+
```
|
|
567
|
+
|
|
568
|
+
900+ tests covering backends, agents, workflows, plugins, connectors, distributed layer, and security-related behaviour. Tests marked `@pytest.mark.network` (requiring live external services) are excluded by default; run them explicitly with `pytest -m network`.
|
|
569
|
+
|
|
570
|
+
---
|
|
571
|
+
|
|
572
|
+
## Contributing
|
|
573
|
+
|
|
574
|
+
Contributions are welcome: bug fixes, documentation improvements, new plugins, and feature suggestions all help move the project forward. Open an issue or submit a pull request on GitHub.
|
|
575
|
+
|
|
576
|
+
If you are interested in this line of research, consider joining [Bowl of Data](https://bowlofdata.net/), an open-source AI research community.
|
|
577
|
+
|
|
578
|
+
---
|
|
579
|
+
|
|
580
|
+
## License
|
|
581
|
+
|
|
582
|
+
[MIT](LICENSE)
|