@memgrafter/flatagents 0.10.0 → 2.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/dist/index.mjs CHANGED
@@ -949,6 +949,179 @@ var LocalFileLock = class {
949
949
  }
950
950
  };
951
951
 
952
+ // src/hooks.ts
953
+ var WebhookHooks = class {
954
+ constructor(url) {
955
+ this.url = url;
956
+ }
957
+ async send(event, data) {
958
+ try {
959
+ const body = JSON.stringify({ event, ...data, timestamp: (/* @__PURE__ */ new Date()).toISOString() }, (key, value) => {
960
+ if (typeof value === "object" && value !== null) {
961
+ const seen = /* @__PURE__ */ new WeakSet();
962
+ return JSON.parse(JSON.stringify(value, (k, v) => {
963
+ if (typeof v === "object" && v !== null) {
964
+ if (seen.has(v)) return "[Circular]";
965
+ seen.add(v);
966
+ }
967
+ return v;
968
+ }));
969
+ }
970
+ return value;
971
+ });
972
+ await fetch(this.url, {
973
+ method: "POST",
974
+ headers: { "Content-Type": "application/json" },
975
+ body
976
+ });
977
+ } catch {
978
+ }
979
+ }
980
+ async onMachineStart(context) {
981
+ await this.send("machine_start", { context });
982
+ return context;
983
+ }
984
+ async onMachineEnd(context, output) {
985
+ await this.send("machine_end", { context, output });
986
+ return output;
987
+ }
988
+ async onStateEnter(state, context) {
989
+ await this.send("state_enter", { state, context });
990
+ return context;
991
+ }
992
+ async onStateExit(state, context, output) {
993
+ await this.send("state_exit", { state, context, output });
994
+ return output;
995
+ }
996
+ async onAction(action, context) {
997
+ await this.send("action", { action, context });
998
+ return context;
999
+ }
1000
+ };
1001
+ var CompositeHooks = class {
1002
+ constructor(hooks) {
1003
+ this.hooks = hooks;
1004
+ }
1005
+ async onMachineStart(context) {
1006
+ let result = context;
1007
+ for (const hook of this.hooks) {
1008
+ if (hook.onMachineStart) {
1009
+ try {
1010
+ result = await hook.onMachineStart(result);
1011
+ } catch {
1012
+ }
1013
+ }
1014
+ }
1015
+ return result;
1016
+ }
1017
+ async onMachineEnd(context, output) {
1018
+ let result = output;
1019
+ for (const hook of this.hooks) {
1020
+ if (hook.onMachineEnd) {
1021
+ try {
1022
+ result = await hook.onMachineEnd(context, result);
1023
+ } catch {
1024
+ }
1025
+ }
1026
+ }
1027
+ return result;
1028
+ }
1029
+ async onStateEnter(state, context) {
1030
+ let result = context;
1031
+ for (const hook of this.hooks) {
1032
+ if (hook.onStateEnter) {
1033
+ try {
1034
+ result = await hook.onStateEnter(state, result);
1035
+ } catch {
1036
+ }
1037
+ }
1038
+ }
1039
+ return result;
1040
+ }
1041
+ async onStateExit(state, context, output) {
1042
+ let result = output;
1043
+ for (const hook of this.hooks) {
1044
+ if (hook.onStateExit) {
1045
+ try {
1046
+ result = await hook.onStateExit(state, context, result);
1047
+ } catch {
1048
+ }
1049
+ }
1050
+ }
1051
+ return result;
1052
+ }
1053
+ async onTransition(from, to, context) {
1054
+ let result = to;
1055
+ for (const hook of this.hooks) {
1056
+ if (hook.onTransition) {
1057
+ try {
1058
+ result = await hook.onTransition(from, result, context);
1059
+ } catch {
1060
+ }
1061
+ }
1062
+ }
1063
+ return result;
1064
+ }
1065
+ async onError(state, error, context) {
1066
+ let result = null;
1067
+ for (const hook of this.hooks) {
1068
+ if (hook.onError) {
1069
+ try {
1070
+ const hookResult = await hook.onError(state, error, context);
1071
+ if (hookResult !== null) result = hookResult;
1072
+ } catch {
1073
+ }
1074
+ }
1075
+ }
1076
+ return result;
1077
+ }
1078
+ async onAction(action, context) {
1079
+ let result = context;
1080
+ for (const hook of this.hooks) {
1081
+ if (hook.onAction) {
1082
+ try {
1083
+ result = await hook.onAction(action, result);
1084
+ } catch {
1085
+ }
1086
+ }
1087
+ }
1088
+ return result;
1089
+ }
1090
+ };
1091
+ var HooksRegistry = class {
1092
+ constructor() {
1093
+ this.factories = /* @__PURE__ */ new Map();
1094
+ }
1095
+ register(name, factory) {
1096
+ this.factories.set(name, factory);
1097
+ }
1098
+ has(name) {
1099
+ return this.factories.has(name);
1100
+ }
1101
+ resolve(ref) {
1102
+ if (Array.isArray(ref)) {
1103
+ const hooks = ref.map((entry) => this.resolveSingle(entry));
1104
+ return new CompositeHooks(hooks);
1105
+ }
1106
+ return this.resolveSingle(ref);
1107
+ }
1108
+ resolveSingle(ref) {
1109
+ const name = typeof ref === "string" ? ref : ref.name;
1110
+ const args = typeof ref === "string" ? void 0 : ref.args;
1111
+ const factory = this.factories.get(name);
1112
+ if (!factory) {
1113
+ throw new Error(
1114
+ `No hooks registered for name '${name}'. Registered: [${[...this.factories.keys()].join(", ")}]`
1115
+ );
1116
+ }
1117
+ try {
1118
+ return new factory(args);
1119
+ } catch {
1120
+ return factory(args);
1121
+ }
1122
+ }
1123
+ };
1124
+
952
1125
  // src/flatmachine.ts
953
1126
  var FlatMachine = class _FlatMachine {
954
1127
  constructor(options) {
@@ -960,7 +1133,8 @@ var FlatMachine = class _FlatMachine {
960
1133
  this.pendingLaunches = [];
961
1134
  this.currentStep = 0;
962
1135
  this.config = typeof options.config === "string" ? yaml3.parse(readFileSync3(options.config, "utf-8")) : options.config;
963
- this.hooks = options.hooks;
1136
+ this._hooksRegistry = options.hooksRegistry ?? new HooksRegistry();
1137
+ this.hooks = this.resolveHooks(options.hooks);
964
1138
  this.configDir = options.configDir ?? process.cwd();
965
1139
  this.profilesFile = this.resolveProfilesFile(options.profilesFile);
966
1140
  this.executionId = options.executionId ?? this.executionId;
@@ -983,6 +1157,15 @@ var FlatMachine = class _FlatMachine {
983
1157
  this.checkpointEvents = new Set(events);
984
1158
  }
985
1159
  }
1160
+ get hooksRegistry() {
1161
+ return this._hooksRegistry;
1162
+ }
1163
+ resolveHooks(explicit) {
1164
+ if (explicit) return explicit;
1165
+ const hooksConfig = this.config.data.hooks;
1166
+ if (!hooksConfig) return void 0;
1167
+ return this._hooksRegistry.resolve(hooksConfig);
1168
+ }
986
1169
  async execute(input, resumeSnapshot) {
987
1170
  if (this.config.data.expression_engine === "cel") {
988
1171
  throw new Error("expression_engine 'cel' is not supported in the JS SDK yet");
@@ -1266,7 +1449,7 @@ var FlatMachine = class _FlatMachine {
1266
1449
  config: resolved.config,
1267
1450
  configDir: resolved.configDir,
1268
1451
  resultBackend: this.resultBackend,
1269
- hooks: this.hooks,
1452
+ hooksRegistry: this._hooksRegistry,
1270
1453
  executionId: overrides?.executionId,
1271
1454
  parentExecutionId: overrides?.parentExecutionId,
1272
1455
  profilesFile: this.profilesFile
@@ -1476,152 +1659,13 @@ var FlatMachine = class _FlatMachine {
1476
1659
  return { [firstKey]: results[firstKey] };
1477
1660
  }
1478
1661
  };
1479
-
1480
- // src/hooks.ts
1481
- var WebhookHooks = class {
1482
- constructor(url) {
1483
- this.url = url;
1484
- }
1485
- async send(event, data) {
1486
- try {
1487
- const body = JSON.stringify({ event, ...data, timestamp: (/* @__PURE__ */ new Date()).toISOString() }, (key, value) => {
1488
- if (typeof value === "object" && value !== null) {
1489
- const seen = /* @__PURE__ */ new WeakSet();
1490
- return JSON.parse(JSON.stringify(value, (k, v) => {
1491
- if (typeof v === "object" && v !== null) {
1492
- if (seen.has(v)) return "[Circular]";
1493
- seen.add(v);
1494
- }
1495
- return v;
1496
- }));
1497
- }
1498
- return value;
1499
- });
1500
- await fetch(this.url, {
1501
- method: "POST",
1502
- headers: { "Content-Type": "application/json" },
1503
- body
1504
- });
1505
- } catch {
1506
- }
1507
- }
1508
- async onMachineStart(context) {
1509
- await this.send("machine_start", { context });
1510
- return context;
1511
- }
1512
- async onMachineEnd(context, output) {
1513
- await this.send("machine_end", { context, output });
1514
- return output;
1515
- }
1516
- async onStateEnter(state, context) {
1517
- await this.send("state_enter", { state, context });
1518
- return context;
1519
- }
1520
- async onStateExit(state, context, output) {
1521
- await this.send("state_exit", { state, context, output });
1522
- return output;
1523
- }
1524
- async onAction(action, context) {
1525
- await this.send("action", { action, context });
1526
- return context;
1527
- }
1528
- };
1529
- var CompositeHooks = class {
1530
- constructor(hooks) {
1531
- this.hooks = hooks;
1532
- }
1533
- async onMachineStart(context) {
1534
- let result = context;
1535
- for (const hook of this.hooks) {
1536
- if (hook.onMachineStart) {
1537
- try {
1538
- result = await hook.onMachineStart(result);
1539
- } catch {
1540
- }
1541
- }
1542
- }
1543
- return result;
1544
- }
1545
- async onMachineEnd(context, output) {
1546
- let result = output;
1547
- for (const hook of this.hooks) {
1548
- if (hook.onMachineEnd) {
1549
- try {
1550
- result = await hook.onMachineEnd(context, result);
1551
- } catch {
1552
- }
1553
- }
1554
- }
1555
- return result;
1556
- }
1557
- async onStateEnter(state, context) {
1558
- let result = context;
1559
- for (const hook of this.hooks) {
1560
- if (hook.onStateEnter) {
1561
- try {
1562
- result = await hook.onStateEnter(state, result);
1563
- } catch {
1564
- }
1565
- }
1566
- }
1567
- return result;
1568
- }
1569
- async onStateExit(state, context, output) {
1570
- let result = output;
1571
- for (const hook of this.hooks) {
1572
- if (hook.onStateExit) {
1573
- try {
1574
- result = await hook.onStateExit(state, context, result);
1575
- } catch {
1576
- }
1577
- }
1578
- }
1579
- return result;
1580
- }
1581
- async onTransition(from, to, context) {
1582
- let result = to;
1583
- for (const hook of this.hooks) {
1584
- if (hook.onTransition) {
1585
- try {
1586
- result = await hook.onTransition(from, result, context);
1587
- } catch {
1588
- }
1589
- }
1590
- }
1591
- return result;
1592
- }
1593
- async onError(state, error, context) {
1594
- let result = null;
1595
- for (const hook of this.hooks) {
1596
- if (hook.onError) {
1597
- try {
1598
- const hookResult = await hook.onError(state, error, context);
1599
- if (hookResult !== null) result = hookResult;
1600
- } catch {
1601
- }
1602
- }
1603
- }
1604
- return result;
1605
- }
1606
- async onAction(action, context) {
1607
- let result = context;
1608
- for (const hook of this.hooks) {
1609
- if (hook.onAction) {
1610
- try {
1611
- result = await hook.onAction(action, result);
1612
- } catch {
1613
- }
1614
- }
1615
- }
1616
- return result;
1617
- }
1618
- };
1619
1662
  export {
1620
1663
  CheckpointManager,
1621
1664
  CompositeHooks,
1622
1665
  DefaultExecution,
1623
1666
  FlatAgent,
1624
1667
  FlatMachine,
1668
+ HooksRegistry,
1625
1669
  LocalFileBackend,
1626
1670
  LocalFileLock,
1627
1671
  MCPToolProvider,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memgrafter/flatagents",
3
- "version": "0.10.0",
3
+ "version": "2.0.0",
4
4
  "description": "TypeScript SDK for FlatAgents - Declarative LLM orchestration with YAML",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -149,7 +149,7 @@
149
149
  * The profile field specifies which profile name to use as base.
150
150
  */
151
151
 
152
- export const SPEC_VERSION = "0.10.0";
152
+ export const SPEC_VERSION = "2.0.0";
153
153
 
154
154
  export interface AgentWrapper {
155
155
  spec: "flatagent";
@@ -166,6 +166,16 @@ export interface AgentData {
166
166
  instruction_suffix?: string;
167
167
  output?: OutputSchema;
168
168
  mcp?: MCPConfig;
169
+ tools?: ToolDefinition[];
170
+ }
171
+
172
+ export interface ToolDefinition {
173
+ type: "function";
174
+ function: {
175
+ name: string;
176
+ description?: string;
177
+ parameters?: Record<string, any>;
178
+ };
169
179
  }
170
180
 
171
181
  export interface MCPConfig {
@@ -59,6 +59,12 @@
59
59
  },
60
60
  "mcp": {
61
61
  "$ref": "#/definitions/MCPConfig"
62
+ },
63
+ "tools": {
64
+ "type": "array",
65
+ "items": {
66
+ "$ref": "#/definitions/ToolDefinition"
67
+ }
62
68
  }
63
69
  },
64
70
  "required": [
@@ -266,6 +272,38 @@
266
272
  }
267
273
  },
268
274
  "additionalProperties": false
275
+ },
276
+ "ToolDefinition": {
277
+ "type": "object",
278
+ "properties": {
279
+ "type": {
280
+ "type": "string",
281
+ "const": "function"
282
+ },
283
+ "function": {
284
+ "type": "object",
285
+ "properties": {
286
+ "name": {
287
+ "type": "string"
288
+ },
289
+ "description": {
290
+ "type": "string"
291
+ },
292
+ "parameters": {
293
+ "type": "object"
294
+ }
295
+ },
296
+ "required": [
297
+ "name"
298
+ ],
299
+ "additionalProperties": false
300
+ }
301
+ },
302
+ "required": [
303
+ "type",
304
+ "function"
305
+ ],
306
+ "additionalProperties": false
269
307
  }
270
308
  }
271
309
  }
@@ -1,4 +1,4 @@
1
- export const SPEC_VERSION = "0.10.0";
1
+ export const SPEC_VERSION = "2.0.0";
2
2
  export interface AgentWrapper {
3
3
  spec: "flatagent";
4
4
  spec_version: string;
@@ -13,6 +13,15 @@ export interface AgentData {
13
13
  instruction_suffix?: string;
14
14
  output?: OutputSchema;
15
15
  mcp?: MCPConfig;
16
+ tools?: ToolDefinition[];
17
+ }
18
+ export interface ToolDefinition {
19
+ type: "function";
20
+ function: {
21
+ name: string;
22
+ description?: string;
23
+ parameters?: Record<string, any>;
24
+ };
16
25
  }
17
26
  export interface MCPConfig {
18
27
  servers: Record<string, MCPServerDef>;