noesium 0.1.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.
Files changed (91) hide show
  1. noesium-0.1.0/LICENSE +21 -0
  2. noesium-0.1.0/PKG-INFO +525 -0
  3. noesium-0.1.0/README.md +466 -0
  4. noesium-0.1.0/noesium/core/__init__.py +4 -0
  5. noesium-0.1.0/noesium/core/agent/__init__.py +14 -0
  6. noesium-0.1.0/noesium/core/agent/base.py +227 -0
  7. noesium-0.1.0/noesium/core/consts.py +6 -0
  8. noesium-0.1.0/noesium/core/goalith/conflict/conflict.py +104 -0
  9. noesium-0.1.0/noesium/core/goalith/conflict/detector.py +53 -0
  10. noesium-0.1.0/noesium/core/goalith/decomposer/__init__.py +6 -0
  11. noesium-0.1.0/noesium/core/goalith/decomposer/base.py +46 -0
  12. noesium-0.1.0/noesium/core/goalith/decomposer/callable_decomposer.py +65 -0
  13. noesium-0.1.0/noesium/core/goalith/decomposer/llm_decomposer.py +326 -0
  14. noesium-0.1.0/noesium/core/goalith/decomposer/prompts.py +140 -0
  15. noesium-0.1.0/noesium/core/goalith/decomposer/simple_decomposer.py +61 -0
  16. noesium-0.1.0/noesium/core/goalith/errors.py +22 -0
  17. noesium-0.1.0/noesium/core/goalith/goalgraph/graph.py +526 -0
  18. noesium-0.1.0/noesium/core/goalith/goalgraph/node.py +179 -0
  19. noesium-0.1.0/noesium/core/goalith/replanner/base.py +31 -0
  20. noesium-0.1.0/noesium/core/goalith/replanner/replanner.py +36 -0
  21. noesium-0.1.0/noesium/core/goalith/service.py +26 -0
  22. noesium-0.1.0/noesium/core/llm/__init__.py +154 -0
  23. noesium-0.1.0/noesium/core/llm/base.py +152 -0
  24. noesium-0.1.0/noesium/core/llm/litellm.py +528 -0
  25. noesium-0.1.0/noesium/core/llm/llamacpp.py +487 -0
  26. noesium-0.1.0/noesium/core/llm/message.py +184 -0
  27. noesium-0.1.0/noesium/core/llm/ollama.py +459 -0
  28. noesium-0.1.0/noesium/core/llm/openai.py +520 -0
  29. noesium-0.1.0/noesium/core/llm/openrouter.py +89 -0
  30. noesium-0.1.0/noesium/core/llm/prompt.py +551 -0
  31. noesium-0.1.0/noesium/core/memory/__init__.py +11 -0
  32. noesium-0.1.0/noesium/core/memory/base.py +464 -0
  33. noesium-0.1.0/noesium/core/memory/memu/__init__.py +24 -0
  34. noesium-0.1.0/noesium/core/memory/memu/config/__init__.py +26 -0
  35. noesium-0.1.0/noesium/core/memory/memu/config/activity/config.py +46 -0
  36. noesium-0.1.0/noesium/core/memory/memu/config/event/config.py +46 -0
  37. noesium-0.1.0/noesium/core/memory/memu/config/markdown_config.py +241 -0
  38. noesium-0.1.0/noesium/core/memory/memu/config/profile/config.py +48 -0
  39. noesium-0.1.0/noesium/core/memory/memu/llm_adapter.py +129 -0
  40. noesium-0.1.0/noesium/core/memory/memu/memory/__init__.py +31 -0
  41. noesium-0.1.0/noesium/core/memory/memu/memory/actions/__init__.py +40 -0
  42. noesium-0.1.0/noesium/core/memory/memu/memory/actions/add_activity_memory.py +299 -0
  43. noesium-0.1.0/noesium/core/memory/memu/memory/actions/base_action.py +342 -0
  44. noesium-0.1.0/noesium/core/memory/memu/memory/actions/cluster_memories.py +262 -0
  45. noesium-0.1.0/noesium/core/memory/memu/memory/actions/generate_suggestions.py +198 -0
  46. noesium-0.1.0/noesium/core/memory/memu/memory/actions/get_available_categories.py +66 -0
  47. noesium-0.1.0/noesium/core/memory/memu/memory/actions/link_related_memories.py +515 -0
  48. noesium-0.1.0/noesium/core/memory/memu/memory/actions/run_theory_of_mind.py +254 -0
  49. noesium-0.1.0/noesium/core/memory/memu/memory/actions/update_memory_with_suggestions.py +514 -0
  50. noesium-0.1.0/noesium/core/memory/memu/memory/embeddings.py +130 -0
  51. noesium-0.1.0/noesium/core/memory/memu/memory/file_manager.py +306 -0
  52. noesium-0.1.0/noesium/core/memory/memu/memory/memory_agent.py +578 -0
  53. noesium-0.1.0/noesium/core/memory/memu/memory/recall_agent.py +376 -0
  54. noesium-0.1.0/noesium/core/memory/memu/memory_store.py +628 -0
  55. noesium-0.1.0/noesium/core/memory/models.py +149 -0
  56. noesium-0.1.0/noesium/core/msgbus/__init__.py +12 -0
  57. noesium-0.1.0/noesium/core/msgbus/base.py +395 -0
  58. noesium-0.1.0/noesium/core/orchestrix/__init__.py +0 -0
  59. noesium-0.1.0/noesium/core/py.typed +0 -0
  60. noesium-0.1.0/noesium/core/routing/__init__.py +20 -0
  61. noesium-0.1.0/noesium/core/routing/base.py +66 -0
  62. noesium-0.1.0/noesium/core/routing/router.py +241 -0
  63. noesium-0.1.0/noesium/core/routing/strategies/__init__.py +9 -0
  64. noesium-0.1.0/noesium/core/routing/strategies/dynamic_complexity.py +361 -0
  65. noesium-0.1.0/noesium/core/routing/strategies/self_assessment.py +147 -0
  66. noesium-0.1.0/noesium/core/routing/types.py +38 -0
  67. noesium-0.1.0/noesium/core/toolify/__init__.py +39 -0
  68. noesium-0.1.0/noesium/core/toolify/base.py +360 -0
  69. noesium-0.1.0/noesium/core/toolify/config.py +138 -0
  70. noesium-0.1.0/noesium/core/toolify/mcp_integration.py +275 -0
  71. noesium-0.1.0/noesium/core/toolify/registry.py +214 -0
  72. noesium-0.1.0/noesium/core/toolify/toolkits/__init__.py +1 -0
  73. noesium-0.1.0/noesium/core/tracing/__init__.py +37 -0
  74. noesium-0.1.0/noesium/core/tracing/langgraph_hooks.py +308 -0
  75. noesium-0.1.0/noesium/core/tracing/opik_tracing.py +144 -0
  76. noesium-0.1.0/noesium/core/tracing/token_tracker.py +166 -0
  77. noesium-0.1.0/noesium/core/utils/__init__.py +10 -0
  78. noesium-0.1.0/noesium/core/utils/logging.py +172 -0
  79. noesium-0.1.0/noesium/core/utils/statistics.py +12 -0
  80. noesium-0.1.0/noesium/core/utils/typing.py +17 -0
  81. noesium-0.1.0/noesium/core/vector_store/__init__.py +79 -0
  82. noesium-0.1.0/noesium/core/vector_store/base.py +94 -0
  83. noesium-0.1.0/noesium/core/vector_store/pgvector.py +304 -0
  84. noesium-0.1.0/noesium/core/vector_store/weaviate.py +383 -0
  85. noesium-0.1.0/noesium.egg-info/PKG-INFO +525 -0
  86. noesium-0.1.0/noesium.egg-info/SOURCES.txt +89 -0
  87. noesium-0.1.0/noesium.egg-info/dependency_links.txt +1 -0
  88. noesium-0.1.0/noesium.egg-info/requires.txt +38 -0
  89. noesium-0.1.0/noesium.egg-info/top_level.txt +1 -0
  90. noesium-0.1.0/pyproject.toml +118 -0
  91. noesium-0.1.0/setup.cfg +4 -0
noesium-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Xiaming Chen
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.
noesium-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,525 @@
1
+ Metadata-Version: 2.4
2
+ Name: noesium
3
+ Version: 0.1.0
4
+ Summary: Towards a cognitive agentic framework
5
+ Author-email: Xiaming Chen <chenxm35@gmail.com>
6
+ Maintainer-email: Xiaming Chen <chenxm35@gmail.com>
7
+ License-Expression: MIT
8
+ Project-URL: Homepage, https://github.com/mirasoth/noesium
9
+ Project-URL: Repository, https://github.com/mirasoth/noesium
10
+ Keywords: agents,multi-agent system,cognition,artificial intelligence
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
18
+ Requires-Python: >=3.11
19
+ Description-Content-Type: text/markdown
20
+ License-File: LICENSE
21
+ Requires-Dist: pydantic>=2.0.0
22
+ Requires-Dist: requests>=2.31.0
23
+ Requires-Dist: python-dotenv>=1.1.1
24
+ Requires-Dist: colorlog>=6.8.0
25
+ Requires-Dist: typing-extensions>=4.8.0
26
+ Requires-Dist: deprecated>=1.2.18
27
+ Requires-Dist: bubus>=1.5.6
28
+ Requires-Dist: openai>=1.0.0
29
+ Requires-Dist: instructor>=1.10.0
30
+ Requires-Dist: google-genai>=1.5.0
31
+ Requires-Dist: litellm>=1.0.0
32
+ Requires-Dist: ollama>=0.5.3
33
+ Requires-Dist: huggingface-hub>=0.34.4
34
+ Requires-Dist: llama-cpp-python>=0.3.16
35
+ Requires-Dist: langchain-core>=0.3.72
36
+ Requires-Dist: langchain-text-splitters>=0.3.0
37
+ Requires-Dist: langchain-ollama>=0.2.0
38
+ Requires-Dist: langgraph>=0.5.4
39
+ Requires-Dist: networkx>=3.5
40
+ Requires-Dist: mcp>=1.0.0
41
+ Requires-Dist: protobuf<6,>=5
42
+ Requires-Dist: weaviate-client<5,>=4
43
+ Requires-Dist: psycopg2>=2.9.10
44
+ Requires-Dist: psycopg2-binary>=2.9.0
45
+ Provides-Extra: dev
46
+ Requires-Dist: pytest<9,>=8.2; extra == "dev"
47
+ Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
48
+ Requires-Dist: pytest-asyncio>=1.1.0; extra == "dev"
49
+ Requires-Dist: pytest-tornasync>=0.6.0.post2; extra == "dev"
50
+ Requires-Dist: pytest-trio>=0.8.0; extra == "dev"
51
+ Requires-Dist: pytest-twisted>=1.14.3; extra == "dev"
52
+ Requires-Dist: twisted>=25.5.0; extra == "dev"
53
+ Requires-Dist: black>=23.0.0; extra == "dev"
54
+ Requires-Dist: isort>=5.12.0; extra == "dev"
55
+ Requires-Dist: flake8>=7.3.0; extra == "dev"
56
+ Requires-Dist: autoflake>=2.3.1; extra == "dev"
57
+ Requires-Dist: pillow>=11.3.0; extra == "dev"
58
+ Dynamic: license-file
59
+
60
+ # Cogents-core
61
+
62
+ [![CI](https://github.com/mirasoth/noesium/actions/workflows/ci.yml/badge.svg)](https://github.com/mirasoth/noesium/actions/workflows/ci.yml)
63
+ [![PyPI version](https://img.shields.io/pypi/v/noesium.svg)](https://pypi.org/project/noesium/)
64
+ [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/mirasoth/noesium)
65
+
66
+ This is part of [Project Cogents](https://www.xiaming.site/2025/08/30/project-cogents/), an initiative to develop a computation-driven, cognitive agentic system. This repo contains the foundational abstractions (Agent, Memory, Tool, Goal, Orchestration, and more) along with essential modules such as LLM clients, logging, message buses, model routing, and observability. For the underlying philosophy, refer to my talk on MAS ([link](https://github.com/mirasoth/mas-talk-2508/blob/master/mas-talk-xmingc.pdf)).
67
+
68
+ ## Installation
69
+
70
+ ```bash
71
+ pip install -U noesium
72
+ ```
73
+
74
+ ## Core Modules
75
+
76
+ Noesium offers a comprehensive set of modules for creating intelligent agent-based applications:
77
+
78
+ ### LLM Integration & Management (`noesium.core.llm`)
79
+ - **Multi-model support**: OpenAI, OpenRouter, Ollama, LlamaCPP, and LiteLLM
80
+ - **Advanced routing**: Dynamic complexity-based and self-assessment routing strategies
81
+ - **Tracing & monitoring**: Built-in token tracking and Opik tracing integration
82
+ - **Extensible architecture**: Easy to add new LLM providers
83
+
84
+ ### Goal Management & Planning (`noesium.core.goalith`) - *In Development*
85
+ - **Goal decomposition**: LLM-based, callable, and simple goal decomposition strategies
86
+ - **Graph-based structure**: DAG-based goal management with dependencies
87
+ - **Node management**: Goal, subgoal, and task node creation and tracking
88
+ - **Conflict detection**: Framework for automated goal conflict identification (planned)
89
+ - **Replanning**: Dynamic goal replanning capabilities (planned)
90
+
91
+ ### Tool Management (`noesium.core.toolify`)
92
+ - **Tool registry**: Centralized tool registration and management
93
+ - **MCP integration**: Model Context Protocol support for tool discovery
94
+ - **Execution engine**: Robust tool execution with error handling
95
+ - **Toolkit system**: Organized tool collections and configurations
96
+
97
+ ### Memory Management (`noesium.core.memory`)
98
+ - **MemU integration**: Advanced memory agent with categorization
99
+ - **Embedding support**: Vector-based memory retrieval and linking
100
+ - **Multi-category storage**: Activity, event, and profile memory types
101
+ - **Memory linking**: Automatic relationship discovery between memories
102
+
103
+ ### Vector Storage (`noesium.core.vector_store`)
104
+ - **PGVector support**: PostgreSQL with pgvector extension
105
+ - **Weaviate integration**: Cloud-native vector database
106
+ - **Semantic search**: Embedding-based document retrieval
107
+ - **Flexible indexing**: HNSW and DiskANN indexing strategies
108
+
109
+ ### Message Bus (`noesium.core.msgbus`)
110
+ - **Event-driven architecture**: Inter-component communication
111
+ - **Watchdog patterns**: Monitoring and reactive behaviors
112
+ - **Flexible routing**: Message filtering and delivery
113
+
114
+ ### Routing & Tracing (`noesium.core.routing`, `noesium.core.tracing`)
115
+ - **Smart routing**: Dynamic model selection based on complexity
116
+ - **Token tracking**: Comprehensive usage monitoring
117
+ - **Opik integration**: Production-ready observability
118
+ - **LangGraph hooks**: Workflow tracing and debugging
119
+
120
+ ## Project Structure
121
+
122
+ ```
123
+ noesium/core/
124
+ ├── agent/ # Base agent classes and models
125
+ ├── goalith/ # Goal management and planning system
126
+ │ ├── decomposer/ # Goal decomposition strategies
127
+ │ ├── goalgraph/ # Graph data structures
128
+ │ ├── conflict/ # Conflict detection
129
+ │ └── replanner/ # Dynamic replanning
130
+ ├── llm/ # LLM provider implementations
131
+ ├── memory/ # Memory management system
132
+ │ └── memu/ # MemU memory agent integration
133
+ ├── toolify/ # Tool management and execution
134
+ ├── vector_store/ # Vector database integrations
135
+ ├── msgbus/ # Message bus system
136
+ ├── routing/ # LLM routing strategies
137
+ ├── tracing/ # Token tracking and observability
138
+ └── utils/ # Utilities and logging
139
+ ```
140
+
141
+ ## Quick Start
142
+
143
+ ### 1. LLM Client Usage
144
+
145
+ ```python
146
+ from noesium.core.llm import get_llm_client
147
+
148
+ # OpenAI/OpenRouter providers
149
+ client = get_llm_client(provider="openai", api_key="sk-...")
150
+ client = get_llm_client(provider="openrouter", api_key="sk-...")
151
+
152
+ # Local providers
153
+ client = get_llm_client(provider="ollama", base_url="http://localhost:11434")
154
+ client = get_llm_client(provider="llamacpp", model_path="/path/to/model.gguf")
155
+
156
+ # Basic chat completion
157
+ response = client.completion([
158
+ {"role": "user", "content": "Hello!"}
159
+ ])
160
+
161
+ # Structured output (requires structured_output=True)
162
+ from pydantic import BaseModel
163
+
164
+ class Response(BaseModel):
165
+ answer: str
166
+ confidence: float
167
+
168
+ client = get_llm_client(provider="openai", structured_output=True)
169
+ result = client.structured_completion(messages, Response)
170
+ ```
171
+
172
+ ### 2. Goal Management with Goalith
173
+
174
+ **Note**: The Goalith goal management system is currently under development. The core components are available but the full service integration is not yet complete.
175
+
176
+ ```python
177
+ # Basic goal node creation and management
178
+ from noesium.core.goalith.goalgraph.node import GoalNode, NodeStatus
179
+ from noesium.core.goalith.goalgraph.graph import GoalGraph
180
+ from noesium.core.goalith.decomposer import LLMDecomposer
181
+
182
+ # Create a goal node
183
+ goal_node = GoalNode(
184
+ description="Plan and execute a product launch",
185
+ priority=8.0,
186
+ context={
187
+ "budget": "$50,000",
188
+ "timeline": "3 months",
189
+ "target_audience": "young professionals"
190
+ },
191
+ tags=["product", "launch", "marketing"]
192
+ )
193
+
194
+ # Create goal graph for management
195
+ graph = GoalGraph()
196
+ graph.add_node(goal_node)
197
+
198
+ # Use LLM decomposer directly
199
+ decomposer = LLMDecomposer()
200
+ subgoals = decomposer.decompose(goal_node, context={
201
+ "team_size": "5 people",
202
+ "experience_level": "intermediate"
203
+ })
204
+
205
+ print(f"Goal: {goal_node.description}")
206
+ print(f"Status: {goal_node.status}")
207
+ print(f"Generated {len(subgoals)} subgoals")
208
+ ```
209
+
210
+ ### 3. Memory Management
211
+
212
+ ```python
213
+ from noesium.core.memory.memu import MemoryAgent
214
+
215
+ # Initialize memory agent
216
+ memory_agent = MemoryAgent(
217
+ agent_id="my_agent",
218
+ user_id="user123",
219
+ memory_dir="/tmp/memory_storage",
220
+ enable_embeddings=True
221
+ )
222
+
223
+ # Add activity memory
224
+ activity_content = """
225
+ USER: Hi, I'm Sarah and I work as a software engineer.
226
+ ASSISTANT: Nice to meet you Sarah! What kind of projects do you work on?
227
+ USER: I mainly work on web applications using Python and React.
228
+ """
229
+
230
+ result = memory_agent.call_function(
231
+ "add_activity_memory",
232
+ {
233
+ "character_name": "Sarah",
234
+ "content": activity_content
235
+ }
236
+ )
237
+
238
+ # Generate memory suggestions
239
+ if result.get("success"):
240
+ memory_items = result.get("memory_items", [])
241
+ suggestions = memory_agent.call_function(
242
+ "generate_memory_suggestions",
243
+ {
244
+ "character_name": "Sarah",
245
+ "new_memory_items": memory_items
246
+ }
247
+ )
248
+ ```
249
+
250
+ ### 4. Vector Store Operations
251
+
252
+ ```python
253
+ from noesium.core.vector_store import PGVectorStore
254
+ from noesium.core.llm import get_llm_client
255
+
256
+ # Initialize vector store
257
+ vector_store = PGVectorStore(
258
+ collection_name="my_documents",
259
+ embedding_model_dims=768,
260
+ dbname="vectordb",
261
+ user="postgres",
262
+ password="postgres",
263
+ host="localhost",
264
+ port=5432
265
+ )
266
+
267
+ # Initialize embedding client
268
+ embed_client = get_llm_client(provider="ollama", embed_model="nomic-embed-text")
269
+
270
+ # Prepare documents
271
+ documents = [
272
+ {
273
+ "id": "doc1",
274
+ "content": "Machine learning is a subset of AI...",
275
+ "metadata": {"category": "AI", "type": "definition"}
276
+ }
277
+ ]
278
+
279
+ # Generate embeddings and store
280
+ vectors = []
281
+ payloads = []
282
+ ids = []
283
+
284
+ for doc in documents:
285
+ embedding = embed_client.embed(doc["content"])
286
+ vectors.append(embedding)
287
+ payloads.append(doc["metadata"])
288
+ ids.append(doc["id"])
289
+
290
+ # Insert into vector store
291
+ vector_store.insert(vectors=vectors, payloads=payloads, ids=ids)
292
+
293
+ # Search
294
+ query = "What is artificial intelligence?"
295
+ query_embedding = embed_client.embed(query)
296
+ results = vector_store.search(query=query, vectors=query_embedding, limit=5)
297
+ ```
298
+
299
+ ### 5. Tool Management
300
+
301
+ ```python
302
+ from noesium.core.toolify import BaseToolkit, ToolkitConfig, ToolkitRegistry, register_toolkit
303
+ from typing import Dict, Callable
304
+
305
+ # Create a custom toolkit using decorator
306
+ @register_toolkit("calculator")
307
+ class CalculatorToolkit(BaseToolkit):
308
+ def get_tools_map(self) -> Dict[str, Callable]:
309
+ return {
310
+ "add": self.add,
311
+ "multiply": self.multiply
312
+ }
313
+
314
+ def add(self, a: float, b: float) -> float:
315
+ """Add two numbers."""
316
+ return a + b
317
+
318
+ def multiply(self, a: float, b: float) -> float:
319
+ """Multiply two numbers."""
320
+ return a * b
321
+
322
+ # Alternative: Manual registration
323
+ config = ToolkitConfig(name="calculator", description="Basic math operations")
324
+ ToolkitRegistry.register("calculator", CalculatorToolkit)
325
+
326
+ # Create and use toolkit
327
+ calculator = ToolkitRegistry.create_toolkit("calculator", config)
328
+ result = calculator.call_tool("add", a=5, b=3)
329
+ print(f"5 + 3 = {result}")
330
+ ```
331
+
332
+ ### 6. Message Bus and Events
333
+
334
+ ```python
335
+ from noesium.core.msgbus import EventBus, BaseEvent, BaseWatchdog
336
+
337
+ # Define custom event
338
+ class TaskCompleted(BaseEvent):
339
+ def __init__(self, task_id: str, result: str):
340
+ super().__init__()
341
+ self.task_id = task_id
342
+ self.result = result
343
+
344
+ # Create event bus
345
+ bus = EventBus()
346
+
347
+ # Define watchdog
348
+ class TaskWatchdog(BaseWatchdog):
349
+ def handle_event(self, event: BaseEvent):
350
+ if isinstance(event, TaskCompleted):
351
+ print(f"Task {event.task_id} completed with result: {event.result}")
352
+
353
+ # Register watchdog and publish event
354
+ watchdog = TaskWatchdog()
355
+ bus.register_watchdog(watchdog)
356
+ bus.publish(TaskCompleted("task_1", "success"))
357
+ ```
358
+
359
+ ### 7. Token Tracking and Tracing
360
+
361
+ ```python
362
+ from noesium.core.tracing import get_token_tracker
363
+ from noesium.core.llm import get_llm_client
364
+
365
+ # Initialize client and tracker
366
+ client = get_llm_client(provider="openai")
367
+ tracker = get_token_tracker()
368
+
369
+ # Reset tracker
370
+ tracker.reset()
371
+
372
+ # Make LLM calls (automatically tracked)
373
+ response1 = client.completion([{"role": "user", "content": "Hello"}])
374
+ response2 = client.completion([{"role": "user", "content": "How are you?"}])
375
+
376
+ # Get usage statistics
377
+ stats = tracker.get_stats()
378
+ print(f"Total tokens: {stats['total_tokens']}")
379
+ print(f"Total calls: {stats['total_calls']}")
380
+ print(f"Average tokens per call: {stats.get('avg_tokens_per_call', 0)}")
381
+ ```
382
+
383
+ ## Environment Variables
384
+
385
+ Set these environment variables for different providers:
386
+
387
+ ```bash
388
+ # Default LLM provider
389
+ export COGENTS_LLM_PROVIDER="openai"
390
+
391
+ # OpenAI
392
+ export OPENAI_API_KEY="sk-..."
393
+
394
+ # OpenRouter
395
+ export OPENROUTER_API_KEY="sk-..."
396
+
397
+ # LlamaCPP
398
+ export LLAMACPP_MODEL_PATH="/path/to/model.gguf"
399
+
400
+ # Ollama
401
+ export OLLAMA_BASE_URL="http://localhost:11434"
402
+
403
+ # PostgreSQL (for vector store)
404
+ export POSTGRES_HOST="localhost"
405
+ export POSTGRES_PORT="5432"
406
+ export POSTGRES_DB="vectordb"
407
+ export POSTGRES_USER="postgres"
408
+ export POSTGRES_PASSWORD="postgres"
409
+ ```
410
+
411
+ ## Advanced Usage
412
+
413
+ ### Custom Goal Decomposer
414
+
415
+ ```python
416
+ from noesium.core.goalith.decomposer.base import GoalDecomposer
417
+ from noesium.core.goalith.goalgraph.node import GoalNode
418
+ from typing import List, Dict, Any, Optional
419
+ import copy
420
+
421
+ class CustomDecomposer(GoalDecomposer):
422
+ @property
423
+ def name(self) -> str:
424
+ return "custom_decomposer"
425
+
426
+ def decompose(self, goal_node: GoalNode, context: Optional[Dict[str, Any]] = None) -> List[GoalNode]:
427
+ # Custom decomposition logic
428
+ subtasks = [
429
+ "Research requirements",
430
+ "Design solution",
431
+ "Implement features",
432
+ "Test and deploy"
433
+ ]
434
+
435
+ nodes = []
436
+ for i, subtask in enumerate(subtasks):
437
+ # Deep copy context to avoid shared references
438
+ context_copy = copy.deepcopy(goal_node.context) if goal_node.context else {}
439
+
440
+ node = GoalNode(
441
+ description=subtask,
442
+ parent=goal_node.id,
443
+ priority=goal_node.priority - i * 0.1,
444
+ context=context_copy,
445
+ tags=goal_node.tags.copy() if goal_node.tags else [],
446
+ decomposer_name=self.name
447
+ )
448
+ nodes.append(node)
449
+
450
+ return nodes
451
+
452
+ # Use the decomposer directly
453
+ custom_decomposer = CustomDecomposer()
454
+ goal_node = GoalNode(description="Build a web application")
455
+ subgoals = custom_decomposer.decompose(goal_node)
456
+ ```
457
+
458
+ ### LLM Routing Strategies
459
+
460
+ ```python
461
+ from noesium.core.routing import ModelRouter, DynamicComplexityStrategy
462
+ from noesium.core.llm import get_llm_client
463
+
464
+ # Create a lite client for complexity assessment
465
+ lite_client = get_llm_client(provider="ollama", chat_model="llama3.2:1b")
466
+
467
+ # Create router with dynamic complexity strategy
468
+ router = ModelRouter(
469
+ strategy="dynamic_complexity",
470
+ lite_client=lite_client,
471
+ strategy_config={
472
+ "complexity_threshold_low": 0.3,
473
+ "complexity_threshold_high": 0.7
474
+ }
475
+ )
476
+
477
+ # Route queries to get tier recommendations
478
+ simple_query = "What is 2+2?"
479
+ result = router.route(simple_query)
480
+ print(f"Query: {simple_query}")
481
+ print(f"Recommended tier: {result.tier}") # Likely ModelTier.LITE
482
+ print(f"Confidence: {result.confidence}")
483
+
484
+ complex_query = "Explain quantum computing and its applications"
485
+ result = router.route(complex_query)
486
+ print(f"Query: {complex_query}")
487
+ print(f"Recommended tier: {result.tier}") # Likely ModelTier.POWER
488
+ print(f"Confidence: {result.confidence}")
489
+
490
+ # Get recommended model configuration
491
+ routing_result, model_config = router.route_and_configure(complex_query)
492
+ print(f"Recommended config: {model_config}")
493
+ ```
494
+
495
+ ## Examples
496
+
497
+ Check the `examples/` directory for comprehensive usage examples:
498
+
499
+ - **LLM Examples**: `examples/llm/` - OpenAI, Ollama, LlamaCPP, token tracking
500
+ - **Goal Management**: `examples/goals/` - Goal decomposition and planning
501
+ - **Memory Examples**: `examples/memory/` - Memory agent operations
502
+ - **Vector Store**: `examples/vector_store/` - PGVector and Weaviate usage
503
+ - **Message Bus**: `examples/msgbus/` - Event-driven patterns
504
+ - **Tools**: Various toolkit implementations
505
+
506
+ ## Development
507
+
508
+ ```bash
509
+ # Install development dependencies
510
+ make install
511
+
512
+ # Run tests
513
+ make test
514
+
515
+ # Run specific test categories
516
+ make test-unit # Unit tests only
517
+ make test-integration # Integration tests only
518
+
519
+ # Format code
520
+ make format
521
+ ```
522
+
523
+ ## License
524
+
525
+ MIT License - see [LICENSE](LICENSE) file for details.