@elizaos/plugin-action-bench 1.4.3 → 1.4.4
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/README.md +78 -11
- package/dist/index.cjs +770 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +770 -2
- package/dist/index.js.map +1 -1
- package/package.json +5 -2
package/dist/index.js
CHANGED
@@ -862,9 +862,770 @@ var multiverseMathActions = [
|
|
862
862
|
transferAction
|
863
863
|
];
|
864
864
|
|
865
|
+
// src/actions/relationalData.ts
|
866
|
+
function getRelationalState(state) {
|
867
|
+
return {
|
868
|
+
entities: state?.values?.entities || {},
|
869
|
+
relationships: state?.values?.relationships || {},
|
870
|
+
currentEntity: state?.values?.currentEntity || null,
|
871
|
+
queryResults: state?.values?.queryResults || []
|
872
|
+
};
|
873
|
+
}
|
874
|
+
function generateId(prefix) {
|
875
|
+
const timestamp = Date.now();
|
876
|
+
const random = Math.floor(Math.random() * 1e3);
|
877
|
+
return `${prefix}_${timestamp}_${random}`;
|
878
|
+
}
|
879
|
+
var createEntityAction = {
|
880
|
+
name: "CREATE_ENTITY",
|
881
|
+
similes: ["NEW_ENTITY", "ADD_ENTITY", "MAKE_ENTITY"],
|
882
|
+
description: "Create a new entity with a type and name. Entities are the nodes in our relational graph.",
|
883
|
+
validate: async () => true,
|
884
|
+
handler: async (_runtime, message, state, _options, callback) => {
|
885
|
+
const relState = getRelationalState(state);
|
886
|
+
const content = message.content.text?.toLowerCase() || "";
|
887
|
+
let entityType = "generic";
|
888
|
+
let entityName = "unnamed";
|
889
|
+
if (content.includes("person")) entityType = "person";
|
890
|
+
else if (content.includes("company")) entityType = "company";
|
891
|
+
else if (content.includes("product")) entityType = "product";
|
892
|
+
else if (content.includes("location")) entityType = "location";
|
893
|
+
else if (content.includes("project")) entityType = "project";
|
894
|
+
else if (content.includes("department")) entityType = "department";
|
895
|
+
else if (content.includes("task")) entityType = "task";
|
896
|
+
else if (content.includes("document")) entityType = "document";
|
897
|
+
const nameMatch = content.match(/named?\s+["']?([^"']+)["']?/i) || content.match(/called\s+["']?([^"']+)["']?/i) || content.match(/:\s*["']?([^"']+)["']?/i);
|
898
|
+
if (nameMatch) {
|
899
|
+
entityName = nameMatch[1].trim();
|
900
|
+
}
|
901
|
+
const entityId = generateId("entity");
|
902
|
+
const entity = {
|
903
|
+
id: entityId,
|
904
|
+
type: entityType,
|
905
|
+
name: entityName,
|
906
|
+
attributes: {},
|
907
|
+
created: (/* @__PURE__ */ new Date()).toISOString()
|
908
|
+
};
|
909
|
+
relState.entities[entityId] = entity;
|
910
|
+
relState.currentEntity = entityId;
|
911
|
+
const text = `Created entity: ${entityName} (${entityType}) with ID: ${entityId}`;
|
912
|
+
if (callback) {
|
913
|
+
await callback({ text, source: message.content.source });
|
914
|
+
}
|
915
|
+
return {
|
916
|
+
success: true,
|
917
|
+
text,
|
918
|
+
values: {
|
919
|
+
...state?.values,
|
920
|
+
entities: relState.entities,
|
921
|
+
currentEntity: entityId,
|
922
|
+
lastOperation: "create_entity"
|
923
|
+
},
|
924
|
+
data: {
|
925
|
+
operation: "create_entity",
|
926
|
+
entity,
|
927
|
+
totalEntities: Object.keys(relState.entities).length
|
928
|
+
}
|
929
|
+
};
|
930
|
+
},
|
931
|
+
examples: [
|
932
|
+
[
|
933
|
+
{
|
934
|
+
name: "{{user}}",
|
935
|
+
content: { text: "create person entity named John" }
|
936
|
+
},
|
937
|
+
{
|
938
|
+
name: "{{agent}}",
|
939
|
+
content: {
|
940
|
+
text: "Created entity: John (person) with ID: entity_...",
|
941
|
+
actions: ["CREATE_ENTITY"]
|
942
|
+
}
|
943
|
+
}
|
944
|
+
]
|
945
|
+
]
|
946
|
+
};
|
947
|
+
var createRelationshipAction = {
|
948
|
+
name: "CREATE_RELATIONSHIP",
|
949
|
+
similes: ["LINK", "CONNECT", "RELATE"],
|
950
|
+
description: "Create a relationship between two entities. Relationships are the edges in our relational graph.",
|
951
|
+
validate: async (_runtime, _message, state) => {
|
952
|
+
const relState = getRelationalState(state);
|
953
|
+
return Object.keys(relState.entities).length >= 2;
|
954
|
+
},
|
955
|
+
handler: async (_runtime, message, state, _options, callback) => {
|
956
|
+
const relState = getRelationalState(state);
|
957
|
+
const entities = Object.values(relState.entities);
|
958
|
+
if (entities.length < 2) {
|
959
|
+
return {
|
960
|
+
success: false,
|
961
|
+
text: "Error: Need at least 2 entities to create a relationship",
|
962
|
+
values: state?.values || {}
|
963
|
+
};
|
964
|
+
}
|
965
|
+
const content = message.content.text?.toLowerCase() || "";
|
966
|
+
let relationType = "related_to";
|
967
|
+
if (content.includes("parent") || content.includes("child")) relationType = "parent_child";
|
968
|
+
else if (content.includes("sibling")) relationType = "sibling";
|
969
|
+
else if (content.includes("friend")) relationType = "friend";
|
970
|
+
else if (content.includes("employee") || content.includes("works")) relationType = "employment";
|
971
|
+
else if (content.includes("owns") || content.includes("owner")) relationType = "ownership";
|
972
|
+
else if (content.includes("manages") || content.includes("reports")) relationType = "management";
|
973
|
+
else if (content.includes("partner")) relationType = "partnership";
|
974
|
+
else if (content.includes("member")) relationType = "membership";
|
975
|
+
else if (content.includes("located")) relationType = "location";
|
976
|
+
else if (content.includes("assigned")) relationType = "assignment";
|
977
|
+
let fromEntity;
|
978
|
+
let toEntity;
|
979
|
+
if (relState.currentEntity && relState.entities[relState.currentEntity]) {
|
980
|
+
fromEntity = relState.entities[relState.currentEntity];
|
981
|
+
toEntity = entities.filter((e) => e.id !== relState.currentEntity)[entities.length - 2] || entities[0];
|
982
|
+
} else {
|
983
|
+
fromEntity = entities[entities.length - 1];
|
984
|
+
toEntity = entities[entities.length - 2];
|
985
|
+
}
|
986
|
+
const relationshipId = generateId("rel");
|
987
|
+
const relationship = {
|
988
|
+
id: relationshipId,
|
989
|
+
type: relationType,
|
990
|
+
fromEntity: fromEntity.id,
|
991
|
+
toEntity: toEntity.id,
|
992
|
+
properties: {},
|
993
|
+
created: (/* @__PURE__ */ new Date()).toISOString()
|
994
|
+
};
|
995
|
+
relState.relationships[relationshipId] = relationship;
|
996
|
+
const text = `Created ${relationType} relationship: ${fromEntity.name} \u2192 ${toEntity.name}`;
|
997
|
+
if (callback) {
|
998
|
+
await callback({ text, source: message.content.source });
|
999
|
+
}
|
1000
|
+
return {
|
1001
|
+
success: true,
|
1002
|
+
text,
|
1003
|
+
values: {
|
1004
|
+
...state?.values,
|
1005
|
+
relationships: relState.relationships,
|
1006
|
+
lastOperation: "create_relationship"
|
1007
|
+
},
|
1008
|
+
data: {
|
1009
|
+
operation: "create_relationship",
|
1010
|
+
relationship,
|
1011
|
+
fromEntity: fromEntity.name,
|
1012
|
+
toEntity: toEntity.name,
|
1013
|
+
totalRelationships: Object.keys(relState.relationships).length
|
1014
|
+
}
|
1015
|
+
};
|
1016
|
+
},
|
1017
|
+
examples: [
|
1018
|
+
[
|
1019
|
+
{
|
1020
|
+
name: "{{user}}",
|
1021
|
+
content: { text: "create parent relationship" }
|
1022
|
+
},
|
1023
|
+
{
|
1024
|
+
name: "{{agent}}",
|
1025
|
+
content: {
|
1026
|
+
text: "Created parent_child relationship: Entity1 \u2192 Entity2",
|
1027
|
+
actions: ["CREATE_RELATIONSHIP"]
|
1028
|
+
}
|
1029
|
+
}
|
1030
|
+
]
|
1031
|
+
]
|
1032
|
+
};
|
1033
|
+
var setAttributeAction = {
|
1034
|
+
name: "SET_ATTRIBUTE",
|
1035
|
+
similes: ["ADD_ATTRIBUTE", "SET_PROPERTY", "UPDATE_ATTRIBUTE"],
|
1036
|
+
description: "Set an attribute on the current entity. Attributes store additional data on entities.",
|
1037
|
+
validate: async (_runtime, _message, state) => {
|
1038
|
+
const relState = getRelationalState(state);
|
1039
|
+
return relState.currentEntity !== null && relState.entities[relState.currentEntity] !== void 0;
|
1040
|
+
},
|
1041
|
+
handler: async (_runtime, message, state, _options, callback) => {
|
1042
|
+
const relState = getRelationalState(state);
|
1043
|
+
if (!relState.currentEntity || !relState.entities[relState.currentEntity]) {
|
1044
|
+
return {
|
1045
|
+
success: false,
|
1046
|
+
text: "Error: No current entity selected",
|
1047
|
+
values: state?.values || {}
|
1048
|
+
};
|
1049
|
+
}
|
1050
|
+
const entity = relState.entities[relState.currentEntity];
|
1051
|
+
const content = message.content.text || "";
|
1052
|
+
let key = "property";
|
1053
|
+
let value = "value";
|
1054
|
+
const ageMatch = content.match(/age[:\s]+(\d+)/i);
|
1055
|
+
const emailMatch = content.match(/email[:\s]+([^\s]+)/i);
|
1056
|
+
const phoneMatch = content.match(/phone[:\s]+([^\s]+)/i);
|
1057
|
+
const statusMatch = content.match(/status[:\s]+([^\s]+)/i);
|
1058
|
+
const roleMatch = content.match(/role[:\s]+([^\s]+)/i);
|
1059
|
+
const departmentMatch = content.match(/department[:\s]+([^\s]+)/i);
|
1060
|
+
const salaryMatch = content.match(/salary[:\s]+(\d+)/i);
|
1061
|
+
const locationMatch = content.match(/location[:\s]+([^\s]+)/i);
|
1062
|
+
if (ageMatch) {
|
1063
|
+
key = "age";
|
1064
|
+
value = parseInt(ageMatch[1]);
|
1065
|
+
} else if (emailMatch) {
|
1066
|
+
key = "email";
|
1067
|
+
value = emailMatch[1];
|
1068
|
+
} else if (phoneMatch) {
|
1069
|
+
key = "phone";
|
1070
|
+
value = phoneMatch[1];
|
1071
|
+
} else if (statusMatch) {
|
1072
|
+
key = "status";
|
1073
|
+
value = statusMatch[1];
|
1074
|
+
} else if (roleMatch) {
|
1075
|
+
key = "role";
|
1076
|
+
value = roleMatch[1];
|
1077
|
+
} else if (departmentMatch) {
|
1078
|
+
key = "department";
|
1079
|
+
value = departmentMatch[1];
|
1080
|
+
} else if (salaryMatch) {
|
1081
|
+
key = "salary";
|
1082
|
+
value = parseInt(salaryMatch[1]);
|
1083
|
+
} else if (locationMatch) {
|
1084
|
+
key = "location";
|
1085
|
+
value = locationMatch[1];
|
1086
|
+
} else {
|
1087
|
+
const genericMatch = content.match(/(\w+)[:\s=]+([^\s]+)/i);
|
1088
|
+
if (genericMatch) {
|
1089
|
+
key = genericMatch[1];
|
1090
|
+
value = genericMatch[2];
|
1091
|
+
const numValue = parseFloat(value);
|
1092
|
+
if (!isNaN(numValue)) value = numValue;
|
1093
|
+
}
|
1094
|
+
}
|
1095
|
+
entity.attributes[key] = value;
|
1096
|
+
const text = `Set attribute on ${entity.name}: ${key} = ${value}`;
|
1097
|
+
if (callback) {
|
1098
|
+
await callback({ text, source: message.content.source });
|
1099
|
+
}
|
1100
|
+
return {
|
1101
|
+
success: true,
|
1102
|
+
text,
|
1103
|
+
values: {
|
1104
|
+
...state?.values,
|
1105
|
+
entities: relState.entities,
|
1106
|
+
lastOperation: "set_attribute"
|
1107
|
+
},
|
1108
|
+
data: {
|
1109
|
+
operation: "set_attribute",
|
1110
|
+
entityId: entity.id,
|
1111
|
+
entityName: entity.name,
|
1112
|
+
attribute: { key, value },
|
1113
|
+
totalAttributes: Object.keys(entity.attributes).length
|
1114
|
+
}
|
1115
|
+
};
|
1116
|
+
},
|
1117
|
+
examples: [
|
1118
|
+
[
|
1119
|
+
{
|
1120
|
+
name: "{{user}}",
|
1121
|
+
content: { text: "set age 25" }
|
1122
|
+
},
|
1123
|
+
{
|
1124
|
+
name: "{{agent}}",
|
1125
|
+
content: {
|
1126
|
+
text: "Set attribute on Entity: age = 25",
|
1127
|
+
actions: ["SET_ATTRIBUTE"]
|
1128
|
+
}
|
1129
|
+
}
|
1130
|
+
]
|
1131
|
+
]
|
1132
|
+
};
|
1133
|
+
var queryRelationshipsAction = {
|
1134
|
+
name: "QUERY_RELATIONSHIPS",
|
1135
|
+
similes: ["FIND_RELATIONSHIPS", "GET_CONNECTIONS", "SHOW_LINKS"],
|
1136
|
+
description: "Query relationships of a specific type or for a specific entity.",
|
1137
|
+
validate: async () => true,
|
1138
|
+
handler: async (_runtime, message, state, _options, callback) => {
|
1139
|
+
const relState = getRelationalState(state);
|
1140
|
+
const content = message.content.text?.toLowerCase() || "";
|
1141
|
+
let results = [];
|
1142
|
+
let queryDescription = "";
|
1143
|
+
if (content.includes("parent")) {
|
1144
|
+
results = Object.values(relState.relationships).filter((r) => r.type === "parent_child").map((r) => ({
|
1145
|
+
type: r.type,
|
1146
|
+
from: relState.entities[r.fromEntity]?.name || r.fromEntity,
|
1147
|
+
to: relState.entities[r.toEntity]?.name || r.toEntity
|
1148
|
+
}));
|
1149
|
+
queryDescription = "parent-child relationships";
|
1150
|
+
} else if (content.includes("sibling")) {
|
1151
|
+
results = Object.values(relState.relationships).filter((r) => r.type === "sibling").map((r) => ({
|
1152
|
+
type: r.type,
|
1153
|
+
from: relState.entities[r.fromEntity]?.name || r.fromEntity,
|
1154
|
+
to: relState.entities[r.toEntity]?.name || r.toEntity
|
1155
|
+
}));
|
1156
|
+
queryDescription = "sibling relationships";
|
1157
|
+
} else if (content.includes("all")) {
|
1158
|
+
results = Object.values(relState.relationships).map((r) => ({
|
1159
|
+
type: r.type,
|
1160
|
+
from: relState.entities[r.fromEntity]?.name || r.fromEntity,
|
1161
|
+
to: relState.entities[r.toEntity]?.name || r.toEntity
|
1162
|
+
}));
|
1163
|
+
queryDescription = "all relationships";
|
1164
|
+
} else if (relState.currentEntity) {
|
1165
|
+
results = Object.values(relState.relationships).filter((r) => r.fromEntity === relState.currentEntity || r.toEntity === relState.currentEntity).map((r) => ({
|
1166
|
+
type: r.type,
|
1167
|
+
from: relState.entities[r.fromEntity]?.name || r.fromEntity,
|
1168
|
+
to: relState.entities[r.toEntity]?.name || r.toEntity,
|
1169
|
+
direction: r.fromEntity === relState.currentEntity ? "outgoing" : "incoming"
|
1170
|
+
}));
|
1171
|
+
queryDescription = `relationships for ${relState.entities[relState.currentEntity]?.name}`;
|
1172
|
+
}
|
1173
|
+
const text = `Found ${results.length} ${queryDescription}`;
|
1174
|
+
if (callback) {
|
1175
|
+
await callback({ text, source: message.content.source });
|
1176
|
+
}
|
1177
|
+
return {
|
1178
|
+
success: true,
|
1179
|
+
text,
|
1180
|
+
values: {
|
1181
|
+
...state?.values,
|
1182
|
+
queryResults: results,
|
1183
|
+
lastOperation: "query_relationships"
|
1184
|
+
},
|
1185
|
+
data: {
|
1186
|
+
operation: "query_relationships",
|
1187
|
+
query: queryDescription,
|
1188
|
+
results,
|
1189
|
+
count: results.length
|
1190
|
+
}
|
1191
|
+
};
|
1192
|
+
},
|
1193
|
+
examples: [
|
1194
|
+
[
|
1195
|
+
{
|
1196
|
+
name: "{{user}}",
|
1197
|
+
content: { text: "query parent relationships" }
|
1198
|
+
},
|
1199
|
+
{
|
1200
|
+
name: "{{agent}}",
|
1201
|
+
content: {
|
1202
|
+
text: "Found 0 parent-child relationships",
|
1203
|
+
actions: ["QUERY_RELATIONSHIPS"]
|
1204
|
+
}
|
1205
|
+
}
|
1206
|
+
]
|
1207
|
+
]
|
1208
|
+
};
|
1209
|
+
var queryEntitiesAction = {
|
1210
|
+
name: "QUERY_ENTITIES",
|
1211
|
+
similes: ["FIND_ENTITIES", "SEARCH_ENTITIES", "LIST_ENTITIES"],
|
1212
|
+
description: "Query entities by type or attribute values.",
|
1213
|
+
validate: async () => true,
|
1214
|
+
handler: async (_runtime, message, state, _options, callback) => {
|
1215
|
+
const relState = getRelationalState(state);
|
1216
|
+
const content = message.content.text?.toLowerCase() || "";
|
1217
|
+
let results = [];
|
1218
|
+
let queryDescription = "";
|
1219
|
+
if (content.includes("person")) {
|
1220
|
+
results = Object.values(relState.entities).filter((e) => e.type === "person");
|
1221
|
+
queryDescription = "person entities";
|
1222
|
+
} else if (content.includes("company")) {
|
1223
|
+
results = Object.values(relState.entities).filter((e) => e.type === "company");
|
1224
|
+
queryDescription = "company entities";
|
1225
|
+
} else if (content.includes("product")) {
|
1226
|
+
results = Object.values(relState.entities).filter((e) => e.type === "product");
|
1227
|
+
queryDescription = "product entities";
|
1228
|
+
} else if (content.includes("all")) {
|
1229
|
+
results = Object.values(relState.entities);
|
1230
|
+
queryDescription = "all entities";
|
1231
|
+
} else {
|
1232
|
+
const ageMatch = content.match(/age\s*[><=]+\s*(\d+)/);
|
1233
|
+
if (ageMatch) {
|
1234
|
+
const age = parseInt(ageMatch[1]);
|
1235
|
+
results = Object.values(relState.entities).filter((e) => {
|
1236
|
+
const entityAge = e.attributes.age;
|
1237
|
+
if (typeof entityAge !== "number") return false;
|
1238
|
+
if (content.includes(">")) return entityAge > age;
|
1239
|
+
if (content.includes("<")) return entityAge < age;
|
1240
|
+
return entityAge === age;
|
1241
|
+
});
|
1242
|
+
queryDescription = `entities with age ${ageMatch[0]}`;
|
1243
|
+
} else {
|
1244
|
+
results = Object.values(relState.entities);
|
1245
|
+
queryDescription = "all entities";
|
1246
|
+
}
|
1247
|
+
}
|
1248
|
+
const resultSummary = results.map((e) => ({
|
1249
|
+
id: e.id,
|
1250
|
+
name: e.name,
|
1251
|
+
type: e.type,
|
1252
|
+
attributes: e.attributes
|
1253
|
+
}));
|
1254
|
+
const text = `Found ${results.length} ${queryDescription}`;
|
1255
|
+
if (callback) {
|
1256
|
+
await callback({ text, source: message.content.source });
|
1257
|
+
}
|
1258
|
+
return {
|
1259
|
+
success: true,
|
1260
|
+
text,
|
1261
|
+
values: {
|
1262
|
+
...state?.values,
|
1263
|
+
queryResults: resultSummary,
|
1264
|
+
lastOperation: "query_entities"
|
1265
|
+
},
|
1266
|
+
data: {
|
1267
|
+
operation: "query_entities",
|
1268
|
+
query: queryDescription,
|
1269
|
+
results: resultSummary,
|
1270
|
+
count: results.length
|
1271
|
+
}
|
1272
|
+
};
|
1273
|
+
},
|
1274
|
+
examples: [
|
1275
|
+
[
|
1276
|
+
{
|
1277
|
+
name: "{{user}}",
|
1278
|
+
content: { text: "query person entities" }
|
1279
|
+
},
|
1280
|
+
{
|
1281
|
+
name: "{{agent}}",
|
1282
|
+
content: {
|
1283
|
+
text: "Found 0 person entities",
|
1284
|
+
actions: ["QUERY_ENTITIES"]
|
1285
|
+
}
|
1286
|
+
}
|
1287
|
+
]
|
1288
|
+
]
|
1289
|
+
};
|
1290
|
+
var selectEntityAction = {
|
1291
|
+
name: "SELECT_ENTITY",
|
1292
|
+
similes: ["CHOOSE_ENTITY", "FOCUS_ENTITY", "SET_CURRENT_ENTITY"],
|
1293
|
+
description: "Select an entity as the current entity for operations.",
|
1294
|
+
validate: async (_runtime, _message, state) => {
|
1295
|
+
const relState = getRelationalState(state);
|
1296
|
+
return Object.keys(relState.entities).length > 0;
|
1297
|
+
},
|
1298
|
+
handler: async (_runtime, message, state, _options, callback) => {
|
1299
|
+
const relState = getRelationalState(state);
|
1300
|
+
const content = message.content.text || "";
|
1301
|
+
if (Object.keys(relState.entities).length === 0) {
|
1302
|
+
return {
|
1303
|
+
success: false,
|
1304
|
+
text: "Error: No entities exist to select",
|
1305
|
+
values: state?.values || {}
|
1306
|
+
};
|
1307
|
+
}
|
1308
|
+
let selectedEntity;
|
1309
|
+
for (const entity of Object.values(relState.entities)) {
|
1310
|
+
if (content.toLowerCase().includes(entity.name.toLowerCase())) {
|
1311
|
+
selectedEntity = entity;
|
1312
|
+
break;
|
1313
|
+
}
|
1314
|
+
}
|
1315
|
+
if (!selectedEntity) {
|
1316
|
+
const entities = Object.values(relState.entities);
|
1317
|
+
selectedEntity = entities[entities.length - 1];
|
1318
|
+
}
|
1319
|
+
relState.currentEntity = selectedEntity.id;
|
1320
|
+
const text = `Selected entity: ${selectedEntity.name} (${selectedEntity.type})`;
|
1321
|
+
if (callback) {
|
1322
|
+
await callback({ text, source: message.content.source });
|
1323
|
+
}
|
1324
|
+
return {
|
1325
|
+
success: true,
|
1326
|
+
text,
|
1327
|
+
values: {
|
1328
|
+
...state?.values,
|
1329
|
+
currentEntity: selectedEntity.id,
|
1330
|
+
lastOperation: "select_entity"
|
1331
|
+
},
|
1332
|
+
data: {
|
1333
|
+
operation: "select_entity",
|
1334
|
+
entity: selectedEntity
|
1335
|
+
}
|
1336
|
+
};
|
1337
|
+
},
|
1338
|
+
examples: [
|
1339
|
+
[
|
1340
|
+
{
|
1341
|
+
name: "{{user}}",
|
1342
|
+
content: { text: "select entity John" }
|
1343
|
+
},
|
1344
|
+
{
|
1345
|
+
name: "{{agent}}",
|
1346
|
+
content: {
|
1347
|
+
text: "Selected entity: John (person)",
|
1348
|
+
actions: ["SELECT_ENTITY"]
|
1349
|
+
}
|
1350
|
+
}
|
1351
|
+
]
|
1352
|
+
]
|
1353
|
+
};
|
1354
|
+
var deleteEntityAction = {
|
1355
|
+
name: "DELETE_ENTITY",
|
1356
|
+
similes: ["REMOVE_ENTITY", "DESTROY_ENTITY"],
|
1357
|
+
description: "Delete the current entity and all its relationships.",
|
1358
|
+
validate: async (_runtime, _message, state) => {
|
1359
|
+
const relState = getRelationalState(state);
|
1360
|
+
return relState.currentEntity !== null && relState.entities[relState.currentEntity] !== void 0;
|
1361
|
+
},
|
1362
|
+
handler: async (_runtime, message, state, _options, callback) => {
|
1363
|
+
const relState = getRelationalState(state);
|
1364
|
+
if (!relState.currentEntity || !relState.entities[relState.currentEntity]) {
|
1365
|
+
return {
|
1366
|
+
success: false,
|
1367
|
+
text: "Error: No current entity selected",
|
1368
|
+
values: state?.values || {}
|
1369
|
+
};
|
1370
|
+
}
|
1371
|
+
const entity = relState.entities[relState.currentEntity];
|
1372
|
+
const entityName = entity.name;
|
1373
|
+
delete relState.entities[relState.currentEntity];
|
1374
|
+
const relationshipsToDelete = [];
|
1375
|
+
for (const [relId, rel] of Object.entries(relState.relationships)) {
|
1376
|
+
if (rel.fromEntity === relState.currentEntity || rel.toEntity === relState.currentEntity) {
|
1377
|
+
relationshipsToDelete.push(relId);
|
1378
|
+
}
|
1379
|
+
}
|
1380
|
+
for (const relId of relationshipsToDelete) {
|
1381
|
+
delete relState.relationships[relId];
|
1382
|
+
}
|
1383
|
+
relState.currentEntity = null;
|
1384
|
+
const text = `Deleted entity: ${entityName} and ${relationshipsToDelete.length} relationships`;
|
1385
|
+
if (callback) {
|
1386
|
+
await callback({ text, source: message.content.source });
|
1387
|
+
}
|
1388
|
+
return {
|
1389
|
+
success: true,
|
1390
|
+
text,
|
1391
|
+
values: {
|
1392
|
+
...state?.values,
|
1393
|
+
entities: relState.entities,
|
1394
|
+
relationships: relState.relationships,
|
1395
|
+
currentEntity: null,
|
1396
|
+
lastOperation: "delete_entity"
|
1397
|
+
},
|
1398
|
+
data: {
|
1399
|
+
operation: "delete_entity",
|
1400
|
+
deletedEntity: entityName,
|
1401
|
+
deletedRelationships: relationshipsToDelete.length,
|
1402
|
+
remainingEntities: Object.keys(relState.entities).length
|
1403
|
+
}
|
1404
|
+
};
|
1405
|
+
},
|
1406
|
+
examples: [
|
1407
|
+
[
|
1408
|
+
{
|
1409
|
+
name: "{{user}}",
|
1410
|
+
content: { text: "delete current entity" }
|
1411
|
+
},
|
1412
|
+
{
|
1413
|
+
name: "{{agent}}",
|
1414
|
+
content: {
|
1415
|
+
text: "Deleted entity: EntityName and 0 relationships",
|
1416
|
+
actions: ["DELETE_ENTITY"]
|
1417
|
+
}
|
1418
|
+
}
|
1419
|
+
]
|
1420
|
+
]
|
1421
|
+
};
|
1422
|
+
var countStatisticsAction = {
|
1423
|
+
name: "COUNT_STATISTICS",
|
1424
|
+
similes: ["STATS", "STATISTICS", "COUNT"],
|
1425
|
+
description: "Get statistics about the current relational data graph.",
|
1426
|
+
validate: async () => true,
|
1427
|
+
handler: async (_runtime, message, state, _options, callback) => {
|
1428
|
+
const relState = getRelationalState(state);
|
1429
|
+
const totalEntities = Object.keys(relState.entities).length;
|
1430
|
+
const totalRelationships = Object.keys(relState.relationships).length;
|
1431
|
+
const entityTypes = {};
|
1432
|
+
for (const entity of Object.values(relState.entities)) {
|
1433
|
+
entityTypes[entity.type] = (entityTypes[entity.type] || 0) + 1;
|
1434
|
+
}
|
1435
|
+
const relationshipTypes = {};
|
1436
|
+
for (const rel of Object.values(relState.relationships)) {
|
1437
|
+
relationshipTypes[rel.type] = (relationshipTypes[rel.type] || 0) + 1;
|
1438
|
+
}
|
1439
|
+
let totalAttributes = 0;
|
1440
|
+
for (const entity of Object.values(relState.entities)) {
|
1441
|
+
totalAttributes += Object.keys(entity.attributes).length;
|
1442
|
+
}
|
1443
|
+
const stats = {
|
1444
|
+
totalEntities,
|
1445
|
+
totalRelationships,
|
1446
|
+
totalAttributes,
|
1447
|
+
entityTypes,
|
1448
|
+
relationshipTypes,
|
1449
|
+
currentEntity: relState.currentEntity ? relState.entities[relState.currentEntity]?.name : "none"
|
1450
|
+
};
|
1451
|
+
const text = `Graph statistics: ${totalEntities} entities, ${totalRelationships} relationships, ${totalAttributes} attributes`;
|
1452
|
+
if (callback) {
|
1453
|
+
await callback({ text, source: message.content.source });
|
1454
|
+
}
|
1455
|
+
return {
|
1456
|
+
success: true,
|
1457
|
+
text,
|
1458
|
+
values: {
|
1459
|
+
...state?.values,
|
1460
|
+
queryResults: [stats],
|
1461
|
+
lastOperation: "count_statistics"
|
1462
|
+
},
|
1463
|
+
data: {
|
1464
|
+
operation: "count_statistics",
|
1465
|
+
statistics: stats
|
1466
|
+
}
|
1467
|
+
};
|
1468
|
+
},
|
1469
|
+
examples: [
|
1470
|
+
[
|
1471
|
+
{
|
1472
|
+
name: "{{user}}",
|
1473
|
+
content: { text: "show statistics" }
|
1474
|
+
},
|
1475
|
+
{
|
1476
|
+
name: "{{agent}}",
|
1477
|
+
content: {
|
1478
|
+
text: "Graph statistics: 0 entities, 0 relationships, 0 attributes",
|
1479
|
+
actions: ["COUNT_STATISTICS"]
|
1480
|
+
}
|
1481
|
+
}
|
1482
|
+
]
|
1483
|
+
]
|
1484
|
+
};
|
1485
|
+
var clearGraphAction = {
|
1486
|
+
name: "CLEAR_GRAPH",
|
1487
|
+
similes: ["RESET_GRAPH", "CLEAR_ALL", "DELETE_ALL"],
|
1488
|
+
description: "Clear all entities and relationships from the graph.",
|
1489
|
+
validate: async () => true,
|
1490
|
+
handler: async (_runtime, message, _state, _options, callback) => {
|
1491
|
+
const text = "Cleared all entities and relationships";
|
1492
|
+
if (callback) {
|
1493
|
+
await callback({ text, source: message.content.source });
|
1494
|
+
}
|
1495
|
+
return {
|
1496
|
+
success: true,
|
1497
|
+
text,
|
1498
|
+
values: {
|
1499
|
+
entities: {},
|
1500
|
+
relationships: {},
|
1501
|
+
currentEntity: null,
|
1502
|
+
queryResults: [],
|
1503
|
+
lastOperation: "clear_graph"
|
1504
|
+
},
|
1505
|
+
data: {
|
1506
|
+
operation: "clear_graph"
|
1507
|
+
}
|
1508
|
+
};
|
1509
|
+
},
|
1510
|
+
examples: [
|
1511
|
+
[
|
1512
|
+
{
|
1513
|
+
name: "{{user}}",
|
1514
|
+
content: { text: "clear graph" }
|
1515
|
+
},
|
1516
|
+
{
|
1517
|
+
name: "{{agent}}",
|
1518
|
+
content: {
|
1519
|
+
text: "Cleared all entities and relationships",
|
1520
|
+
actions: ["CLEAR_GRAPH"]
|
1521
|
+
}
|
1522
|
+
}
|
1523
|
+
]
|
1524
|
+
]
|
1525
|
+
};
|
1526
|
+
var findPathAction = {
|
1527
|
+
name: "FIND_PATH",
|
1528
|
+
similes: ["PATH", "ROUTE", "CONNECTION_PATH"],
|
1529
|
+
description: "Find the shortest path between two entities in the relationship graph.",
|
1530
|
+
validate: async (_runtime, _message, state) => {
|
1531
|
+
const relState = getRelationalState(state);
|
1532
|
+
return Object.keys(relState.entities).length >= 2;
|
1533
|
+
},
|
1534
|
+
handler: async (_runtime, message, state, _options, callback) => {
|
1535
|
+
const relState = getRelationalState(state);
|
1536
|
+
if (Object.keys(relState.entities).length < 2) {
|
1537
|
+
return {
|
1538
|
+
success: false,
|
1539
|
+
text: "Error: Need at least 2 entities to find a path",
|
1540
|
+
values: state?.values || {}
|
1541
|
+
};
|
1542
|
+
}
|
1543
|
+
const entities = Object.values(relState.entities);
|
1544
|
+
const start = entities[0];
|
1545
|
+
const end = entities[entities.length - 1];
|
1546
|
+
const adjacency = {};
|
1547
|
+
for (const entity of entities) {
|
1548
|
+
adjacency[entity.id] = /* @__PURE__ */ new Set();
|
1549
|
+
}
|
1550
|
+
for (const rel of Object.values(relState.relationships)) {
|
1551
|
+
adjacency[rel.fromEntity]?.add(rel.toEntity);
|
1552
|
+
adjacency[rel.toEntity]?.add(rel.fromEntity);
|
1553
|
+
}
|
1554
|
+
const queue = [{ node: start.id, path: [start.id] }];
|
1555
|
+
const visited = /* @__PURE__ */ new Set();
|
1556
|
+
let foundPath = [];
|
1557
|
+
while (queue.length > 0) {
|
1558
|
+
const current = queue.shift();
|
1559
|
+
if (current.node === end.id) {
|
1560
|
+
foundPath = current.path;
|
1561
|
+
break;
|
1562
|
+
}
|
1563
|
+
if (visited.has(current.node)) continue;
|
1564
|
+
visited.add(current.node);
|
1565
|
+
for (const neighbor of adjacency[current.node] || []) {
|
1566
|
+
if (!visited.has(neighbor)) {
|
1567
|
+
queue.push({
|
1568
|
+
node: neighbor,
|
1569
|
+
path: [...current.path, neighbor]
|
1570
|
+
});
|
1571
|
+
}
|
1572
|
+
}
|
1573
|
+
}
|
1574
|
+
const pathNames = foundPath.map((id) => relState.entities[id]?.name || id);
|
1575
|
+
const text = foundPath.length > 0 ? `Found path: ${pathNames.join(" \u2192 ")}` : `No path found between ${start.name} and ${end.name}`;
|
1576
|
+
if (callback) {
|
1577
|
+
await callback({ text, source: message.content.source });
|
1578
|
+
}
|
1579
|
+
return {
|
1580
|
+
success: true,
|
1581
|
+
text,
|
1582
|
+
values: {
|
1583
|
+
...state?.values,
|
1584
|
+
queryResults: [{ path: pathNames, length: foundPath.length }],
|
1585
|
+
lastOperation: "find_path"
|
1586
|
+
},
|
1587
|
+
data: {
|
1588
|
+
operation: "find_path",
|
1589
|
+
from: start.name,
|
1590
|
+
to: end.name,
|
1591
|
+
path: pathNames,
|
1592
|
+
pathLength: foundPath.length
|
1593
|
+
}
|
1594
|
+
};
|
1595
|
+
},
|
1596
|
+
examples: [
|
1597
|
+
[
|
1598
|
+
{
|
1599
|
+
name: "{{user}}",
|
1600
|
+
content: { text: "find path between entities" }
|
1601
|
+
},
|
1602
|
+
{
|
1603
|
+
name: "{{agent}}",
|
1604
|
+
content: {
|
1605
|
+
text: "Found path: Entity1 \u2192 Entity2",
|
1606
|
+
actions: ["FIND_PATH"]
|
1607
|
+
}
|
1608
|
+
}
|
1609
|
+
]
|
1610
|
+
]
|
1611
|
+
};
|
1612
|
+
var relationalDataActions = [
|
1613
|
+
createEntityAction,
|
1614
|
+
createRelationshipAction,
|
1615
|
+
setAttributeAction,
|
1616
|
+
queryRelationshipsAction,
|
1617
|
+
queryEntitiesAction,
|
1618
|
+
selectEntityAction,
|
1619
|
+
deleteEntityAction,
|
1620
|
+
countStatisticsAction,
|
1621
|
+
clearGraphAction,
|
1622
|
+
findPathAction
|
1623
|
+
];
|
1624
|
+
|
865
1625
|
// src/index.ts
|
866
1626
|
var TYPEWRITER_ENABLED = process.env.TYPEWRITER_ENABLED?.toLowerCase() !== "false";
|
867
1627
|
var MULTIVERSE_MATH_ENABLED = process.env.MULTIVERSE_MATH_ENABLED?.toLowerCase() !== "false";
|
1628
|
+
var RELATIONAL_DATA_ENABLED = process.env.RELATIONAL_DATA_ENABLED?.toLowerCase() !== "false";
|
868
1629
|
function buildActions() {
|
869
1630
|
const actions = [];
|
870
1631
|
if (TYPEWRITER_ENABLED) {
|
@@ -879,20 +1640,27 @@ function buildActions() {
|
|
879
1640
|
} else {
|
880
1641
|
console.log("[plugin-action-bench] Multiverse math actions disabled via MULTIVERSE_MATH_ENABLED=false");
|
881
1642
|
}
|
1643
|
+
if (RELATIONAL_DATA_ENABLED) {
|
1644
|
+
console.log("[plugin-action-bench] Relational data actions enabled");
|
1645
|
+
actions.push(...relationalDataActions);
|
1646
|
+
} else {
|
1647
|
+
console.log("[plugin-action-bench] Relational data actions disabled via RELATIONAL_DATA_ENABLED=false");
|
1648
|
+
}
|
882
1649
|
if (actions.length === 0) {
|
883
|
-
console.warn("[plugin-action-bench] WARNING: No benchmark actions are enabled. Set TYPEWRITER_ENABLED=true or
|
1650
|
+
console.warn("[plugin-action-bench] WARNING: No benchmark actions are enabled. Set TYPEWRITER_ENABLED=true, MULTIVERSE_MATH_ENABLED=true, or RELATIONAL_DATA_ENABLED=true to enable benchmarks.");
|
884
1651
|
}
|
885
1652
|
console.log(`[plugin-action-bench] Total actions loaded: ${actions.length}`);
|
886
1653
|
return actions;
|
887
1654
|
}
|
888
1655
|
var actionBenchPlugin = {
|
889
1656
|
name: "plugin-action-bench",
|
890
|
-
description: "Action benchmark plugin providing typewriter (A\u2013Z)
|
1657
|
+
description: "Action benchmark plugin providing typewriter (A\u2013Z), multiverse math operations with dimensional constants, and relational data management, testing AI agents' ability to handle action chaining, context-dependent operations, and complex data relationships.",
|
891
1658
|
actions: buildActions()
|
892
1659
|
};
|
893
1660
|
var benchmarkConfig = {
|
894
1661
|
typewriterEnabled: TYPEWRITER_ENABLED,
|
895
1662
|
multiverseMathEnabled: MULTIVERSE_MATH_ENABLED,
|
1663
|
+
relationalDataEnabled: RELATIONAL_DATA_ENABLED,
|
896
1664
|
totalActionsLoaded: actionBenchPlugin.actions?.length ?? 0
|
897
1665
|
};
|
898
1666
|
var index_default = actionBenchPlugin;
|