@agentxjs/core 1.9.1-dev
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/package.json +31 -0
- package/src/agent/AgentStateMachine.ts +151 -0
- package/src/agent/README.md +296 -0
- package/src/agent/__tests__/AgentStateMachine.test.ts +346 -0
- package/src/agent/__tests__/createAgent.test.ts +728 -0
- package/src/agent/__tests__/engine/internal/messageAssemblerProcessor.test.ts +567 -0
- package/src/agent/__tests__/engine/internal/stateEventProcessor.test.ts +315 -0
- package/src/agent/__tests__/engine/internal/turnTrackerProcessor.test.ts +340 -0
- package/src/agent/__tests__/engine/mealy/Mealy.test.ts +370 -0
- package/src/agent/__tests__/engine/mealy/Store.test.ts +123 -0
- package/src/agent/__tests__/engine/mealy/combinators.test.ts +322 -0
- package/src/agent/createAgent.ts +467 -0
- package/src/agent/engine/AgentProcessor.ts +106 -0
- package/src/agent/engine/MealyMachine.ts +184 -0
- package/src/agent/engine/internal/index.ts +35 -0
- package/src/agent/engine/internal/messageAssemblerProcessor.ts +550 -0
- package/src/agent/engine/internal/stateEventProcessor.ts +313 -0
- package/src/agent/engine/internal/turnTrackerProcessor.ts +239 -0
- package/src/agent/engine/mealy/Mealy.ts +308 -0
- package/src/agent/engine/mealy/Processor.ts +70 -0
- package/src/agent/engine/mealy/Sink.ts +56 -0
- package/src/agent/engine/mealy/Source.ts +51 -0
- package/src/agent/engine/mealy/Store.ts +98 -0
- package/src/agent/engine/mealy/combinators.ts +176 -0
- package/src/agent/engine/mealy/index.ts +45 -0
- package/src/agent/index.ts +106 -0
- package/src/agent/types/engine.ts +395 -0
- package/src/agent/types/event.ts +478 -0
- package/src/agent/types/index.ts +197 -0
- package/src/agent/types/message.ts +387 -0
- package/src/common/index.ts +8 -0
- package/src/common/logger/ConsoleLogger.ts +137 -0
- package/src/common/logger/LoggerFactoryImpl.ts +123 -0
- package/src/common/logger/index.ts +26 -0
- package/src/common/logger/types.ts +98 -0
- package/src/container/Container.ts +185 -0
- package/src/container/index.ts +44 -0
- package/src/container/types.ts +71 -0
- package/src/driver/index.ts +42 -0
- package/src/driver/types.ts +363 -0
- package/src/event/EventBus.ts +260 -0
- package/src/event/README.md +237 -0
- package/src/event/__tests__/EventBus.test.ts +251 -0
- package/src/event/index.ts +46 -0
- package/src/event/types/agent.ts +512 -0
- package/src/event/types/base.ts +241 -0
- package/src/event/types/bus.ts +429 -0
- package/src/event/types/command.ts +749 -0
- package/src/event/types/container.ts +471 -0
- package/src/event/types/driver.ts +452 -0
- package/src/event/types/index.ts +26 -0
- package/src/event/types/session.ts +314 -0
- package/src/image/Image.ts +203 -0
- package/src/image/index.ts +36 -0
- package/src/image/types.ts +77 -0
- package/src/index.ts +20 -0
- package/src/mq/OffsetGenerator.ts +48 -0
- package/src/mq/README.md +166 -0
- package/src/mq/__tests__/OffsetGenerator.test.ts +121 -0
- package/src/mq/index.ts +18 -0
- package/src/mq/types.ts +172 -0
- package/src/network/RpcClient.ts +455 -0
- package/src/network/index.ts +76 -0
- package/src/network/jsonrpc.ts +336 -0
- package/src/network/protocol.ts +90 -0
- package/src/network/types.ts +284 -0
- package/src/persistence/index.ts +27 -0
- package/src/persistence/types.ts +226 -0
- package/src/runtime/AgentXRuntime.ts +501 -0
- package/src/runtime/index.ts +56 -0
- package/src/runtime/types.ts +236 -0
- package/src/session/Session.ts +71 -0
- package/src/session/index.ts +25 -0
- package/src/session/types.ts +77 -0
- package/src/workspace/index.ts +27 -0
- package/src/workspace/types.ts +131 -0
- package/tsconfig.json +10 -0
package/package.json
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@agentxjs/core",
|
|
3
|
+
"version": "1.9.1-dev",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"exports": {
|
|
6
|
+
".": "./src/index.ts",
|
|
7
|
+
"./common": "./src/common/index.ts",
|
|
8
|
+
"./agent": "./src/agent/index.ts",
|
|
9
|
+
"./driver": "./src/driver/index.ts",
|
|
10
|
+
"./event": "./src/event/index.ts",
|
|
11
|
+
"./session": "./src/session/index.ts",
|
|
12
|
+
"./image": "./src/image/index.ts",
|
|
13
|
+
"./container": "./src/container/index.ts",
|
|
14
|
+
"./workspace": "./src/workspace/index.ts",
|
|
15
|
+
"./runtime": "./src/runtime/index.ts",
|
|
16
|
+
"./mq": "./src/mq/index.ts",
|
|
17
|
+
"./persistence": "./src/persistence/index.ts",
|
|
18
|
+
"./network": "./src/network/index.ts"
|
|
19
|
+
},
|
|
20
|
+
"scripts": {
|
|
21
|
+
"typecheck": "tsc --noEmit",
|
|
22
|
+
"test": "bun test"
|
|
23
|
+
},
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"jsonrpc-lite": "2.2.0",
|
|
26
|
+
"rxjs": "^7.8.2"
|
|
27
|
+
},
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"typescript": "^5.3.3"
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AgentStateMachine - State management driven by StateEvents
|
|
3
|
+
*
|
|
4
|
+
* Manages agent state transitions driven by StateEvents.
|
|
5
|
+
* Single source of truth for agent state in AgentEngine.
|
|
6
|
+
*
|
|
7
|
+
* Flow:
|
|
8
|
+
* StreamEvent → MealyMachine → StateEvent → AgentStateMachine → state update
|
|
9
|
+
*
|
|
10
|
+
* Responsibilities:
|
|
11
|
+
* - Process StateEvents
|
|
12
|
+
* - Maintain current AgentState
|
|
13
|
+
* - Notify state change subscribers
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import type {
|
|
17
|
+
AgentState,
|
|
18
|
+
StateChange,
|
|
19
|
+
StateChangeHandler,
|
|
20
|
+
AgentOutput,
|
|
21
|
+
Unsubscribe,
|
|
22
|
+
} from "./types";
|
|
23
|
+
import { isStateEvent } from "./types";
|
|
24
|
+
import { createLogger } from "commonxjs/logger";
|
|
25
|
+
|
|
26
|
+
const logger = createLogger("agent/AgentStateMachine");
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* AgentStateMachine implementation
|
|
30
|
+
*/
|
|
31
|
+
export class AgentStateMachine {
|
|
32
|
+
private _state: AgentState = "idle";
|
|
33
|
+
private readonly handlers = new Set<StateChangeHandler>();
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Current agent state
|
|
37
|
+
*/
|
|
38
|
+
get state(): AgentState {
|
|
39
|
+
return this._state;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Process an event and update internal state if it's a StateEvent
|
|
44
|
+
*
|
|
45
|
+
* @param event - Event from MealyMachine (could be any AgentOutput)
|
|
46
|
+
*/
|
|
47
|
+
process(event: AgentOutput): void {
|
|
48
|
+
// Only process StateEvents
|
|
49
|
+
if (!isStateEvent(event)) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const prev = this._state;
|
|
54
|
+
const next = this.mapEventToState(event);
|
|
55
|
+
|
|
56
|
+
if (next !== null && prev !== next) {
|
|
57
|
+
this._state = next;
|
|
58
|
+
logger.debug("State transition", {
|
|
59
|
+
eventType: event.type,
|
|
60
|
+
from: prev,
|
|
61
|
+
to: next,
|
|
62
|
+
});
|
|
63
|
+
this.notifyHandlers({ prev, current: next });
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Subscribe to state changes
|
|
69
|
+
*
|
|
70
|
+
* @param handler - Callback receiving { prev, current } state change
|
|
71
|
+
* @returns Unsubscribe function
|
|
72
|
+
*/
|
|
73
|
+
onStateChange(handler: StateChangeHandler): Unsubscribe {
|
|
74
|
+
this.handlers.add(handler);
|
|
75
|
+
return () => {
|
|
76
|
+
this.handlers.delete(handler);
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Reset state machine (used on destroy)
|
|
82
|
+
*/
|
|
83
|
+
reset(): void {
|
|
84
|
+
const prev = this._state;
|
|
85
|
+
this._state = "idle";
|
|
86
|
+
|
|
87
|
+
// Notify handlers of reset to idle
|
|
88
|
+
if (prev !== "idle") {
|
|
89
|
+
this.notifyHandlers({ prev, current: "idle" });
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
this.handlers.clear();
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Map StateEvent type to AgentState
|
|
97
|
+
*
|
|
98
|
+
* @param event - StateEvent from MealyMachine
|
|
99
|
+
* @returns New AgentState or null if no transition needed
|
|
100
|
+
*/
|
|
101
|
+
private mapEventToState(event: AgentOutput): AgentState | null {
|
|
102
|
+
switch (event.type) {
|
|
103
|
+
// Conversation lifecycle
|
|
104
|
+
case "conversation_start":
|
|
105
|
+
return "thinking";
|
|
106
|
+
case "conversation_thinking":
|
|
107
|
+
return "thinking";
|
|
108
|
+
case "conversation_responding":
|
|
109
|
+
return "responding";
|
|
110
|
+
case "conversation_end":
|
|
111
|
+
return "idle";
|
|
112
|
+
case "conversation_interrupted":
|
|
113
|
+
return "idle";
|
|
114
|
+
|
|
115
|
+
// Tool lifecycle
|
|
116
|
+
case "tool_planned":
|
|
117
|
+
return "planning_tool";
|
|
118
|
+
case "tool_executing":
|
|
119
|
+
return "awaiting_tool_result";
|
|
120
|
+
case "tool_completed":
|
|
121
|
+
return "responding";
|
|
122
|
+
case "tool_failed":
|
|
123
|
+
return "responding";
|
|
124
|
+
|
|
125
|
+
// Error
|
|
126
|
+
case "error_occurred":
|
|
127
|
+
return "error";
|
|
128
|
+
|
|
129
|
+
default:
|
|
130
|
+
// Unknown event type, no state change
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Notify all registered handlers of state change
|
|
137
|
+
*/
|
|
138
|
+
private notifyHandlers(change: StateChange): void {
|
|
139
|
+
for (const handler of this.handlers) {
|
|
140
|
+
try {
|
|
141
|
+
handler(change);
|
|
142
|
+
} catch (error) {
|
|
143
|
+
logger.error("State change handler error", {
|
|
144
|
+
from: change.prev,
|
|
145
|
+
to: change.current,
|
|
146
|
+
error,
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
# @agentxjs/core/agent
|
|
2
|
+
|
|
3
|
+
Event Processing Unit for AI Conversations - Pure Mealy Machine implementation.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The agent module is the core event processing engine of AgentX. It transforms raw stream events from LLM providers into structured, typed events for UI consumption.
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
StreamEvent (from LLM) AgentOutput (to UI)
|
|
11
|
+
│ ▲
|
|
12
|
+
▼ │
|
|
13
|
+
┌─────────────────────────────┴───┐
|
|
14
|
+
│ MealyMachine │
|
|
15
|
+
│ ┌───────────────────────────┐ │
|
|
16
|
+
│ │ AgentProcessor │ │
|
|
17
|
+
│ │ ┌─────────────────────┐ │ │
|
|
18
|
+
│ │ │ MessageAssembler │──┼──┼──► MessageEvent
|
|
19
|
+
│ │ ├─────────────────────┤ │ │
|
|
20
|
+
│ │ │ StateEventProcessor │──┼──┼──► StateEvent
|
|
21
|
+
│ │ ├─────────────────────┤ │ │
|
|
22
|
+
│ │ │ TurnTracker │──┼──┼──► TurnEvent
|
|
23
|
+
│ │ └─────────────────────┘ │ │
|
|
24
|
+
│ └───────────────────────────┘ │
|
|
25
|
+
└─────────────────────────────────┘
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Key Concepts
|
|
29
|
+
|
|
30
|
+
### Mealy Machine Pattern
|
|
31
|
+
|
|
32
|
+
The core insight is that **state is a means, outputs are the goal**.
|
|
33
|
+
|
|
34
|
+
```typescript
|
|
35
|
+
// Traditional Redux: state is the goal
|
|
36
|
+
(state, action) => newState
|
|
37
|
+
|
|
38
|
+
// Mealy Machine: outputs are the goal
|
|
39
|
+
(state, input) => [newState, outputs]
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
This pattern enables:
|
|
43
|
+
|
|
44
|
+
- Pure functions (testable, no side effects)
|
|
45
|
+
- Event chaining (outputs can trigger more processing)
|
|
46
|
+
- Stateless processors (state managed externally)
|
|
47
|
+
|
|
48
|
+
### Event Layers
|
|
49
|
+
|
|
50
|
+
| Layer | Events | Purpose |
|
|
51
|
+
| ----------- | ------------------------------------------------------------------- | -------------------- |
|
|
52
|
+
| **Stream** | `message_start`, `text_delta`, `tool_use_start`, `message_stop` | Raw LLM events |
|
|
53
|
+
| **Message** | `assistant_message`, `tool_call_message`, `tool_result_message` | Complete messages |
|
|
54
|
+
| **State** | `conversation_start`, `conversation_responding`, `conversation_end` | UI state transitions |
|
|
55
|
+
| **Turn** | `turn_request`, `turn_response` | Analytics & billing |
|
|
56
|
+
|
|
57
|
+
## Usage
|
|
58
|
+
|
|
59
|
+
### Basic Usage
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
import { createAgent, type AgentDriver, type AgentPresenter } from "@agentxjs/core/agent";
|
|
63
|
+
|
|
64
|
+
// Define a driver (produces stream events)
|
|
65
|
+
const driver: AgentDriver = {
|
|
66
|
+
receive: async function* (message) {
|
|
67
|
+
yield { type: "message_start", data: { messageId: "msg_1" }, timestamp: Date.now() };
|
|
68
|
+
yield { type: "text_delta", data: { text: "Hello!" }, timestamp: Date.now() };
|
|
69
|
+
yield { type: "message_stop", data: { stopReason: "end_turn" }, timestamp: Date.now() };
|
|
70
|
+
},
|
|
71
|
+
interrupt: () => {},
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
// Define a presenter (consumes agent output)
|
|
75
|
+
const presenter: AgentPresenter = {
|
|
76
|
+
present: (agentId, event) => {
|
|
77
|
+
console.log(`[${agentId}] ${event.type}:`, event.data);
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
// Create agent
|
|
82
|
+
const agent = createAgent({ driver, presenter });
|
|
83
|
+
|
|
84
|
+
// Subscribe to events
|
|
85
|
+
agent.on("text_delta", (e) => console.log(e.data.text));
|
|
86
|
+
agent.on("assistant_message", (e) => console.log("Complete:", e.data.content));
|
|
87
|
+
|
|
88
|
+
// Send message
|
|
89
|
+
await agent.receive("Hello, AI!");
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### React-style Handlers
|
|
93
|
+
|
|
94
|
+
```typescript
|
|
95
|
+
agent.react({
|
|
96
|
+
onTextDelta: (e) => updateUI(e.data.text),
|
|
97
|
+
onAssistantMessage: (e) => saveMessage(e.data),
|
|
98
|
+
onConversationStart: () => showThinking(),
|
|
99
|
+
onConversationEnd: () => hideThinking(),
|
|
100
|
+
});
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### State Machine
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
import { AgentStateMachine } from "@agentxjs/core/agent";
|
|
107
|
+
|
|
108
|
+
const stateMachine = new AgentStateMachine();
|
|
109
|
+
|
|
110
|
+
stateMachine.onStateChange(({ prev, current }) => {
|
|
111
|
+
console.log(`State: ${prev} → ${current}`);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
// States: idle → thinking → responding → idle
|
|
115
|
+
// ↓
|
|
116
|
+
// planning_tool → awaiting_tool_result → responding
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Custom Processors
|
|
120
|
+
|
|
121
|
+
```typescript
|
|
122
|
+
import { combineProcessors, filterProcessor, type Processor } from "@agentxjs/core/agent";
|
|
123
|
+
|
|
124
|
+
// Create a custom processor
|
|
125
|
+
const myProcessor: Processor<MyState, StreamEvent, MyOutput> = (state, input) => {
|
|
126
|
+
if (input.type === "text_delta") {
|
|
127
|
+
return [state, [{ type: "custom_event", data: input.data }]];
|
|
128
|
+
}
|
|
129
|
+
return [state, []];
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
// Combine with existing processors
|
|
133
|
+
const combined = combineProcessors({
|
|
134
|
+
message: messageAssemblerProcessor,
|
|
135
|
+
custom: myProcessor,
|
|
136
|
+
});
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Architecture
|
|
140
|
+
|
|
141
|
+
### Directory Structure
|
|
142
|
+
|
|
143
|
+
```
|
|
144
|
+
agent/
|
|
145
|
+
├── createAgent.ts # AgentEngine factory
|
|
146
|
+
├── AgentStateMachine.ts # State management
|
|
147
|
+
├── index.ts # Public exports
|
|
148
|
+
│
|
|
149
|
+
└── engine/
|
|
150
|
+
├── MealyMachine.ts # Mealy runtime with state store
|
|
151
|
+
├── AgentProcessor.ts # Combined processor
|
|
152
|
+
│
|
|
153
|
+
├── mealy/ # Mealy framework
|
|
154
|
+
│ ├── Source.ts # Input adapter type
|
|
155
|
+
│ ├── Processor.ts # Pure transition function type
|
|
156
|
+
│ ├── Sink.ts # Output adapter type
|
|
157
|
+
│ ├── Store.ts # State storage interface
|
|
158
|
+
│ ├── Mealy.ts # Runtime orchestrator
|
|
159
|
+
│ └── combinators.ts # Processor composition utilities
|
|
160
|
+
│
|
|
161
|
+
└── internal/ # Built-in processors
|
|
162
|
+
├── messageAssemblerProcessor.ts
|
|
163
|
+
├── stateEventProcessor.ts
|
|
164
|
+
└── turnTrackerProcessor.ts
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Component Responsibilities
|
|
168
|
+
|
|
169
|
+
| Component | Responsibility |
|
|
170
|
+
| --------------------- | -------------------------------------- |
|
|
171
|
+
| `AgentEngine` | Coordinate driver, machine, presenter |
|
|
172
|
+
| `MealyMachine` | Process events, manage state per agent |
|
|
173
|
+
| `AgentProcessor` | Combine all internal processors |
|
|
174
|
+
| `MessageAssembler` | Stream → Message events |
|
|
175
|
+
| `StateEventProcessor` | Stream → State events |
|
|
176
|
+
| `TurnTracker` | Message → Turn events |
|
|
177
|
+
| `AgentStateMachine` | Track agent state from StateEvents |
|
|
178
|
+
|
|
179
|
+
## API Reference
|
|
180
|
+
|
|
181
|
+
### createAgent(options)
|
|
182
|
+
|
|
183
|
+
```typescript
|
|
184
|
+
function createAgent(options: CreateAgentOptions): AgentEngine;
|
|
185
|
+
|
|
186
|
+
interface CreateAgentOptions {
|
|
187
|
+
driver: AgentDriver;
|
|
188
|
+
presenter: AgentPresenter;
|
|
189
|
+
}
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### AgentEngine
|
|
193
|
+
|
|
194
|
+
```typescript
|
|
195
|
+
interface AgentEngine {
|
|
196
|
+
readonly agentId: string;
|
|
197
|
+
readonly state: AgentState;
|
|
198
|
+
readonly messageQueue: MessageQueue;
|
|
199
|
+
|
|
200
|
+
// Send message
|
|
201
|
+
receive(message: string | UserMessage): Promise<void>;
|
|
202
|
+
|
|
203
|
+
// Event subscription
|
|
204
|
+
on(handler: AgentOutputCallback): Unsubscribe;
|
|
205
|
+
on(type: string, handler: AgentOutputCallback): Unsubscribe;
|
|
206
|
+
on(handlers: EventHandlerMap): Unsubscribe;
|
|
207
|
+
react(handlers: ReactHandlerMap): Unsubscribe;
|
|
208
|
+
|
|
209
|
+
// State subscription
|
|
210
|
+
onStateChange(handler: StateChangeHandler): Unsubscribe;
|
|
211
|
+
|
|
212
|
+
// Lifecycle
|
|
213
|
+
onReady(handler: () => void): Unsubscribe;
|
|
214
|
+
onDestroy(handler: () => void): Unsubscribe;
|
|
215
|
+
|
|
216
|
+
// Middleware
|
|
217
|
+
use(middleware: AgentMiddleware): Unsubscribe;
|
|
218
|
+
intercept(interceptor: AgentInterceptor): Unsubscribe;
|
|
219
|
+
|
|
220
|
+
// Control
|
|
221
|
+
interrupt(): void;
|
|
222
|
+
destroy(): Promise<void>;
|
|
223
|
+
}
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### Processor Type
|
|
227
|
+
|
|
228
|
+
```typescript
|
|
229
|
+
type Processor<TState, TInput, TOutput> = (
|
|
230
|
+
state: Readonly<TState>,
|
|
231
|
+
input: TInput
|
|
232
|
+
) => [TState, TOutput[]];
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
### Combinators
|
|
236
|
+
|
|
237
|
+
```typescript
|
|
238
|
+
// Combine multiple processors (parallel)
|
|
239
|
+
combineProcessors<TState, TInput, TOutput>(processors): Processor;
|
|
240
|
+
|
|
241
|
+
// Chain processors (sequential)
|
|
242
|
+
chainProcessors<TState, TEvent>(...processors): Processor;
|
|
243
|
+
|
|
244
|
+
// Filter events before processing
|
|
245
|
+
filterProcessor<TState, TInput, TOutput>(
|
|
246
|
+
predicate: (event: TInput) => boolean,
|
|
247
|
+
processor: Processor
|
|
248
|
+
): Processor;
|
|
249
|
+
|
|
250
|
+
// Transform outputs
|
|
251
|
+
mapOutput<TState, TInput, TOutput, TMapped>(
|
|
252
|
+
processor: Processor,
|
|
253
|
+
mapper: (output: TOutput) => TMapped
|
|
254
|
+
): Processor;
|
|
255
|
+
|
|
256
|
+
// Add logging
|
|
257
|
+
withLogging<TState, TInput, TOutput>(
|
|
258
|
+
processor: Processor,
|
|
259
|
+
name: string
|
|
260
|
+
): Processor;
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
## Testing
|
|
264
|
+
|
|
265
|
+
```bash
|
|
266
|
+
cd packages-new/core
|
|
267
|
+
bun test
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
```
|
|
271
|
+
✅ 175 tests pass
|
|
272
|
+
✅ 0 fail
|
|
273
|
+
✅ 265ms
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### Test Coverage
|
|
277
|
+
|
|
278
|
+
- Mealy framework: Store, combinators, runtime
|
|
279
|
+
- Internal processors: message assembly, state events, turn tracking
|
|
280
|
+
- AgentStateMachine: state transitions, subscriptions
|
|
281
|
+
- createAgent: full agent lifecycle, middleware, interceptors
|
|
282
|
+
|
|
283
|
+
## Platform Independence
|
|
284
|
+
|
|
285
|
+
This module has **zero platform dependencies**:
|
|
286
|
+
|
|
287
|
+
- No `node:*` imports
|
|
288
|
+
- No `bun:*` imports
|
|
289
|
+
- No `ws`, `ioredis`, or other platform-specific packages
|
|
290
|
+
- Only depends on `rxjs` (pure JavaScript)
|
|
291
|
+
|
|
292
|
+
Can run in: Node.js, Bun, Deno, Cloudflare Workers, Browser.
|
|
293
|
+
|
|
294
|
+
## License
|
|
295
|
+
|
|
296
|
+
MIT
|