@agent-glue/glue 0.1.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 (51) hide show
  1. package/.turbo/turbo-build.log +5 -0
  2. package/.turbo/turbo-clean$colon$build.log +1 -0
  3. package/.turbo/turbo-format$colon$fix.log +46 -0
  4. package/.turbo/turbo-format.log +13 -0
  5. package/.turbo/turbo-lint$colon$fix.log +9 -0
  6. package/.turbo/turbo-lint.log +5 -0
  7. package/.turbo/turbo-test.log +27 -0
  8. package/.turbo/turbo-typecheck.log +5 -0
  9. package/CHANGELOG.md +7 -0
  10. package/LICENSE +21 -0
  11. package/dist/Actor.d.ts +51 -0
  12. package/dist/Actor.js +30 -0
  13. package/dist/actor.js +32 -0
  14. package/dist/actors/examples/timer.d.ts +1 -0
  15. package/dist/actors/examples/timer.js +1 -0
  16. package/dist/actors/langchain/llm.d.ts +40 -0
  17. package/dist/actors/langchain/llm.js +52 -0
  18. package/dist/constructors.js +1 -0
  19. package/dist/effects.js +66 -0
  20. package/dist/emitter.js +19 -0
  21. package/dist/index.d.ts +1 -0
  22. package/dist/index.js +1 -0
  23. package/dist/message.js +18 -0
  24. package/dist/message.test.js +37 -0
  25. package/dist/server/memory.js +46 -0
  26. package/dist/server/protocol.js +4 -0
  27. package/dist/server/websocket.js +72 -0
  28. package/dist/server.js +3 -0
  29. package/dist/transformers.d.ts +41 -0
  30. package/dist/transformers.js +17 -0
  31. package/dist/tsconfig.tsbuildinfo +1 -0
  32. package/dist/types.js +1 -0
  33. package/dist/utils/TypedEmitter.d.ts +15 -0
  34. package/dist/utils/TypedEmitter.js +16 -0
  35. package/eslint.config.js +4 -0
  36. package/nodemon.json +7 -0
  37. package/package.json +75 -0
  38. package/src/actor.ts +69 -0
  39. package/src/effects.ts +88 -0
  40. package/src/emitter.ts +22 -0
  41. package/src/index.ts +1 -0
  42. package/src/message.test.ts +52 -0
  43. package/src/message.ts +54 -0
  44. package/src/server/memory.ts +77 -0
  45. package/src/server/protocol.ts +36 -0
  46. package/src/server/websocket.ts +137 -0
  47. package/src/server.ts +3 -0
  48. package/src/transformers.ts +66 -0
  49. package/src/types.ts +7 -0
  50. package/src/utils/TypedEmitter.ts +30 -0
  51. package/tsconfig.json +8 -0
@@ -0,0 +1,77 @@
1
+ import { Actor, ActorInterface } from "../actor.js";
2
+ import { defineMessage, Message } from "../message.js";
3
+ import {
4
+ Commands,
5
+ Connect,
6
+ event,
7
+ Events,
8
+ isConnect,
9
+ isSend,
10
+ Send
11
+ } from "./protocol.js";
12
+
13
+ export interface LocalConnect extends Connect {
14
+ destination: string;
15
+ callback: (msg: Message) => void;
16
+ }
17
+ export const {
18
+ message: localConnect,
19
+ isMessage: isLocalConnect,
20
+ type: LocalConnectType
21
+ } = defineMessage<LocalConnect>("local-connect");
22
+
23
+ export interface LocalRegister extends Message {
24
+ name: string;
25
+ actor: Actor<Message, Message>;
26
+ }
27
+ export const {
28
+ message: localRegister,
29
+ isMessage: isLocalRegister,
30
+ type: LocalRegisterType
31
+ } = defineMessage<LocalRegister>("local-register");
32
+
33
+ export type LocalCommands = Send | LocalConnect | LocalRegister;
34
+ export type LocalServerActor = ActorInterface<LocalCommands, never>;
35
+
36
+ export class LocalServer extends Actor<LocalCommands, never> {
37
+ private store = new Map<string, Actor<Message, Message>>();
38
+
39
+ send(command: LocalCommands) {
40
+ if (isSend(command)) {
41
+ const { destination, message } = command;
42
+ const actor = this.store.get(destination);
43
+ if (actor) {
44
+ actor.send(message);
45
+ }
46
+ } else if (isLocalConnect(command)) {
47
+ const { destination, callback } = command;
48
+ const actor = this.store.get(destination);
49
+ if (actor) {
50
+ actor.connect(callback);
51
+ }
52
+ } else if (isLocalRegister(command)) {
53
+ const { name, actor } = command;
54
+ this.store.set(name, actor);
55
+ }
56
+ }
57
+ }
58
+
59
+ export class MemoryClient extends Actor<Commands, Events> {
60
+ constructor(private server: LocalServerActor) {
61
+ super();
62
+ }
63
+
64
+ send(command: Commands): void {
65
+ if (isSend(command)) {
66
+ this.server.send(command);
67
+ } else if (isConnect(command)) {
68
+ this.server.send(
69
+ localConnect({
70
+ destination: command.destination,
71
+ callback: (msg) =>
72
+ this.emit(event({ origin: command.destination, message: msg }))
73
+ })
74
+ );
75
+ }
76
+ }
77
+ }
@@ -0,0 +1,36 @@
1
+ import { ActorInterface } from "../actor.js";
2
+ import { defineMessage, Message } from "../message.js";
3
+
4
+ export interface Send extends Message {
5
+ destination: string;
6
+ message: Message;
7
+ }
8
+ export const {
9
+ message: send,
10
+ isMessage: isSend,
11
+ type: SendType
12
+ } = defineMessage<Send>("send");
13
+
14
+ export interface Connect extends Message {
15
+ destination: string;
16
+ }
17
+ export const {
18
+ message: connect,
19
+ isMessage: isConnect,
20
+ type: ConnectType
21
+ } = defineMessage<Connect>("connect");
22
+
23
+ export interface Event extends Message {
24
+ origin: string;
25
+ message: Message;
26
+ }
27
+ export const {
28
+ message: event,
29
+ isMessage: isEvent,
30
+ type: EventType
31
+ } = defineMessage<Event>("event");
32
+
33
+ export type Commands = Send | Connect;
34
+ export type Events = Event;
35
+
36
+ export type ServerActor = ActorInterface<Commands, Events>;
@@ -0,0 +1,137 @@
1
+ import { Actor, ActorInterface } from "../actor.js";
2
+ import { defineMessage, Message } from "../message.js";
3
+ import type {
4
+ WebSocketServer as NodeWebSocketServer,
5
+ WebSocket as NodeWebsocket
6
+ } from "ws";
7
+
8
+ export interface SendCommand extends Message {
9
+ message: string;
10
+ }
11
+ export const {
12
+ message: sendCommand,
13
+ isMessage: isSendCommand,
14
+ type: SendCommandType
15
+ } = defineMessage<SendCommand>("send-command");
16
+
17
+ type OpenEvent = Message;
18
+ export const {
19
+ message: openEvent,
20
+ isMessage: isOpenEvent,
21
+ type: OpenEventType
22
+ } = defineMessage<OpenEvent>("open-event");
23
+
24
+ type CloseEvent = Message;
25
+ export const {
26
+ message: closeEvent,
27
+ isMessage: isCloseEvent,
28
+ type: CloseEventType
29
+ } = defineMessage<CloseEvent>("close-event");
30
+
31
+ export interface ErrorEvent extends Message {
32
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
33
+ error: any;
34
+ }
35
+ export const {
36
+ message: errorEvent,
37
+ isMessage: isErrorEvent,
38
+ type: ErrorEventType
39
+ } = defineMessage<ErrorEvent>("error-event");
40
+ export interface MessageEvent extends Message {
41
+ message: string;
42
+ }
43
+ export const {
44
+ message: messageEvent,
45
+ isMessage: isMessageEvent,
46
+ type: MessageEventType
47
+ } = defineMessage<MessageEvent>("message-event");
48
+
49
+ export type WebsocketCommands = SendCommand;
50
+ export type WebsocketEvents =
51
+ | OpenEvent
52
+ | CloseEvent
53
+ | ErrorEvent
54
+ | MessageEvent;
55
+
56
+ export class WebsocketClient extends Actor<WebsocketCommands, WebsocketEvents> {
57
+ constructor(private readonly ws: WebSocket | NodeWebsocket) {
58
+ super();
59
+
60
+ ws.addEventListener("open", () => {
61
+ this.emit(openEvent({}));
62
+ });
63
+ ws.addEventListener("message", (event) => {
64
+ this.emit(messageEvent({ message: event.data }));
65
+ });
66
+ ws.addEventListener("close", () => {
67
+ this.emit(closeEvent({}));
68
+ });
69
+ ws.addEventListener("error", (event) => {
70
+ this.emit(errorEvent({ error: event }));
71
+ });
72
+ }
73
+
74
+ send(command: WebsocketCommands) {
75
+ if (isSendCommand(command)) {
76
+ this.ws.send(command.message);
77
+ }
78
+ }
79
+ }
80
+
81
+ export class WebsocketClientWrapper<
82
+ Commands extends Message,
83
+ Events extends Message
84
+ > extends Actor<Commands, Events> {
85
+ private readonly client: WebsocketClient;
86
+
87
+ constructor(private readonly ws: WebSocket | NodeWebsocket) {
88
+ super();
89
+ this.client = new WebsocketClient(ws);
90
+
91
+ this.client.connect((event) => {
92
+ if (isMessageEvent(event)) {
93
+ const message = JSON.parse(event.message) as Events;
94
+ this.emit(message);
95
+ }
96
+ });
97
+ }
98
+
99
+ send(command: Commands) {
100
+ this.client.send(sendCommand({ message: JSON.stringify(command) }));
101
+ }
102
+ }
103
+
104
+ export interface ConnectionEvent extends Message {
105
+ ws: NodeWebsocket;
106
+ }
107
+ export const {
108
+ message: connectionEvent,
109
+ isMessage: isConnectionEvent,
110
+ type: ConnectionEventType
111
+ } = defineMessage<ConnectionEvent>("connection-event");
112
+
113
+ export class WebsocketServer extends Actor<WebsocketCommands, WebsocketEvents> {
114
+ constructor(private readonly wss: NodeWebSocketServer) {
115
+ super();
116
+
117
+ this.wss.on("connection", (ws) => {
118
+ this.emit(connectionEvent({ ws }));
119
+ });
120
+ }
121
+ }
122
+
123
+ export class WebsocketServerWrapper<
124
+ Commands extends Message,
125
+ Events extends Message
126
+ > {
127
+ constructor(ws: NodeWebsocket, actor: ActorInterface<Commands, Events>) {
128
+ //const client = new WebsocketClient(ws);
129
+ const wrapper = new WebsocketClientWrapper<Events, Commands>(ws);
130
+ wrapper.connect((command) => {
131
+ actor.send(command);
132
+ });
133
+ actor.connect((event) => {
134
+ wrapper.send(event);
135
+ });
136
+ }
137
+ }
package/src/server.ts ADDED
@@ -0,0 +1,3 @@
1
+ export * from "./server/protocol.js";
2
+ export * from "./server/memory.js";
3
+ export * from "./server/websocket.js";
@@ -0,0 +1,66 @@
1
+ import { ActorInterface, actor } from "./actor.js";
2
+ import { Message } from "./message.js";
3
+
4
+ export type Replace<U, A, B> = Exclude<U, A> | B;
5
+
6
+ export type ActorTransformer<
7
+ A extends ActorInterface<C1, E1>,
8
+ B extends ActorInterface<C2, E2>,
9
+ C1 extends Message = never,
10
+ C2 extends Message = never,
11
+ E1 extends Message = never,
12
+ E2 extends Message = never
13
+ > = (a: A) => B;
14
+
15
+ export type CommandTransformer<
16
+ OldCommands extends Message,
17
+ NewCommands extends Message,
18
+ E extends Message = never,
19
+ A extends ActorInterface<OldCommands, E> = ActorInterface<OldCommands, E>,
20
+ B extends ActorInterface<NewCommands, E> = ActorInterface<NewCommands, E>
21
+ > = ActorTransformer<A, B, OldCommands, NewCommands, E, E>;
22
+
23
+ export type EventTransformer<
24
+ NewEvents extends Message,
25
+ OldEvents extends Message,
26
+ C extends Message = never,
27
+ A extends ActorInterface<C, OldEvents> = ActorInterface<C, OldEvents>,
28
+ B extends ActorInterface<C, NewEvents> = ActorInterface<C, NewEvents>
29
+ > = ActorTransformer<A, B, C, C, OldEvents, NewEvents>;
30
+
31
+ export type TransformerFunction<A extends Message, B extends Message> = (
32
+ message: A
33
+ ) => B;
34
+
35
+ export function commandTransformer<
36
+ OldCommands extends Message,
37
+ NewCommands extends Message,
38
+ Events extends Message = never
39
+ >(
40
+ fn: TransformerFunction<NewCommands, OldCommands>
41
+ ): CommandTransformer<OldCommands, NewCommands, Events> {
42
+ return (wrapped: ActorInterface<OldCommands, Events>) =>
43
+ actor((emit) => {
44
+ wrapped.connect(emit);
45
+
46
+ return (command) => {
47
+ wrapped.send(fn(command));
48
+ };
49
+ });
50
+ }
51
+
52
+ export function eventTransformer<
53
+ OldEvents extends Message,
54
+ NewEvents extends Message,
55
+ Commands extends Message = never
56
+ >(
57
+ fn: TransformerFunction<OldEvents, NewEvents>
58
+ ): EventTransformer<NewEvents, OldEvents, Commands> {
59
+ return (wrapped: ActorInterface<Commands, OldEvents>) =>
60
+ actor((emit) => {
61
+ wrapped.connect((msg) => {
62
+ emit(fn(msg));
63
+ });
64
+ return (command) => wrapped.send(command);
65
+ });
66
+ }
package/src/types.ts ADDED
@@ -0,0 +1,7 @@
1
+ import { ActorInterface } from "./actor.js";
2
+ import { Message } from "./message.js";
3
+
4
+ export type Events<T> = T extends ActorInterface<Message, infer E> ? E : never;
5
+ export type Commands<T> = T extends ActorInterface<infer C, Message>
6
+ ? C
7
+ : never;
@@ -0,0 +1,30 @@
1
+ import EventEmitter from "node:events";
2
+
3
+ export class TypedEmitter<TEvents extends Record<string, unknown>> {
4
+ private emitter = new EventEmitter();
5
+
6
+ emit<TEventName extends keyof TEvents & string>(
7
+ eventName: TEventName,
8
+ eventArg: TEvents[TEventName]
9
+ ) {
10
+ this.emitter.emit(eventName, eventArg);
11
+ }
12
+
13
+ on<TEventName extends keyof TEvents & string>(
14
+ eventName: TEventName,
15
+ handler: (eventArg: TEvents[TEventName]) => void
16
+ ) {
17
+ this.emitter.on(eventName, handler);
18
+ }
19
+
20
+ off<TEventName extends keyof TEvents & string>(
21
+ eventName: TEventName,
22
+ handler: (eventArg: TEvents[TEventName]) => void
23
+ ) {
24
+ this.emitter.off(eventName, handler);
25
+ }
26
+
27
+ removeAllListeners() {
28
+ this.emitter.removeAllListeners();
29
+ }
30
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,8 @@
1
+ {
2
+ "extends": "@repo/typescript-config/tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "outDir": "dist"
5
+ },
6
+ "include": ["src"],
7
+ "exclude": ["node_modules"]
8
+ }