@rudderhq/agent-runtime-utils 0.7.13 → 0.7.15
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.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/rudder-agent-contract.d.ts +5 -0
- package/dist/rudder-agent-contract.d.ts.map +1 -0
- package/dist/rudder-agent-contract.generated.d.ts +8322 -0
- package/dist/rudder-agent-contract.generated.d.ts.map +1 -0
- package/dist/rudder-agent-contract.generated.js +9320 -0
- package/dist/rudder-agent-contract.generated.js.map +1 -0
- package/dist/rudder-agent-contract.js +31 -0
- package/dist/rudder-agent-contract.js.map +1 -0
- package/dist/rudder-agent-contract.test.d.ts +2 -0
- package/dist/rudder-agent-contract.test.d.ts.map +1 -0
- package/dist/rudder-agent-contract.test.js +69 -0
- package/dist/rudder-agent-contract.test.js.map +1 -0
- package/dist/rudder-mcp-contract.d.ts +5939 -932
- package/dist/rudder-mcp-contract.d.ts.map +1 -1
- package/dist/rudder-mcp-contract.js +7 -805
- package/dist/rudder-mcp-contract.js.map +1 -1
- package/dist/rudder-mcp-tool-descriptors.generated.d.ts +5111 -1
- package/dist/rudder-mcp-tool-descriptors.generated.d.ts.map +1 -1
- package/dist/rudder-mcp-tool-descriptors.generated.js +5999 -104
- package/dist/rudder-mcp-tool-descriptors.generated.js.map +1 -1
- package/dist/server-utils.instructions.d.ts.map +1 -1
- package/dist/server-utils.instructions.js +26 -6
- package/dist/server-utils.instructions.js.map +1 -1
- package/dist/server-utils.prompt-boundaries.test.d.ts +2 -0
- package/dist/server-utils.prompt-boundaries.test.d.ts.map +1 -0
- package/dist/server-utils.prompt-boundaries.test.js +44 -0
- package/dist/server-utils.prompt-boundaries.test.js.map +1 -0
- package/dist/server-utils.prompts.d.ts +23 -10
- package/dist/server-utils.prompts.d.ts.map +1 -1
- package/dist/server-utils.prompts.js +65 -27
- package/dist/server-utils.prompts.js.map +1 -1
- package/dist/server-utils.test.js +65 -19
- package/dist/server-utils.test.js.map +1 -1
- package/package.json +2 -2
|
@@ -918,7 +918,9 @@ describe("loadAgentInstructionsPrefix", () => {
|
|
|
918
918
|
instructionsFilePath: "",
|
|
919
919
|
onLog: async () => { },
|
|
920
920
|
});
|
|
921
|
-
expect(loaded.prefix).toContain("
|
|
921
|
+
expect(loaded.prefix).toContain("<rudder_agent_operating_contract>");
|
|
922
|
+
expect(loaded.prefix).toContain("</rudder_agent_operating_contract>");
|
|
923
|
+
expect(loaded.prefix).not.toContain("# Rudder Agent Operating Contract");
|
|
922
924
|
expect(loaded.prefix).toContain(RUDDER_AGENT_OPERATING_CONTRACT);
|
|
923
925
|
expect(loaded.prefix).toContain("installed but not enabled");
|
|
924
926
|
expect(loaded.prefix).toContain("library:projects/<project-key>/");
|
|
@@ -971,7 +973,8 @@ describe("loadAgentInstructionsPrefix", () => {
|
|
|
971
973
|
includeHeartbeatInstructions: true,
|
|
972
974
|
onLog: async () => { },
|
|
973
975
|
});
|
|
974
|
-
expect(loaded.prefix).toContain("
|
|
976
|
+
expect(loaded.prefix).toContain("<rudder_agent_operating_contract>");
|
|
977
|
+
expect(loaded.prefix).toContain("<rudder_heartbeat_instruction>");
|
|
975
978
|
expect(loaded.prefix).toContain(RUDDER_AGENT_HEARTBEAT_INSTRUCTION);
|
|
976
979
|
expect(loaded.prefix).toContain("platform-owned heartbeat/self-check pipeline");
|
|
977
980
|
expect(loaded.commandNotes).toEqual([
|
|
@@ -1006,8 +1009,9 @@ describe("loadAgentInstructionsPrefix", () => {
|
|
|
1006
1009
|
logs.push({ stream, chunk });
|
|
1007
1010
|
},
|
|
1008
1011
|
});
|
|
1009
|
-
expect(loaded.prefix).toContain("
|
|
1012
|
+
expect(loaded.prefix).toContain("<rudder_agent_operating_contract>");
|
|
1010
1013
|
expect(loaded.prefix).toContain("# Agent Instructions");
|
|
1014
|
+
expect(loaded.prefix).toContain("<AGENTS.md>\n# Agent Instructions\n</AGENTS.md>");
|
|
1011
1015
|
expect(loaded.prefix).toContain("The above AGENTS.md instruction file was loaded from $AGENT_HOME/instructions.");
|
|
1012
1016
|
expect(loaded.prefix).toContain("relative file references from $AGENT_HOME/instructions/");
|
|
1013
1017
|
expect(loaded.prefix).not.toContain("Tacit Memory");
|
|
@@ -1030,6 +1034,41 @@ describe("loadAgentInstructionsPrefix", () => {
|
|
|
1030
1034
|
await fs.rm(root, { recursive: true, force: true });
|
|
1031
1035
|
}
|
|
1032
1036
|
});
|
|
1037
|
+
it("uses a stable escaped wrapper for a non-canonical configured entry file", async () => {
|
|
1038
|
+
const root = await fs.mkdtemp(path.join(os.tmpdir(), "rudder-load-agent-instructions-custom-entry-"));
|
|
1039
|
+
const instructionsPath = path.join(root, "instructions", "custom role.md");
|
|
1040
|
+
const contents = " generic entry code block\n\nKeep <angle brackets> and Markdown unchanged.\n";
|
|
1041
|
+
await fs.mkdir(path.dirname(instructionsPath), { recursive: true });
|
|
1042
|
+
await fs.writeFile(instructionsPath, contents, "utf8");
|
|
1043
|
+
try {
|
|
1044
|
+
const loaded = await loadAgentInstructionsPrefix({
|
|
1045
|
+
instructionsFilePath: instructionsPath,
|
|
1046
|
+
onLog: async () => { },
|
|
1047
|
+
});
|
|
1048
|
+
expect(loaded.prefix).toContain(`<agent_instruction_file path="$AGENT_HOME/instructions/custom role.md">\n${contents.trimEnd()}\n</agent_instruction_file>`);
|
|
1049
|
+
expect(loaded.prefix).not.toContain("<custom role.md>");
|
|
1050
|
+
}
|
|
1051
|
+
finally {
|
|
1052
|
+
await fs.rm(root, { recursive: true, force: true });
|
|
1053
|
+
}
|
|
1054
|
+
});
|
|
1055
|
+
it("preserves leading blank lines and indented Markdown in canonical instruction files", async () => {
|
|
1056
|
+
const root = await fs.mkdtemp(path.join(os.tmpdir(), "rudder-load-agent-instructions-leading-markdown-"));
|
|
1057
|
+
const instructionsPath = path.join(root, "instructions", "SOUL.md");
|
|
1058
|
+
const contents = "\n canonical code block\n\nKeep the leading bytes.\n";
|
|
1059
|
+
await fs.mkdir(path.dirname(instructionsPath), { recursive: true });
|
|
1060
|
+
await fs.writeFile(instructionsPath, contents, "utf8");
|
|
1061
|
+
try {
|
|
1062
|
+
const loaded = await loadAgentInstructionsPrefix({
|
|
1063
|
+
instructionsFilePath: instructionsPath,
|
|
1064
|
+
onLog: async () => { },
|
|
1065
|
+
});
|
|
1066
|
+
expect(loaded.prefix).toContain(`<SOUL.md>\n${contents.trimEnd()}\n</SOUL.md>`);
|
|
1067
|
+
}
|
|
1068
|
+
finally {
|
|
1069
|
+
await fs.rm(root, { recursive: true, force: true });
|
|
1070
|
+
}
|
|
1071
|
+
});
|
|
1033
1072
|
it("loads the entry instructions file plus sibling SOUL.md, TOOLS.md, and MEMORY.md", async () => {
|
|
1034
1073
|
const root = await fs.mkdtemp(path.join(os.tmpdir(), "rudder-load-agent-instructions-memory-"));
|
|
1035
1074
|
const instructionsPath = path.join(root, "instructions", "AGENTS.md");
|
|
@@ -1052,6 +1091,10 @@ describe("loadAgentInstructionsPrefix", () => {
|
|
|
1052
1091
|
expect(loaded.prefix).toContain("# Persona");
|
|
1053
1092
|
expect(loaded.prefix).toContain("# Tools");
|
|
1054
1093
|
expect(loaded.prefix).toContain("# Tacit Memory");
|
|
1094
|
+
expect(loaded.prefix).toContain("<AGENTS.md>\n# Agent Instructions\n</AGENTS.md>");
|
|
1095
|
+
expect(loaded.prefix).toContain("<SOUL.md>\n# Persona\n\nYou are QA.\n</SOUL.md>");
|
|
1096
|
+
expect(loaded.prefix).toContain("<TOOLS.md>\n# Tools\n\n- Use rudder.\n</TOOLS.md>");
|
|
1097
|
+
expect(loaded.prefix).toContain("<MEMORY.md>\n# Tacit Memory\n\n- Prefer concise updates.\n</MEMORY.md>");
|
|
1055
1098
|
expect(loaded.prefix).not.toContain("# Heartbeat");
|
|
1056
1099
|
expect(loaded.prefix).not.toContain("## Current Time");
|
|
1057
1100
|
expect(loaded.prefix).toContain("The above AGENTS.md, SOUL.md, TOOLS.md, MEMORY.md instruction files were loaded from $AGENT_HOME/instructions.");
|
|
@@ -1091,15 +1134,15 @@ describe("loadAgentInstructionsPrefix", () => {
|
|
|
1091
1134
|
const loaded = await loadAgentInstructionsPrefix({
|
|
1092
1135
|
instructionsFilePath: instructionsPath,
|
|
1093
1136
|
includeHeartbeatInstructions: true,
|
|
1094
|
-
instructionContextSections: ["
|
|
1137
|
+
instructionContextSections: ["<recent_rudder_context>\n#### today memory: 2026-06-21.md\n- Calibrate prompt stack\n</recent_rudder_context>"],
|
|
1095
1138
|
onLog: async () => { },
|
|
1096
1139
|
});
|
|
1097
|
-
const operatingContractIndex = loaded.prefix.indexOf("
|
|
1140
|
+
const operatingContractIndex = loaded.prefix.indexOf("<rudder_agent_operating_contract>");
|
|
1098
1141
|
const soulIndex = loaded.prefix.indexOf("# Persona");
|
|
1099
1142
|
const toolsIndex = loaded.prefix.indexOf("# Tool Notes");
|
|
1100
1143
|
const memoryIndex = loaded.prefix.indexOf("# Memory Notes");
|
|
1101
|
-
const recentContextIndex = loaded.prefix.indexOf("
|
|
1102
|
-
const heartbeatIndex = loaded.prefix.indexOf("
|
|
1144
|
+
const recentContextIndex = loaded.prefix.indexOf("<recent_rudder_context>");
|
|
1145
|
+
const heartbeatIndex = loaded.prefix.indexOf("<rudder_heartbeat_instruction>");
|
|
1103
1146
|
expect(operatingContractIndex).toBeGreaterThanOrEqual(0);
|
|
1104
1147
|
expect(soulIndex).toBeGreaterThan(operatingContractIndex);
|
|
1105
1148
|
expect(toolsIndex).toBeGreaterThan(soulIndex);
|
|
@@ -1110,6 +1153,9 @@ describe("loadAgentInstructionsPrefix", () => {
|
|
|
1110
1153
|
expect(loaded.prefix).toContain("# Persona");
|
|
1111
1154
|
expect(loaded.prefix).toContain("# Tool Notes");
|
|
1112
1155
|
expect(loaded.prefix).toContain("# Memory Notes");
|
|
1156
|
+
expect(loaded.prefix).toContain("<SOUL.md>\n# Persona");
|
|
1157
|
+
expect(loaded.prefix).toContain("<TOOLS.md>\n# Tool Notes");
|
|
1158
|
+
expect(loaded.prefix).toContain("<MEMORY.md>\n# Memory Notes");
|
|
1113
1159
|
expect(loaded.prefix).not.toContain("## Agent Instruction:");
|
|
1114
1160
|
expect(loaded.prefix).not.toContain("Agent Instruction: SOUL.md");
|
|
1115
1161
|
expect(loaded.prefix).not.toContain("The above SOUL.md content was loaded");
|
|
@@ -1135,7 +1181,7 @@ describe("loadAgentInstructionsPrefix", () => {
|
|
|
1135
1181
|
onLog: async () => { },
|
|
1136
1182
|
});
|
|
1137
1183
|
expect(loaded.prefix).toContain("# Persona");
|
|
1138
|
-
expect(loaded.prefix).toContain("
|
|
1184
|
+
expect(loaded.prefix).toContain("<rudder_heartbeat_instruction>");
|
|
1139
1185
|
expect(loaded.prefix).not.toContain("# Heartbeat\n\n- Check assignments.");
|
|
1140
1186
|
expect(loaded.commandNotes).toContain("Loaded Rudder heartbeat instructions from runtime code");
|
|
1141
1187
|
expect(loaded.commandNotes).not.toContain("Loaded supplemental agent heartbeat notes from $AGENT_HOME/instructions/HEARTBEAT.md");
|
|
@@ -1159,8 +1205,8 @@ describe("loadAgentInstructionsPrefix", () => {
|
|
|
1159
1205
|
try {
|
|
1160
1206
|
const instructionContext = prepareAgentInstructionRuntimeContext({
|
|
1161
1207
|
rudderWorkspace: {
|
|
1162
|
-
orgResourcesPrompt: "
|
|
1163
|
-
resourcesPrompt: "
|
|
1208
|
+
orgResourcesPrompt: "<current_automations>\n- Morning review\n</current_automations>",
|
|
1209
|
+
resourcesPrompt: "<current_automations>\n- Morning review\n</current_automations>",
|
|
1164
1210
|
},
|
|
1165
1211
|
});
|
|
1166
1212
|
const loaded = await loadAgentInstructionsPrefix({
|
|
@@ -1169,13 +1215,13 @@ describe("loadAgentInstructionsPrefix", () => {
|
|
|
1169
1215
|
instructionContextSections: instructionContext.instructionContextSections,
|
|
1170
1216
|
onLog: async () => { },
|
|
1171
1217
|
});
|
|
1172
|
-
const operatingContractIndex = loaded.prefix.indexOf("
|
|
1218
|
+
const operatingContractIndex = loaded.prefix.indexOf("<rudder_agent_operating_contract>");
|
|
1173
1219
|
const agentContractIndex = loaded.prefix.indexOf("# Agent Contract");
|
|
1174
1220
|
const soulIndex = loaded.prefix.indexOf("# Agent Soul");
|
|
1175
1221
|
const toolsIndex = loaded.prefix.indexOf("# Agent Tools");
|
|
1176
1222
|
const memoryIndex = loaded.prefix.indexOf("# Agent Memory");
|
|
1177
|
-
const automationsIndex = loaded.prefix.indexOf("
|
|
1178
|
-
const heartbeatIndex = loaded.prefix.indexOf("
|
|
1223
|
+
const automationsIndex = loaded.prefix.indexOf("<current_automations>");
|
|
1224
|
+
const heartbeatIndex = loaded.prefix.indexOf("<rudder_heartbeat_instruction>");
|
|
1179
1225
|
expect(operatingContractIndex).toBeGreaterThanOrEqual(0);
|
|
1180
1226
|
expect(agentContractIndex).toBeGreaterThan(operatingContractIndex);
|
|
1181
1227
|
expect(soulIndex).toBeGreaterThan(agentContractIndex);
|
|
@@ -1184,7 +1230,7 @@ describe("loadAgentInstructionsPrefix", () => {
|
|
|
1184
1230
|
expect(automationsIndex).toBeGreaterThan(memoryIndex);
|
|
1185
1231
|
expect(heartbeatIndex).toBeGreaterThan(automationsIndex);
|
|
1186
1232
|
expect(loaded.prefix).not.toContain("## Current Time");
|
|
1187
|
-
expect(loaded.prefix).toMatch(
|
|
1233
|
+
expect(loaded.prefix).toMatch(/<rudder_heartbeat_instruction>[\s\S]*runtime\.\n<\/rudder_heartbeat_instruction>$/);
|
|
1188
1234
|
expect(renderTemplate("{{context.rudderWorkspace.orgResourcesPrompt}}", { context: instructionContext.promptContext })).toBe("");
|
|
1189
1235
|
}
|
|
1190
1236
|
finally {
|
|
@@ -1192,7 +1238,7 @@ describe("loadAgentInstructionsPrefix", () => {
|
|
|
1192
1238
|
}
|
|
1193
1239
|
});
|
|
1194
1240
|
it("moves all documented resource prompt aliases into the stable instruction stack", async () => {
|
|
1195
|
-
const canonicalPrompt = "
|
|
1241
|
+
const canonicalPrompt = "<current_automations>\n- Canonical\n</current_automations>";
|
|
1196
1242
|
const topLevelOnly = prepareAgentInstructionRuntimeContext({
|
|
1197
1243
|
rudderResourcesPrompt: canonicalPrompt,
|
|
1198
1244
|
});
|
|
@@ -1214,7 +1260,7 @@ describe("loadAgentInstructionsPrefix", () => {
|
|
|
1214
1260
|
expect(renderTemplate("{{context.rudderWorkspace.orgResourcesPrompt}}", { context: legacyOnly.promptContext })).toBe("");
|
|
1215
1261
|
});
|
|
1216
1262
|
it("prefers canonical resourcesPrompt and only clears matching resource prompt aliases", async () => {
|
|
1217
|
-
const canonicalPrompt = "
|
|
1263
|
+
const canonicalPrompt = "<project_context_resources>\n- Canonical library context\n</project_context_resources>";
|
|
1218
1264
|
const legacyPrompt = "## Legacy Resources\n\n- Legacy fallback";
|
|
1219
1265
|
const prepared = prepareAgentInstructionRuntimeContext({
|
|
1220
1266
|
rudderResourcesPrompt: canonicalPrompt,
|
|
@@ -1241,7 +1287,7 @@ describe("loadAgentInstructionsPrefix", () => {
|
|
|
1241
1287
|
logs.push({ stream, chunk });
|
|
1242
1288
|
},
|
|
1243
1289
|
});
|
|
1244
|
-
expect(loaded.prefix).toContain("
|
|
1290
|
+
expect(loaded.prefix).toContain("<rudder_agent_operating_contract>");
|
|
1245
1291
|
expect(loaded.prefix).not.toContain("# Heartbeat");
|
|
1246
1292
|
expect(loaded.commandNotes).toContain("Ignored legacy HEARTBEAT.md instructions file: $AGENT_HOME/instructions/HEARTBEAT.md");
|
|
1247
1293
|
expect(loaded.heartbeatFilePath).toBeNull();
|
|
@@ -1270,7 +1316,7 @@ describe("loadAgentInstructionsPrefix", () => {
|
|
|
1270
1316
|
includeHeartbeatInstructions: true,
|
|
1271
1317
|
onLog: async () => { },
|
|
1272
1318
|
});
|
|
1273
|
-
expect(loaded.prefix).toContain("
|
|
1319
|
+
expect(loaded.prefix).toContain("<rudder_heartbeat_instruction>");
|
|
1274
1320
|
expect(loaded.prefix).not.toContain("# Heartbeat\n\n- Check assignments.");
|
|
1275
1321
|
expect(loaded.commandNotes).toContain("Loaded Rudder heartbeat instructions from runtime code");
|
|
1276
1322
|
expect(loaded.commandNotes).toContain("Ignored legacy HEARTBEAT.md instructions file: $AGENT_HOME/instructions/HEARTBEAT.md");
|
|
@@ -1296,7 +1342,7 @@ describe("loadAgentInstructionsPrefix", () => {
|
|
|
1296
1342
|
logs.push({ stream, chunk });
|
|
1297
1343
|
},
|
|
1298
1344
|
});
|
|
1299
|
-
expect(loaded.prefix).toContain("
|
|
1345
|
+
expect(loaded.prefix).toContain("<rudder_agent_operating_contract>");
|
|
1300
1346
|
expect(loaded.prefix).not.toContain("# Agent Instructions");
|
|
1301
1347
|
expect(loaded.readFailed).toBe(true);
|
|
1302
1348
|
expect(loaded.commandNotes).toContain("Configured instructionsFilePath $AGENT_HOME/instructions/AGENTS.md, but file could not be read; continuing without injected instructions.");
|