mojentic 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (247) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +459 -0
  3. package/dist/agents/async-aggregator-agent.d.ts +101 -0
  4. package/dist/agents/async-aggregator-agent.d.ts.map +1 -0
  5. package/dist/agents/async-aggregator-agent.js +160 -0
  6. package/dist/agents/async-aggregator-agent.js.map +1 -0
  7. package/dist/agents/async-dispatcher.d.ts +98 -0
  8. package/dist/agents/async-dispatcher.d.ts.map +1 -0
  9. package/dist/agents/async-dispatcher.js +173 -0
  10. package/dist/agents/async-dispatcher.js.map +1 -0
  11. package/dist/agents/async-llm-agent-with-memory.d.ts +95 -0
  12. package/dist/agents/async-llm-agent-with-memory.d.ts.map +1 -0
  13. package/dist/agents/async-llm-agent-with-memory.js +136 -0
  14. package/dist/agents/async-llm-agent-with-memory.js.map +1 -0
  15. package/dist/agents/async-llm-agent.d.ts +85 -0
  16. package/dist/agents/async-llm-agent.d.ts.map +1 -0
  17. package/dist/agents/async-llm-agent.js +87 -0
  18. package/dist/agents/async-llm-agent.js.map +1 -0
  19. package/dist/agents/base-agent.d.ts +59 -0
  20. package/dist/agents/base-agent.d.ts.map +1 -0
  21. package/dist/agents/base-agent.js +24 -0
  22. package/dist/agents/base-agent.js.map +1 -0
  23. package/dist/agents/base-async-agent.d.ts +42 -0
  24. package/dist/agents/base-async-agent.d.ts.map +1 -0
  25. package/dist/agents/base-async-agent.js +6 -0
  26. package/dist/agents/base-async-agent.js.map +1 -0
  27. package/dist/agents/event.d.ts +26 -0
  28. package/dist/agents/event.d.ts.map +1 -0
  29. package/dist/agents/event.js +13 -0
  30. package/dist/agents/event.js.map +1 -0
  31. package/dist/agents/index.d.ts +14 -0
  32. package/dist/agents/index.d.ts.map +1 -0
  33. package/dist/agents/index.js +30 -0
  34. package/dist/agents/index.js.map +1 -0
  35. package/dist/agents/iterative-problem-solver.d.ts +83 -0
  36. package/dist/agents/iterative-problem-solver.d.ts.map +1 -0
  37. package/dist/agents/iterative-problem-solver.js +120 -0
  38. package/dist/agents/iterative-problem-solver.js.map +1 -0
  39. package/dist/agents/router.d.ts +44 -0
  40. package/dist/agents/router.d.ts.map +1 -0
  41. package/dist/agents/router.js +53 -0
  42. package/dist/agents/router.js.map +1 -0
  43. package/dist/agents/simple-recursive-agent.d.ts +182 -0
  44. package/dist/agents/simple-recursive-agent.d.ts.map +1 -0
  45. package/dist/agents/simple-recursive-agent.js +272 -0
  46. package/dist/agents/simple-recursive-agent.js.map +1 -0
  47. package/dist/context/index.d.ts +5 -0
  48. package/dist/context/index.d.ts.map +1 -0
  49. package/dist/context/index.js +21 -0
  50. package/dist/context/index.js.map +1 -0
  51. package/dist/context/shared-working-memory.d.ts +76 -0
  52. package/dist/context/shared-working-memory.d.ts.map +1 -0
  53. package/dist/context/shared-working-memory.js +121 -0
  54. package/dist/context/shared-working-memory.js.map +1 -0
  55. package/dist/error.d.ts +93 -0
  56. package/dist/error.d.ts.map +1 -0
  57. package/dist/error.js +149 -0
  58. package/dist/error.js.map +1 -0
  59. package/dist/examples/react/decisioning-agent.d.ts +48 -0
  60. package/dist/examples/react/decisioning-agent.d.ts.map +1 -0
  61. package/dist/examples/react/decisioning-agent.js +204 -0
  62. package/dist/examples/react/decisioning-agent.js.map +1 -0
  63. package/dist/examples/react/events.d.ts +77 -0
  64. package/dist/examples/react/events.d.ts.map +1 -0
  65. package/dist/examples/react/events.js +9 -0
  66. package/dist/examples/react/events.js.map +1 -0
  67. package/dist/examples/react/formatters.d.ts +23 -0
  68. package/dist/examples/react/formatters.d.ts.map +1 -0
  69. package/dist/examples/react/formatters.js +68 -0
  70. package/dist/examples/react/formatters.js.map +1 -0
  71. package/dist/examples/react/index.d.ts +12 -0
  72. package/dist/examples/react/index.d.ts.map +1 -0
  73. package/dist/examples/react/index.js +28 -0
  74. package/dist/examples/react/index.js.map +1 -0
  75. package/dist/examples/react/models.d.ts +57 -0
  76. package/dist/examples/react/models.d.ts.map +1 -0
  77. package/dist/examples/react/models.js +19 -0
  78. package/dist/examples/react/models.js.map +1 -0
  79. package/dist/examples/react/output-agent.d.ts +23 -0
  80. package/dist/examples/react/output-agent.d.ts.map +1 -0
  81. package/dist/examples/react/output-agent.js +28 -0
  82. package/dist/examples/react/output-agent.js.map +1 -0
  83. package/dist/examples/react/summarization-agent.d.ts +46 -0
  84. package/dist/examples/react/summarization-agent.d.ts.map +1 -0
  85. package/dist/examples/react/summarization-agent.js +102 -0
  86. package/dist/examples/react/summarization-agent.js.map +1 -0
  87. package/dist/examples/react/thinking-agent.d.ts +47 -0
  88. package/dist/examples/react/thinking-agent.d.ts.map +1 -0
  89. package/dist/examples/react/thinking-agent.js +127 -0
  90. package/dist/examples/react/thinking-agent.js.map +1 -0
  91. package/dist/examples/react/tool-call-agent.d.ts +25 -0
  92. package/dist/examples/react/tool-call-agent.d.ts.map +1 -0
  93. package/dist/examples/react/tool-call-agent.js +83 -0
  94. package/dist/examples/react/tool-call-agent.js.map +1 -0
  95. package/dist/index.d.ts +10 -0
  96. package/dist/index.d.ts.map +1 -0
  97. package/dist/index.js +28 -0
  98. package/dist/index.js.map +1 -0
  99. package/dist/llm/agent.d.ts +68 -0
  100. package/dist/llm/agent.d.ts.map +1 -0
  101. package/dist/llm/agent.js +85 -0
  102. package/dist/llm/agent.js.map +1 -0
  103. package/dist/llm/broker.d.ts +150 -0
  104. package/dist/llm/broker.d.ts.map +1 -0
  105. package/dist/llm/broker.js +355 -0
  106. package/dist/llm/broker.js.map +1 -0
  107. package/dist/llm/chat-session.d.ts +98 -0
  108. package/dist/llm/chat-session.d.ts.map +1 -0
  109. package/dist/llm/chat-session.js +156 -0
  110. package/dist/llm/chat-session.js.map +1 -0
  111. package/dist/llm/gateway.d.ts +28 -0
  112. package/dist/llm/gateway.d.ts.map +1 -0
  113. package/dist/llm/gateway.js +6 -0
  114. package/dist/llm/gateway.js.map +1 -0
  115. package/dist/llm/gateways/index.d.ts +9 -0
  116. package/dist/llm/gateways/index.d.ts.map +1 -0
  117. package/dist/llm/gateways/index.js +25 -0
  118. package/dist/llm/gateways/index.js.map +1 -0
  119. package/dist/llm/gateways/ollama.d.ts +30 -0
  120. package/dist/llm/gateways/ollama.d.ts.map +1 -0
  121. package/dist/llm/gateways/ollama.js +322 -0
  122. package/dist/llm/gateways/ollama.js.map +1 -0
  123. package/dist/llm/gateways/openai-messages-adapter.d.ts +29 -0
  124. package/dist/llm/gateways/openai-messages-adapter.d.ts.map +1 -0
  125. package/dist/llm/gateways/openai-messages-adapter.js +188 -0
  126. package/dist/llm/gateways/openai-messages-adapter.js.map +1 -0
  127. package/dist/llm/gateways/openai-model-registry.d.ts +82 -0
  128. package/dist/llm/gateways/openai-model-registry.d.ts.map +1 -0
  129. package/dist/llm/gateways/openai-model-registry.js +352 -0
  130. package/dist/llm/gateways/openai-model-registry.js.map +1 -0
  131. package/dist/llm/gateways/openai.d.ts +40 -0
  132. package/dist/llm/gateways/openai.d.ts.map +1 -0
  133. package/dist/llm/gateways/openai.js +469 -0
  134. package/dist/llm/gateways/openai.js.map +1 -0
  135. package/dist/llm/gateways/tokenizerGateway.d.ts +61 -0
  136. package/dist/llm/gateways/tokenizerGateway.d.ts.map +1 -0
  137. package/dist/llm/gateways/tokenizerGateway.js +75 -0
  138. package/dist/llm/gateways/tokenizerGateway.js.map +1 -0
  139. package/dist/llm/index.d.ts +11 -0
  140. package/dist/llm/index.d.ts.map +1 -0
  141. package/dist/llm/index.js +27 -0
  142. package/dist/llm/index.js.map +1 -0
  143. package/dist/llm/models.d.ts +95 -0
  144. package/dist/llm/models.d.ts.map +1 -0
  145. package/dist/llm/models.js +50 -0
  146. package/dist/llm/models.js.map +1 -0
  147. package/dist/llm/tools/ask-user.d.ts +39 -0
  148. package/dist/llm/tools/ask-user.d.ts.map +1 -0
  149. package/dist/llm/tools/ask-user.js +111 -0
  150. package/dist/llm/tools/ask-user.js.map +1 -0
  151. package/dist/llm/tools/current-datetime.d.ts +17 -0
  152. package/dist/llm/tools/current-datetime.d.ts.map +1 -0
  153. package/dist/llm/tools/current-datetime.js +76 -0
  154. package/dist/llm/tools/current-datetime.js.map +1 -0
  155. package/dist/llm/tools/date-resolver.d.ts +17 -0
  156. package/dist/llm/tools/date-resolver.d.ts.map +1 -0
  157. package/dist/llm/tools/date-resolver.js +135 -0
  158. package/dist/llm/tools/date-resolver.js.map +1 -0
  159. package/dist/llm/tools/ephemeral-task-manager/append-task.d.ts +13 -0
  160. package/dist/llm/tools/ephemeral-task-manager/append-task.d.ts.map +1 -0
  161. package/dist/llm/tools/ephemeral-task-manager/append-task.js +54 -0
  162. package/dist/llm/tools/ephemeral-task-manager/append-task.js.map +1 -0
  163. package/dist/llm/tools/ephemeral-task-manager/clear-tasks.d.ts +13 -0
  164. package/dist/llm/tools/ephemeral-task-manager/clear-tasks.d.ts.map +1 -0
  165. package/dist/llm/tools/ephemeral-task-manager/clear-tasks.js +37 -0
  166. package/dist/llm/tools/ephemeral-task-manager/clear-tasks.js.map +1 -0
  167. package/dist/llm/tools/ephemeral-task-manager/complete-task.d.ts +15 -0
  168. package/dist/llm/tools/ephemeral-task-manager/complete-task.d.ts.map +1 -0
  169. package/dist/llm/tools/ephemeral-task-manager/complete-task.js +56 -0
  170. package/dist/llm/tools/ephemeral-task-manager/complete-task.js.map +1 -0
  171. package/dist/llm/tools/ephemeral-task-manager/index.d.ts +44 -0
  172. package/dist/llm/tools/ephemeral-task-manager/index.d.ts.map +1 -0
  173. package/dist/llm/tools/ephemeral-task-manager/index.js +73 -0
  174. package/dist/llm/tools/ephemeral-task-manager/index.js.map +1 -0
  175. package/dist/llm/tools/ephemeral-task-manager/insert-task-after.d.ts +13 -0
  176. package/dist/llm/tools/ephemeral-task-manager/insert-task-after.d.ts.map +1 -0
  177. package/dist/llm/tools/ephemeral-task-manager/insert-task-after.js +59 -0
  178. package/dist/llm/tools/ephemeral-task-manager/insert-task-after.js.map +1 -0
  179. package/dist/llm/tools/ephemeral-task-manager/list-tasks.d.ts +14 -0
  180. package/dist/llm/tools/ephemeral-task-manager/list-tasks.d.ts.map +1 -0
  181. package/dist/llm/tools/ephemeral-task-manager/list-tasks.js +45 -0
  182. package/dist/llm/tools/ephemeral-task-manager/list-tasks.js.map +1 -0
  183. package/dist/llm/tools/ephemeral-task-manager/prepend-task.d.ts +13 -0
  184. package/dist/llm/tools/ephemeral-task-manager/prepend-task.d.ts.map +1 -0
  185. package/dist/llm/tools/ephemeral-task-manager/prepend-task.js +54 -0
  186. package/dist/llm/tools/ephemeral-task-manager/prepend-task.js.map +1 -0
  187. package/dist/llm/tools/ephemeral-task-manager/start-task.d.ts +15 -0
  188. package/dist/llm/tools/ephemeral-task-manager/start-task.d.ts.map +1 -0
  189. package/dist/llm/tools/ephemeral-task-manager/start-task.js +56 -0
  190. package/dist/llm/tools/ephemeral-task-manager/start-task.js.map +1 -0
  191. package/dist/llm/tools/ephemeral-task-manager/task-list.d.ts +68 -0
  192. package/dist/llm/tools/ephemeral-task-manager/task-list.d.ts.map +1 -0
  193. package/dist/llm/tools/ephemeral-task-manager/task-list.js +120 -0
  194. package/dist/llm/tools/ephemeral-task-manager/task-list.js.map +1 -0
  195. package/dist/llm/tools/ephemeral-task-manager/task.d.ts +21 -0
  196. package/dist/llm/tools/ephemeral-task-manager/task.d.ts.map +1 -0
  197. package/dist/llm/tools/ephemeral-task-manager/task.js +24 -0
  198. package/dist/llm/tools/ephemeral-task-manager/task.js.map +1 -0
  199. package/dist/llm/tools/file-manager.d.ts +127 -0
  200. package/dist/llm/tools/file-manager.d.ts.map +1 -0
  201. package/dist/llm/tools/file-manager.js +598 -0
  202. package/dist/llm/tools/file-manager.js.map +1 -0
  203. package/dist/llm/tools/index.d.ts +11 -0
  204. package/dist/llm/tools/index.d.ts.map +1 -0
  205. package/dist/llm/tools/index.js +27 -0
  206. package/dist/llm/tools/index.js.map +1 -0
  207. package/dist/llm/tools/tell-user.d.ts +31 -0
  208. package/dist/llm/tools/tell-user.d.ts.map +1 -0
  209. package/dist/llm/tools/tell-user.js +57 -0
  210. package/dist/llm/tools/tell-user.js.map +1 -0
  211. package/dist/llm/tools/tool-wrapper.d.ts +54 -0
  212. package/dist/llm/tools/tool-wrapper.d.ts.map +1 -0
  213. package/dist/llm/tools/tool-wrapper.js +91 -0
  214. package/dist/llm/tools/tool-wrapper.js.map +1 -0
  215. package/dist/llm/tools/tool.d.ts +70 -0
  216. package/dist/llm/tools/tool.d.ts.map +1 -0
  217. package/dist/llm/tools/tool.js +19 -0
  218. package/dist/llm/tools/tool.js.map +1 -0
  219. package/dist/llm/tools/web-search-tool.d.ts +35 -0
  220. package/dist/llm/tools/web-search-tool.d.ts.map +1 -0
  221. package/dist/llm/tools/web-search-tool.js +105 -0
  222. package/dist/llm/tools/web-search-tool.js.map +1 -0
  223. package/dist/llm/utils/image.d.ts +30 -0
  224. package/dist/llm/utils/image.d.ts.map +1 -0
  225. package/dist/llm/utils/image.js +65 -0
  226. package/dist/llm/utils/image.js.map +1 -0
  227. package/dist/tracer/eventStore.d.ts +101 -0
  228. package/dist/tracer/eventStore.d.ts.map +1 -0
  229. package/dist/tracer/eventStore.js +120 -0
  230. package/dist/tracer/eventStore.js.map +1 -0
  231. package/dist/tracer/index.d.ts +8 -0
  232. package/dist/tracer/index.d.ts.map +1 -0
  233. package/dist/tracer/index.js +24 -0
  234. package/dist/tracer/index.js.map +1 -0
  235. package/dist/tracer/nullTracer.d.ts +127 -0
  236. package/dist/tracer/nullTracer.d.ts.map +1 -0
  237. package/dist/tracer/nullTracer.js +148 -0
  238. package/dist/tracer/nullTracer.js.map +1 -0
  239. package/dist/tracer/tracerEvents.d.ts +209 -0
  240. package/dist/tracer/tracerEvents.d.ts.map +1 -0
  241. package/dist/tracer/tracerEvents.js +312 -0
  242. package/dist/tracer/tracerEvents.js.map +1 -0
  243. package/dist/tracer/tracerSystem.d.ts +149 -0
  244. package/dist/tracer/tracerSystem.d.ts.map +1 -0
  245. package/dist/tracer/tracerSystem.js +196 -0
  246. package/dist/tracer/tracerSystem.js.map +1 -0
  247. package/package.json +87 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Mojility Inc.
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.
package/README.md ADDED
@@ -0,0 +1,459 @@
1
+ # Mojentic
2
+
3
+ [![npm](https://img.shields.io/npm/v/mojentic.svg)](https://www.npmjs.com/package/mojentic)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
5
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.3-blue)](https://www.typescriptlang.org/)
6
+ [![Node](https://img.shields.io/badge/Node-%3E%3D18.0-green)](https://nodejs.org/)
7
+
8
+ A modern LLM integration framework for TypeScript with full feature parity across Python, Elixir, and Rust implementations. Perfect for building VS Code extensions, Obsidian plugins, and Node.js applications.
9
+
10
+ ## 🚀 Features
11
+
12
+ - **🔌 Multi-Provider Support**: OpenAI and Ollama gateways
13
+ - **🤖 Agent System**: Complete event-driven agent framework with ReAct pattern
14
+ - **🛠️ Tool System**: Extensible function calling with automatic recursive execution
15
+ - **📊 Structured Output**: Type-safe response parsing with JSON schemas
16
+ - **🌊 Streaming**: Real-time streaming with full tool calling support
17
+ - **🔍 Tracer System**: Complete observability for debugging and monitoring
18
+ - **🔒 Type-Safe**: Full TypeScript support with comprehensive type definitions
19
+ - **🎯 Result Type Pattern**: Rust-inspired error handling for robust code
20
+ - **📦 24 Examples**: Comprehensive examples demonstrating all features
21
+
22
+ ## 📦 Installation
23
+
24
+ ```bash
25
+ npm install mojentic
26
+ # or
27
+ yarn add mojentic
28
+ # or
29
+ pnpm add mojentic
30
+ ```
31
+
32
+ ## 🔧 Prerequisites
33
+
34
+ To use Mojentic with local models, you need Ollama installed and running:
35
+
36
+ 1. Install Ollama from [ollama.ai](https://ollama.ai)
37
+ 2. Pull a model: `ollama pull qwen3:32b`
38
+ 3. Verify it's running: `ollama list`
39
+
40
+ ## 🎯 Quick Start
41
+
42
+ ### Simple Text Generation
43
+
44
+ ```typescript
45
+ import { LlmBroker, OllamaGateway, Message } from 'mojentic';
46
+ import { isOk } from 'mojentic';
47
+
48
+ const gateway = new OllamaGateway();
49
+ const broker = new LlmBroker('qwen3:32b', gateway);
50
+
51
+ const messages = [Message.user('What is TypeScript?')];
52
+ const result = await broker.generate(messages);
53
+
54
+ if (isOk(result)) {
55
+ console.log(result.value);
56
+ } else {
57
+ console.error(result.error);
58
+ }
59
+ ```
60
+
61
+ ### Structured Output
62
+
63
+ ```typescript
64
+ import { LlmBroker, OllamaGateway, Message } from 'mojentic';
65
+ import { isOk } from 'mojentic';
66
+
67
+ interface SentimentAnalysis {
68
+ sentiment: string;
69
+ confidence: number;
70
+ reasoning: string;
71
+ }
72
+
73
+ const gateway = new OllamaGateway();
74
+ const broker = new LlmBroker('qwen3:32b', gateway);
75
+
76
+ const schema = {
77
+ type: 'object',
78
+ properties: {
79
+ sentiment: { type: 'string', enum: ['positive', 'negative', 'neutral'] },
80
+ confidence: { type: 'number', minimum: 0, maximum: 1 },
81
+ reasoning: { type: 'string' },
82
+ },
83
+ required: ['sentiment', 'confidence', 'reasoning'],
84
+ };
85
+
86
+ const messages = [
87
+ Message.user('I love this new framework!'),
88
+ ];
89
+
90
+ const result = await broker.generateObject<SentimentAnalysis>(messages, schema);
91
+
92
+ if (isOk(result)) {
93
+ console.log(`Sentiment: ${result.value.sentiment}`);
94
+ console.log(`Confidence: ${(result.value.confidence * 100).toFixed(1)}%`);
95
+ }
96
+ ```
97
+
98
+ ### Tool Usage
99
+
100
+ ```typescript
101
+ import { LlmBroker, OllamaGateway, Message, DateResolverTool } from 'mojentic';
102
+ import { isOk } from 'mojentic';
103
+
104
+ const gateway = new OllamaGateway();
105
+ const broker = new LlmBroker('qwen3:32b', gateway);
106
+
107
+ const tools = [new DateResolverTool()];
108
+
109
+ const messages = [
110
+ Message.system('You are a helpful assistant with access to tools.'),
111
+ Message.user('What day of the week is next Friday?'),
112
+ ];
113
+
114
+ // The broker automatically handles tool calls
115
+ const result = await broker.generate(messages, tools);
116
+
117
+ if (isOk(result)) {
118
+ console.log(result.value);
119
+ }
120
+ ```
121
+
122
+ ### Streaming
123
+
124
+ ```typescript
125
+ import { LlmBroker, OllamaGateway, Message } from 'mojentic';
126
+ import { isOk } from 'mojentic';
127
+
128
+ const gateway = new OllamaGateway();
129
+ const broker = new LlmBroker('qwen3:32b', gateway);
130
+
131
+ const messages = [Message.user('Write a short poem about TypeScript')];
132
+
133
+ for await (const chunk of broker.generateStream(messages)) {
134
+ if (isOk(chunk)) {
135
+ process.stdout.write(chunk.value);
136
+ }
137
+ }
138
+ ```
139
+
140
+ ### Tracer System
141
+
142
+ Monitor and debug your LLM applications:
143
+
144
+ ```typescript
145
+ import { LlmBroker, OllamaGateway, Message, TracerSystem } from 'mojentic';
146
+ import { DateResolverTool } from 'mojentic';
147
+ import { isOk } from 'mojentic';
148
+
149
+ // Create a tracer system
150
+ const tracer = new TracerSystem();
151
+
152
+ const gateway = new OllamaGateway();
153
+ const broker = new LlmBroker('qwen3:32b', gateway, tracer);
154
+
155
+ const tools = [new DateResolverTool()];
156
+
157
+ // Generate unique correlation ID for tracing related events
158
+ const correlationId = crypto.randomUUID();
159
+
160
+ const messages = [
161
+ Message.user('What day is next Friday?'),
162
+ ];
163
+
164
+ const result = await broker.generate(messages, tools, {}, 10, correlationId);
165
+
166
+ // Query tracer events
167
+ const allEvents = tracer.getEvents();
168
+ console.log(`Recorded ${allEvents.length} events`);
169
+
170
+ // Filter by correlation ID
171
+ const relatedEvents = tracer.getEvents({
172
+ filterFunc: (e) => e.correlationId === correlationId
173
+ });
174
+
175
+ // Print event summaries
176
+ relatedEvents.forEach(event => {
177
+ console.log(event.printableSummary());
178
+ });
179
+ ```
180
+
181
+ See [Tracer Documentation](docs/tracer.md) for comprehensive usage guide.
182
+
183
+ ## 🏗️ Architecture
184
+
185
+ Mojentic is structured in three layers:
186
+
187
+ ### Layer 1: LLM Integration
188
+
189
+ - **LlmBroker** - Main interface for LLM interactions
190
+ - **LlmGateway** interface - Abstract interface for LLM providers
191
+ - **OllamaGateway** / **OpenAiGateway** - Provider implementations
192
+ - **ChatSession** - Conversational session management
193
+ - **TokenizerGateway** - Token counting with tiktoken
194
+ - **EmbeddingsGateway** - Vector embeddings
195
+ - **Tool System** - Extensible function calling with 10+ built-in tools
196
+
197
+ ### Layer 2: Tracer System
198
+
199
+ - **TracerSystem** - Complete event recording for observability
200
+ - **EventStore** - Flexible event storage and querying
201
+ - **NullTracer** - Zero-overhead when tracing is disabled
202
+ - Correlation ID tracking across requests
203
+
204
+ ### Layer 3: Agent System
205
+
206
+ - **AsyncDispatcher** - Async event processing
207
+ - **Router** - Event-to-agent routing
208
+ - **AsyncLlmAgent** - LLM-powered async agents
209
+ - **AsyncAggregatorAgent** - Multi-event aggregation
210
+ - **IterativeProblemSolver** - Multi-step reasoning
211
+ - **SimpleRecursiveAgent** - Self-recursive processing
212
+ - **SharedWorkingMemory** - Agent context sharing
213
+ - ReAct pattern implementation
214
+
215
+ ## 🛠️ Creating Custom Tools
216
+
217
+ Implement the `LlmTool` interface:
218
+
219
+ ```typescript
220
+ import { BaseTool, ToolArgs, ToolDescriptor, ToolResult } from 'mojentic';
221
+ import { Ok, Result } from 'mojentic';
222
+
223
+ export class WeatherTool extends BaseTool {
224
+ async run(args: ToolArgs): Promise<Result<ToolResult, Error>> {
225
+ const location = args.location as string;
226
+ // Fetch weather data...
227
+ return Ok({
228
+ location,
229
+ temperature: 22,
230
+ condition: 'sunny',
231
+ });
232
+ }
233
+
234
+ descriptor(): ToolDescriptor {
235
+ return {
236
+ type: 'function',
237
+ function: {
238
+ name: 'get_weather',
239
+ description: 'Get current weather for a location',
240
+ parameters: {
241
+ type: 'object',
242
+ properties: {
243
+ location: {
244
+ type: 'string',
245
+ description: 'City name',
246
+ },
247
+ },
248
+ required: ['location'],
249
+ },
250
+ },
251
+ };
252
+ }
253
+ }
254
+ ```
255
+
256
+ ## 🎨 Error Handling
257
+
258
+ Mojentic uses a Result type pattern inspired by Rust:
259
+
260
+ ```typescript
261
+ import { Result, Ok, Err, isOk, isErr, unwrap, unwrapOr } from 'mojentic';
262
+
263
+ const result = await broker.generate(messages);
264
+
265
+ // Pattern 1: Check and narrow
266
+ if (isOk(result)) {
267
+ console.log(result.value); // Type: string
268
+ } else {
269
+ console.error(result.error); // Type: Error
270
+ }
271
+
272
+ // Pattern 2: Unwrap (throws on error)
273
+ const value = unwrap(result);
274
+
275
+ // Pattern 3: Unwrap with default
276
+ const value = unwrapOr(result, 'default value');
277
+
278
+ // Pattern 4: Map and transform
279
+ const mapped = mapResult(result, (text) => text.toUpperCase());
280
+ ```
281
+
282
+ ### Error Types
283
+
284
+ ```typescript
285
+ import {
286
+ MojenticError, // Base error
287
+ GatewayError, // API/network errors
288
+ ToolError, // Tool execution errors
289
+ ValidationError, // Input validation errors
290
+ ParseError, // JSON parsing errors
291
+ TimeoutError, // Timeout errors
292
+ } from 'mojentic';
293
+ ```
294
+
295
+ ## 📖 API Reference
296
+
297
+ ### LlmBroker
298
+
299
+ Main interface for LLM interactions:
300
+
301
+ ```typescript
302
+ class LlmBroker {
303
+ constructor(model: string, gateway: LlmGateway);
304
+
305
+ // Generate text completion
306
+ generate(
307
+ messages: LlmMessage[],
308
+ tools?: LlmTool[],
309
+ config?: CompletionConfig,
310
+ maxToolIterations?: number
311
+ ): Promise<Result<string, Error>>;
312
+
313
+ // Generate structured object
314
+ generateObject<T>(
315
+ messages: LlmMessage[],
316
+ schema: Record<string, unknown>,
317
+ config?: CompletionConfig
318
+ ): Promise<Result<T, Error>>;
319
+
320
+ // Generate streaming completion
321
+ generateStream(
322
+ messages: LlmMessage[],
323
+ config?: CompletionConfig,
324
+ tools?: LlmTool[]
325
+ ): AsyncGenerator<Result<string, Error>>;
326
+
327
+ // List available models
328
+ listModels(): Promise<Result<string[], Error>>;
329
+
330
+ // Get current model
331
+ getModel(): string;
332
+ }
333
+ ```
334
+
335
+ ### Message Helpers
336
+
337
+ ```typescript
338
+ class Message {
339
+ static system(content: string): LlmMessage;
340
+ static user(content: string): LlmMessage;
341
+ static assistant(content: string, toolCalls?: ToolCall[]): LlmMessage;
342
+ static tool(content: string, toolCallId: string, name: string): LlmMessage;
343
+ }
344
+ ```
345
+
346
+ ### CompletionConfig
347
+
348
+ ```typescript
349
+ interface CompletionConfig {
350
+ temperature?: number;
351
+ maxTokens?: number;
352
+ topP?: number;
353
+ frequencyPenalty?: number;
354
+ presencePenalty?: number;
355
+ stop?: string[];
356
+ stream?: boolean;
357
+ responseFormat?: {
358
+ type: 'json_object' | 'text';
359
+ schema?: Record<string, unknown>;
360
+ };
361
+ }
362
+ ```
363
+
364
+ ## 🧪 Examples
365
+
366
+ Run any of the 24 included examples:
367
+
368
+ ```bash
369
+ # Install dependencies
370
+ npm install
371
+
372
+ # Core examples
373
+ npm run example:simple # Simple text generation
374
+ npm run example:structured # Structured output
375
+ npm run example:tool # Tool usage
376
+ npm run example:streaming # Streaming responses
377
+
378
+ # Advanced examples
379
+ npm run example:broker # Comprehensive broker features
380
+ npm run example:broker-as-tool # Agent delegation pattern
381
+ npm run example:tracer # Tracer system demo
382
+ npm run example:async-llm # Async agents
383
+ npm run example:iterative-solver # Multi-step problem solving
384
+ npm run example:recursive-agent # Recursive agent patterns
385
+ ```
386
+
387
+ ## 🏗️ Architecture
388
+
389
+ Mojentic is structured in three layers:
390
+
391
+ ### Layer 1: LLM Integration
392
+
393
+ - `LlmBroker` - Main interface for LLM interactions
394
+ - `LlmGateway` interface - Abstract interface for LLM providers
395
+ - `OllamaGateway` / `OpenAiGateway` - Provider implementations
396
+ - `ChatSession` - Conversational session management
397
+ - `TokenizerGateway` - Token counting with tiktoken
398
+ - `EmbeddingsGateway` - Vector embeddings
399
+ - Comprehensive tool system with 10+ built-in tools
400
+
401
+ ### Layer 2: Tracer System
402
+
403
+ - `TracerSystem` - Event recording for observability
404
+ - `EventStore` - Flexible event storage and querying
405
+ - Correlation ID tracking across requests
406
+ - LLM call, response, and tool events
407
+
408
+ ### Layer 3: Agent System
409
+
410
+ - `AsyncDispatcher` - Async event processing
411
+ - `Router` - Event-to-agent routing
412
+ - `AsyncLlmAgent` - LLM-powered agents
413
+ - `AsyncAggregatorAgent` - Multi-event aggregation
414
+ - `IterativeProblemSolver` - Multi-step reasoning
415
+ - `SimpleRecursiveAgent` - Self-recursive processing
416
+ - `SharedWorkingMemory` - Agent context sharing
417
+ - ReAct pattern implementation
418
+
419
+ ## 🔧 Development
420
+
421
+ ```bash
422
+ # Install dependencies
423
+ npm install
424
+
425
+ # Build
426
+ npm run build
427
+
428
+ # Run tests
429
+ npm test
430
+
431
+ # Run tests with coverage
432
+ npm run test:coverage
433
+
434
+ # Lint (zero warnings enforced)
435
+ npm run lint
436
+
437
+ # Format
438
+ npm run format
439
+
440
+ # Full quality check
441
+ npm run quality
442
+ ```
443
+
444
+ ## 🤝 Contributing
445
+
446
+ Contributions are welcome! This is part of the Mojentic family of implementations:
447
+
448
+ - **mojentic-py** - Python implementation (reference)
449
+ - **mojentic-ex** - Elixir implementation
450
+ - **mojentic-ru** - Rust implementation
451
+ - **mojentic-ts** - TypeScript implementation (this)
452
+
453
+ ## 📄 License
454
+
455
+ MIT License - see [LICENSE](LICENSE) for details
456
+
457
+ ## Credits
458
+
459
+ Mojentic is a [Mojility](https://mojility.com) product by Stacey Vetzal.
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Async Aggregator Agent - Collects and processes multiple related events
3
+ */
4
+ import { BaseAsyncAgent } from './base-async-agent';
5
+ import { Event } from './event';
6
+ import { Result } from '../error';
7
+ /**
8
+ * Base class for agents that aggregate multiple events before processing.
9
+ *
10
+ * This agent collects events with the same correlation ID until all required
11
+ * event types have been received, then calls `processEvents` with the complete set.
12
+ *
13
+ * Useful for workflows where multiple agents process parts of a request in parallel,
14
+ * and a final agent combines their results.
15
+ *
16
+ * @example
17
+ * ```typescript
18
+ * class FinalAnswerAgent extends AsyncAggregatorAgent {
19
+ * constructor() {
20
+ * super(['FactCheckEvent', 'AnswerEvent']);
21
+ * }
22
+ *
23
+ * async processEvents(events: Event[]): Promise<Result<Event[], Error>> {
24
+ * const facts = events.find(e => e.type === 'FactCheckEvent') as FactCheckEvent;
25
+ * const answer = events.find(e => e.type === 'AnswerEvent') as AnswerEvent;
26
+ *
27
+ * return Ok([new FinalAnswerEvent({
28
+ * answer: answer.answer,
29
+ * facts: facts.facts
30
+ * })]);
31
+ * }
32
+ * }
33
+ * ```
34
+ */
35
+ export declare abstract class AsyncAggregatorAgent implements BaseAsyncAgent {
36
+ /** Map of correlation IDs to accumulated events */
37
+ protected results: Map<string, Event[]>;
38
+ /** Map of correlation IDs to waiting promise resolvers */
39
+ private waiters;
40
+ /** Event type names that must be collected before processing */
41
+ protected readonly eventTypesNeeded: string[];
42
+ /**
43
+ * Create a new aggregator agent.
44
+ *
45
+ * @param eventTypesNeeded - Array of event type names to wait for
46
+ */
47
+ constructor(eventTypesNeeded: string[]);
48
+ /**
49
+ * Check if all required event types have been received for a correlation ID.
50
+ *
51
+ * @param correlationId - The correlation ID to check
52
+ * @returns True if all needed event types are present
53
+ */
54
+ private hasAllNeeded;
55
+ /**
56
+ * Capture an event and check if processing should trigger.
57
+ *
58
+ * @param event - The event to capture
59
+ */
60
+ private captureEvent;
61
+ /**
62
+ * Get and clear the accumulated events for a correlation ID.
63
+ *
64
+ * @param correlationId - The correlation ID
65
+ * @returns Array of events
66
+ */
67
+ private getAndResetResults;
68
+ /**
69
+ * Wait for all required events to be received for a correlation ID.
70
+ *
71
+ * This method blocks until all events specified in `eventTypesNeeded` have
72
+ * been received with the given correlation ID, or until the timeout expires.
73
+ *
74
+ * @param correlationId - The correlation ID to wait for
75
+ * @param timeout - Optional timeout in milliseconds
76
+ * @returns Result containing the complete set of events or an error
77
+ */
78
+ waitForEvents(correlationId: string, timeout?: number): Promise<Result<Event[], Error>>;
79
+ /**
80
+ * Receive and process an event.
81
+ *
82
+ * Events are accumulated until all required types are present, then
83
+ * `processEvents` is called with the complete set.
84
+ *
85
+ * @param event - The event to process
86
+ * @returns Result containing new events to dispatch or an error
87
+ */
88
+ receiveEventAsync(event: Event): Promise<Result<Event[], Error>>;
89
+ /**
90
+ * Process a complete set of aggregated events.
91
+ *
92
+ * This method is called when all required event types have been received
93
+ * for a correlation ID. Subclasses must implement this to define their
94
+ * aggregation logic.
95
+ *
96
+ * @param events - The complete set of events to process
97
+ * @returns Result containing new events to dispatch or an error
98
+ */
99
+ abstract processEvents(events: Event[]): Promise<Result<Event[], Error>>;
100
+ }
101
+ //# sourceMappingURL=async-aggregator-agent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"async-aggregator-agent.d.ts","sourceRoot":"","sources":["../../src/agents/async-aggregator-agent.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,MAAM,EAAW,MAAM,UAAU,CAAC;AAO3C;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,8BAAsB,oBAAqB,YAAW,cAAc;IAClE,mDAAmD;IACnD,SAAS,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,CAAa;IAEpD,0DAA0D;IAC1D,OAAO,CAAC,OAAO,CAA2C;IAE1D,gEAAgE;IAChE,SAAS,CAAC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAE9C;;;;OAIG;gBACS,gBAAgB,EAAE,MAAM,EAAE;IAItC;;;;;OAKG;IACH,OAAO,CAAC,YAAY;IAQpB;;;;OAIG;IACH,OAAO,CAAC,YAAY;IAoBpB;;;;;OAKG;IACH,OAAO,CAAC,kBAAkB;IAM1B;;;;;;;;;OASG;IACG,aAAa,CAAC,aAAa,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,KAAK,CAAC,CAAC;IAiC7F;;;;;;;;OAQG;IACG,iBAAiB,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,KAAK,CAAC,CAAC;IAmBtE;;;;;;;;;OASG;IACH,QAAQ,CAAC,aAAa,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,KAAK,CAAC,CAAC;CACzE"}