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.
- package/LICENSE +21 -0
- package/README.md +459 -0
- package/dist/agents/async-aggregator-agent.d.ts +101 -0
- package/dist/agents/async-aggregator-agent.d.ts.map +1 -0
- package/dist/agents/async-aggregator-agent.js +160 -0
- package/dist/agents/async-aggregator-agent.js.map +1 -0
- package/dist/agents/async-dispatcher.d.ts +98 -0
- package/dist/agents/async-dispatcher.d.ts.map +1 -0
- package/dist/agents/async-dispatcher.js +173 -0
- package/dist/agents/async-dispatcher.js.map +1 -0
- package/dist/agents/async-llm-agent-with-memory.d.ts +95 -0
- package/dist/agents/async-llm-agent-with-memory.d.ts.map +1 -0
- package/dist/agents/async-llm-agent-with-memory.js +136 -0
- package/dist/agents/async-llm-agent-with-memory.js.map +1 -0
- package/dist/agents/async-llm-agent.d.ts +85 -0
- package/dist/agents/async-llm-agent.d.ts.map +1 -0
- package/dist/agents/async-llm-agent.js +87 -0
- package/dist/agents/async-llm-agent.js.map +1 -0
- package/dist/agents/base-agent.d.ts +59 -0
- package/dist/agents/base-agent.d.ts.map +1 -0
- package/dist/agents/base-agent.js +24 -0
- package/dist/agents/base-agent.js.map +1 -0
- package/dist/agents/base-async-agent.d.ts +42 -0
- package/dist/agents/base-async-agent.d.ts.map +1 -0
- package/dist/agents/base-async-agent.js +6 -0
- package/dist/agents/base-async-agent.js.map +1 -0
- package/dist/agents/event.d.ts +26 -0
- package/dist/agents/event.d.ts.map +1 -0
- package/dist/agents/event.js +13 -0
- package/dist/agents/event.js.map +1 -0
- package/dist/agents/index.d.ts +14 -0
- package/dist/agents/index.d.ts.map +1 -0
- package/dist/agents/index.js +30 -0
- package/dist/agents/index.js.map +1 -0
- package/dist/agents/iterative-problem-solver.d.ts +83 -0
- package/dist/agents/iterative-problem-solver.d.ts.map +1 -0
- package/dist/agents/iterative-problem-solver.js +120 -0
- package/dist/agents/iterative-problem-solver.js.map +1 -0
- package/dist/agents/router.d.ts +44 -0
- package/dist/agents/router.d.ts.map +1 -0
- package/dist/agents/router.js +53 -0
- package/dist/agents/router.js.map +1 -0
- package/dist/agents/simple-recursive-agent.d.ts +182 -0
- package/dist/agents/simple-recursive-agent.d.ts.map +1 -0
- package/dist/agents/simple-recursive-agent.js +272 -0
- package/dist/agents/simple-recursive-agent.js.map +1 -0
- package/dist/context/index.d.ts +5 -0
- package/dist/context/index.d.ts.map +1 -0
- package/dist/context/index.js +21 -0
- package/dist/context/index.js.map +1 -0
- package/dist/context/shared-working-memory.d.ts +76 -0
- package/dist/context/shared-working-memory.d.ts.map +1 -0
- package/dist/context/shared-working-memory.js +121 -0
- package/dist/context/shared-working-memory.js.map +1 -0
- package/dist/error.d.ts +93 -0
- package/dist/error.d.ts.map +1 -0
- package/dist/error.js +149 -0
- package/dist/error.js.map +1 -0
- package/dist/examples/react/decisioning-agent.d.ts +48 -0
- package/dist/examples/react/decisioning-agent.d.ts.map +1 -0
- package/dist/examples/react/decisioning-agent.js +204 -0
- package/dist/examples/react/decisioning-agent.js.map +1 -0
- package/dist/examples/react/events.d.ts +77 -0
- package/dist/examples/react/events.d.ts.map +1 -0
- package/dist/examples/react/events.js +9 -0
- package/dist/examples/react/events.js.map +1 -0
- package/dist/examples/react/formatters.d.ts +23 -0
- package/dist/examples/react/formatters.d.ts.map +1 -0
- package/dist/examples/react/formatters.js +68 -0
- package/dist/examples/react/formatters.js.map +1 -0
- package/dist/examples/react/index.d.ts +12 -0
- package/dist/examples/react/index.d.ts.map +1 -0
- package/dist/examples/react/index.js +28 -0
- package/dist/examples/react/index.js.map +1 -0
- package/dist/examples/react/models.d.ts +57 -0
- package/dist/examples/react/models.d.ts.map +1 -0
- package/dist/examples/react/models.js +19 -0
- package/dist/examples/react/models.js.map +1 -0
- package/dist/examples/react/output-agent.d.ts +23 -0
- package/dist/examples/react/output-agent.d.ts.map +1 -0
- package/dist/examples/react/output-agent.js +28 -0
- package/dist/examples/react/output-agent.js.map +1 -0
- package/dist/examples/react/summarization-agent.d.ts +46 -0
- package/dist/examples/react/summarization-agent.d.ts.map +1 -0
- package/dist/examples/react/summarization-agent.js +102 -0
- package/dist/examples/react/summarization-agent.js.map +1 -0
- package/dist/examples/react/thinking-agent.d.ts +47 -0
- package/dist/examples/react/thinking-agent.d.ts.map +1 -0
- package/dist/examples/react/thinking-agent.js +127 -0
- package/dist/examples/react/thinking-agent.js.map +1 -0
- package/dist/examples/react/tool-call-agent.d.ts +25 -0
- package/dist/examples/react/tool-call-agent.d.ts.map +1 -0
- package/dist/examples/react/tool-call-agent.js +83 -0
- package/dist/examples/react/tool-call-agent.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +28 -0
- package/dist/index.js.map +1 -0
- package/dist/llm/agent.d.ts +68 -0
- package/dist/llm/agent.d.ts.map +1 -0
- package/dist/llm/agent.js +85 -0
- package/dist/llm/agent.js.map +1 -0
- package/dist/llm/broker.d.ts +150 -0
- package/dist/llm/broker.d.ts.map +1 -0
- package/dist/llm/broker.js +355 -0
- package/dist/llm/broker.js.map +1 -0
- package/dist/llm/chat-session.d.ts +98 -0
- package/dist/llm/chat-session.d.ts.map +1 -0
- package/dist/llm/chat-session.js +156 -0
- package/dist/llm/chat-session.js.map +1 -0
- package/dist/llm/gateway.d.ts +28 -0
- package/dist/llm/gateway.d.ts.map +1 -0
- package/dist/llm/gateway.js +6 -0
- package/dist/llm/gateway.js.map +1 -0
- package/dist/llm/gateways/index.d.ts +9 -0
- package/dist/llm/gateways/index.d.ts.map +1 -0
- package/dist/llm/gateways/index.js +25 -0
- package/dist/llm/gateways/index.js.map +1 -0
- package/dist/llm/gateways/ollama.d.ts +30 -0
- package/dist/llm/gateways/ollama.d.ts.map +1 -0
- package/dist/llm/gateways/ollama.js +322 -0
- package/dist/llm/gateways/ollama.js.map +1 -0
- package/dist/llm/gateways/openai-messages-adapter.d.ts +29 -0
- package/dist/llm/gateways/openai-messages-adapter.d.ts.map +1 -0
- package/dist/llm/gateways/openai-messages-adapter.js +188 -0
- package/dist/llm/gateways/openai-messages-adapter.js.map +1 -0
- package/dist/llm/gateways/openai-model-registry.d.ts +82 -0
- package/dist/llm/gateways/openai-model-registry.d.ts.map +1 -0
- package/dist/llm/gateways/openai-model-registry.js +352 -0
- package/dist/llm/gateways/openai-model-registry.js.map +1 -0
- package/dist/llm/gateways/openai.d.ts +40 -0
- package/dist/llm/gateways/openai.d.ts.map +1 -0
- package/dist/llm/gateways/openai.js +469 -0
- package/dist/llm/gateways/openai.js.map +1 -0
- package/dist/llm/gateways/tokenizerGateway.d.ts +61 -0
- package/dist/llm/gateways/tokenizerGateway.d.ts.map +1 -0
- package/dist/llm/gateways/tokenizerGateway.js +75 -0
- package/dist/llm/gateways/tokenizerGateway.js.map +1 -0
- package/dist/llm/index.d.ts +11 -0
- package/dist/llm/index.d.ts.map +1 -0
- package/dist/llm/index.js +27 -0
- package/dist/llm/index.js.map +1 -0
- package/dist/llm/models.d.ts +95 -0
- package/dist/llm/models.d.ts.map +1 -0
- package/dist/llm/models.js +50 -0
- package/dist/llm/models.js.map +1 -0
- package/dist/llm/tools/ask-user.d.ts +39 -0
- package/dist/llm/tools/ask-user.d.ts.map +1 -0
- package/dist/llm/tools/ask-user.js +111 -0
- package/dist/llm/tools/ask-user.js.map +1 -0
- package/dist/llm/tools/current-datetime.d.ts +17 -0
- package/dist/llm/tools/current-datetime.d.ts.map +1 -0
- package/dist/llm/tools/current-datetime.js +76 -0
- package/dist/llm/tools/current-datetime.js.map +1 -0
- package/dist/llm/tools/date-resolver.d.ts +17 -0
- package/dist/llm/tools/date-resolver.d.ts.map +1 -0
- package/dist/llm/tools/date-resolver.js +135 -0
- package/dist/llm/tools/date-resolver.js.map +1 -0
- package/dist/llm/tools/ephemeral-task-manager/append-task.d.ts +13 -0
- package/dist/llm/tools/ephemeral-task-manager/append-task.d.ts.map +1 -0
- package/dist/llm/tools/ephemeral-task-manager/append-task.js +54 -0
- package/dist/llm/tools/ephemeral-task-manager/append-task.js.map +1 -0
- package/dist/llm/tools/ephemeral-task-manager/clear-tasks.d.ts +13 -0
- package/dist/llm/tools/ephemeral-task-manager/clear-tasks.d.ts.map +1 -0
- package/dist/llm/tools/ephemeral-task-manager/clear-tasks.js +37 -0
- package/dist/llm/tools/ephemeral-task-manager/clear-tasks.js.map +1 -0
- package/dist/llm/tools/ephemeral-task-manager/complete-task.d.ts +15 -0
- package/dist/llm/tools/ephemeral-task-manager/complete-task.d.ts.map +1 -0
- package/dist/llm/tools/ephemeral-task-manager/complete-task.js +56 -0
- package/dist/llm/tools/ephemeral-task-manager/complete-task.js.map +1 -0
- package/dist/llm/tools/ephemeral-task-manager/index.d.ts +44 -0
- package/dist/llm/tools/ephemeral-task-manager/index.d.ts.map +1 -0
- package/dist/llm/tools/ephemeral-task-manager/index.js +73 -0
- package/dist/llm/tools/ephemeral-task-manager/index.js.map +1 -0
- package/dist/llm/tools/ephemeral-task-manager/insert-task-after.d.ts +13 -0
- package/dist/llm/tools/ephemeral-task-manager/insert-task-after.d.ts.map +1 -0
- package/dist/llm/tools/ephemeral-task-manager/insert-task-after.js +59 -0
- package/dist/llm/tools/ephemeral-task-manager/insert-task-after.js.map +1 -0
- package/dist/llm/tools/ephemeral-task-manager/list-tasks.d.ts +14 -0
- package/dist/llm/tools/ephemeral-task-manager/list-tasks.d.ts.map +1 -0
- package/dist/llm/tools/ephemeral-task-manager/list-tasks.js +45 -0
- package/dist/llm/tools/ephemeral-task-manager/list-tasks.js.map +1 -0
- package/dist/llm/tools/ephemeral-task-manager/prepend-task.d.ts +13 -0
- package/dist/llm/tools/ephemeral-task-manager/prepend-task.d.ts.map +1 -0
- package/dist/llm/tools/ephemeral-task-manager/prepend-task.js +54 -0
- package/dist/llm/tools/ephemeral-task-manager/prepend-task.js.map +1 -0
- package/dist/llm/tools/ephemeral-task-manager/start-task.d.ts +15 -0
- package/dist/llm/tools/ephemeral-task-manager/start-task.d.ts.map +1 -0
- package/dist/llm/tools/ephemeral-task-manager/start-task.js +56 -0
- package/dist/llm/tools/ephemeral-task-manager/start-task.js.map +1 -0
- package/dist/llm/tools/ephemeral-task-manager/task-list.d.ts +68 -0
- package/dist/llm/tools/ephemeral-task-manager/task-list.d.ts.map +1 -0
- package/dist/llm/tools/ephemeral-task-manager/task-list.js +120 -0
- package/dist/llm/tools/ephemeral-task-manager/task-list.js.map +1 -0
- package/dist/llm/tools/ephemeral-task-manager/task.d.ts +21 -0
- package/dist/llm/tools/ephemeral-task-manager/task.d.ts.map +1 -0
- package/dist/llm/tools/ephemeral-task-manager/task.js +24 -0
- package/dist/llm/tools/ephemeral-task-manager/task.js.map +1 -0
- package/dist/llm/tools/file-manager.d.ts +127 -0
- package/dist/llm/tools/file-manager.d.ts.map +1 -0
- package/dist/llm/tools/file-manager.js +598 -0
- package/dist/llm/tools/file-manager.js.map +1 -0
- package/dist/llm/tools/index.d.ts +11 -0
- package/dist/llm/tools/index.d.ts.map +1 -0
- package/dist/llm/tools/index.js +27 -0
- package/dist/llm/tools/index.js.map +1 -0
- package/dist/llm/tools/tell-user.d.ts +31 -0
- package/dist/llm/tools/tell-user.d.ts.map +1 -0
- package/dist/llm/tools/tell-user.js +57 -0
- package/dist/llm/tools/tell-user.js.map +1 -0
- package/dist/llm/tools/tool-wrapper.d.ts +54 -0
- package/dist/llm/tools/tool-wrapper.d.ts.map +1 -0
- package/dist/llm/tools/tool-wrapper.js +91 -0
- package/dist/llm/tools/tool-wrapper.js.map +1 -0
- package/dist/llm/tools/tool.d.ts +70 -0
- package/dist/llm/tools/tool.d.ts.map +1 -0
- package/dist/llm/tools/tool.js +19 -0
- package/dist/llm/tools/tool.js.map +1 -0
- package/dist/llm/tools/web-search-tool.d.ts +35 -0
- package/dist/llm/tools/web-search-tool.d.ts.map +1 -0
- package/dist/llm/tools/web-search-tool.js +105 -0
- package/dist/llm/tools/web-search-tool.js.map +1 -0
- package/dist/llm/utils/image.d.ts +30 -0
- package/dist/llm/utils/image.d.ts.map +1 -0
- package/dist/llm/utils/image.js +65 -0
- package/dist/llm/utils/image.js.map +1 -0
- package/dist/tracer/eventStore.d.ts +101 -0
- package/dist/tracer/eventStore.d.ts.map +1 -0
- package/dist/tracer/eventStore.js +120 -0
- package/dist/tracer/eventStore.js.map +1 -0
- package/dist/tracer/index.d.ts +8 -0
- package/dist/tracer/index.d.ts.map +1 -0
- package/dist/tracer/index.js +24 -0
- package/dist/tracer/index.js.map +1 -0
- package/dist/tracer/nullTracer.d.ts +127 -0
- package/dist/tracer/nullTracer.d.ts.map +1 -0
- package/dist/tracer/nullTracer.js +148 -0
- package/dist/tracer/nullTracer.js.map +1 -0
- package/dist/tracer/tracerEvents.d.ts +209 -0
- package/dist/tracer/tracerEvents.d.ts.map +1 -0
- package/dist/tracer/tracerEvents.js +312 -0
- package/dist/tracer/tracerEvents.js.map +1 -0
- package/dist/tracer/tracerSystem.d.ts +149 -0
- package/dist/tracer/tracerSystem.d.ts.map +1 -0
- package/dist/tracer/tracerSystem.js +196 -0
- package/dist/tracer/tracerSystem.js.map +1 -0
- 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
|
+
[](https://www.npmjs.com/package/mojentic)
|
|
4
|
+
[](LICENSE)
|
|
5
|
+
[](https://www.typescriptlang.org/)
|
|
6
|
+
[](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"}
|