@elizaos/agent 2.0.0-alpha.204 → 2.0.0-alpha.206

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 (65) hide show
  1. package/apps/app-lifeops/src/actions/calendar.d.ts.map +1 -1
  2. package/apps/app-lifeops/src/actions/calendar.js +2 -1
  3. package/apps/app-lifeops/src/actions/cross-channel-send.d.ts.map +1 -1
  4. package/apps/app-lifeops/src/actions/cross-channel-send.js +15 -1
  5. package/apps/app-lifeops/src/actions/intent-sync.d.ts.map +1 -1
  6. package/apps/app-lifeops/src/actions/intent-sync.js +107 -14
  7. package/apps/app-lifeops/src/actions/relationships.d.ts.map +1 -1
  8. package/apps/app-lifeops/src/actions/relationships.js +7 -1
  9. package/apps/app-lifeops/src/actions/scheduling.d.ts.map +1 -1
  10. package/apps/app-lifeops/src/actions/scheduling.js +4 -5
  11. package/apps/app-lifeops/src/actions/subscriptions.d.ts.map +1 -1
  12. package/apps/app-lifeops/src/actions/subscriptions.js +71 -17
  13. package/apps/app-lifeops/src/actions/twilio-call.d.ts.map +1 -1
  14. package/apps/app-lifeops/src/actions/twilio-call.js +48 -1
  15. package/apps/app-lifeops/src/actions/website-blocker.d.ts.map +1 -1
  16. package/apps/app-lifeops/src/actions/website-blocker.js +2 -4
  17. package/apps/app-training/src/backends/atropos.d.ts.map +1 -1
  18. package/apps/app-training/src/backends/atropos.js +2 -4
  19. package/apps/app-training/src/backends/native.d.ts.map +1 -1
  20. package/apps/app-training/src/backends/native.js +4 -2
  21. package/apps/app-training/src/core/training-config.d.ts.map +1 -1
  22. package/apps/app-training/src/core/training-config.js +1 -6
  23. package/apps/app-training/src/optimizers/index.d.ts +1 -1
  24. package/apps/app-training/src/optimizers/index.d.ts.map +1 -1
  25. package/apps/app-training/src/optimizers/index.js +1 -1
  26. package/apps/app-training/src/optimizers/scoring.d.ts +19 -0
  27. package/apps/app-training/src/optimizers/scoring.d.ts.map +1 -1
  28. package/apps/app-training/src/optimizers/scoring.js +35 -1
  29. package/apps/app-training/src/services/training-service-like.d.ts +3 -2
  30. package/apps/app-training/src/services/training-service-like.d.ts.map +1 -1
  31. package/package.json +4 -4
  32. package/packages/agent/src/actions/skill-command.js +1 -1
  33. package/packages/agent/src/api/binance-skill-helpers.d.ts.map +1 -1
  34. package/packages/agent/src/api/binance-skill-helpers.js +6 -5
  35. package/packages/agent/src/api/chat-augmentation.d.ts.map +1 -1
  36. package/packages/agent/src/api/chat-augmentation.js +24 -12
  37. package/packages/agent/src/api/curated-skills-routes.d.ts.map +1 -1
  38. package/packages/agent/src/api/curated-skills-routes.js +1 -6
  39. package/packages/agent/src/api/onboarding-routes.d.ts.map +1 -1
  40. package/packages/agent/src/api/onboarding-routes.js +38 -5
  41. package/packages/agent/src/api/provider-switch-config.d.ts.map +1 -1
  42. package/packages/agent/src/api/provider-switch-config.js +6 -0
  43. package/packages/agent/src/api/server-types.d.ts +3 -2
  44. package/packages/agent/src/api/server-types.d.ts.map +1 -1
  45. package/packages/agent/src/api/skills-routes.d.ts.map +1 -1
  46. package/packages/agent/src/api/skills-routes.js +3 -47
  47. package/packages/agent/src/providers/skill-provider.js +2 -2
  48. package/packages/agent/src/runtime/eliza.js +1 -1
  49. package/packages/skills/src/resolver.d.ts.map +1 -1
  50. package/packages/skills/src/resolver.js +14 -4
  51. package/packages/typescript/src/features/advanced-capabilities/evaluators/skillExtraction.d.ts.map +1 -1
  52. package/packages/typescript/src/features/advanced-capabilities/evaluators/skillExtraction.js +1 -6
  53. package/packages/typescript/src/features/advanced-capabilities/evaluators/skillRefinement.d.ts.map +1 -1
  54. package/packages/typescript/src/features/advanced-capabilities/evaluators/skillRefinement.js +1 -5
  55. package/packages/typescript/src/generated/action-docs.d.ts +0 -10
  56. package/packages/typescript/src/generated/action-docs.d.ts.map +1 -1
  57. package/packages/typescript/src/generated/action-docs.js +0 -21
  58. package/packages/typescript/src/index.node.d.ts +1 -0
  59. package/packages/typescript/src/index.node.d.ts.map +1 -1
  60. package/packages/typescript/src/index.node.js +2 -0
  61. package/packages/typescript/src/services/optimized-prompt.d.ts.map +1 -1
  62. package/packages/typescript/src/services/optimized-prompt.js +1 -7
  63. package/packages/typescript/src/utils/state-dir.d.ts +19 -0
  64. package/packages/typescript/src/utils/state-dir.d.ts.map +1 -0
  65. package/packages/typescript/src/utils/state-dir.js +24 -0
@@ -1 +1 @@
1
- {"version":3,"file":"calendar.d.ts","sourceRoot":"","sources":["../../../../../../../apps/app-lifeops/src/actions/calendar.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,MAAM,EAKN,aAAa,EACb,MAAM,EACN,KAAK,EACN,MAAM,eAAe,CAAC;AAyCvB,KAAK,iBAAiB,GAClB,MAAM,GACN,YAAY,GACZ,eAAe,GACf,cAAc,GACd,cAAc,GACd,cAAc,GACd,aAAa,CAAC;AAuBlB,MAAM,MAAM,eAAe,GAAG;IAC5B,SAAS,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACpC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAkjDF,wBAAsB,0BAA0B,CAC9C,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,KAAK,GAAG,SAAS,EACxB,MAAM,EAAE,MAAM,EACd,QAAQ,SAA2B,GAClC,OAAO,CAAC,eAAe,CAAC,CA6J1B;AA2gCD,eAAO,MAAM,cAAc,EAAE,MAAM,GAAG;IACpC,8BAA8B,CAAC,EAAE,OAAO,CAAC;CAmqC1C,CAAC"}
1
+ {"version":3,"file":"calendar.d.ts","sourceRoot":"","sources":["../../../../../../../apps/app-lifeops/src/actions/calendar.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,MAAM,EAKN,aAAa,EACb,MAAM,EACN,KAAK,EACN,MAAM,eAAe,CAAC;AAyCvB,KAAK,iBAAiB,GAClB,MAAM,GACN,YAAY,GACZ,eAAe,GACf,cAAc,GACd,cAAc,GACd,cAAc,GACd,aAAa,CAAC;AAuBlB,MAAM,MAAM,eAAe,GAAG;IAC5B,SAAS,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACpC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAkjDF,wBAAsB,0BAA0B,CAC9C,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,KAAK,GAAG,SAAS,EACxB,MAAM,EAAE,MAAM,EACd,QAAQ,SAA2B,GAClC,OAAO,CAAC,eAAe,CAAC,CA6J1B;AA2gCD,eAAO,MAAM,cAAc,EAAE,MAAM,GAAG;IACpC,8BAA8B,CAAC,EAAE,OAAO,CAAC;CAoqC1C,CAAC"}
@@ -2126,7 +2126,8 @@ export const calendarAction = {
2126
2126
  "DO NOT use this action when the user is only making an observation like 'my calendar has been crazy this quarter' unless they actually ask you to inspect or change calendar state. " +
2127
2127
  "DO NOT use this action for email inbox work, drafting or sending emails — use GMAIL_ACTION instead. " +
2128
2128
  "DO NOT use this action for personal habits, goals, routines, or reminders — use LIFE instead. " +
2129
- "This action provides the final grounded reply; do not pair it with a speculative REPLY action.",
2129
+ "This action provides the final grounded reply; do not pair it with a speculative REPLY action." +
2130
+ " DO NOT use this action when the user asks to 'help schedule' / 'set up' / 'find a time for' a meeting with a person or team without a specific time — that is SCHEDULING (subaction start). DO NOT use this action to 'propose', 'suggest', or 'offer' meeting time slots — that is PROPOSE_MEETING_TIMES. Use CALENDAR_ACTION only when the user specifies (or intends to specify) a concrete date/time for the event.",
2130
2131
  descriptionCompressed: "Google Calendar via LifeOps: view schedule, search events, create events, query travel. Not for email or habits.",
2131
2132
  suppressPostActionContinuation: true,
2132
2133
  validate: async (runtime, message) => {
@@ -1 +1 @@
1
- {"version":3,"file":"cross-channel-send.d.ts","sourceRoot":"","sources":["../../../../../../../apps/app-lifeops/src/actions/cross-channel-send.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EACV,MAAM,EAMP,MAAM,eAAe,CAAC;AAyBvB,eAAO,MAAM,2BAA2B,yIAY9B,CAAC;AACX,MAAM,MAAM,uBAAuB,GAAG,CAAC,OAAO,2BAA2B,CAAC,CAAC,MAAM,CAAC,CAAC;AAwZnF,eAAO,MAAM,sBAAsB,EAAE,MAAM,GAAG;IAC5C,8BAA8B,CAAC,EAAE,OAAO,CAAC;CAsM1C,CAAC"}
1
+ {"version":3,"file":"cross-channel-send.d.ts","sourceRoot":"","sources":["../../../../../../../apps/app-lifeops/src/actions/cross-channel-send.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EACV,MAAM,EAMP,MAAM,eAAe,CAAC;AAyBvB,eAAO,MAAM,2BAA2B,yIAY9B,CAAC;AACX,MAAM,MAAM,uBAAuB,GAAG,CAAC,OAAO,2BAA2B,CAAC,CAAC,MAAM,CAAC,CAAC;AAwZnF,eAAO,MAAM,sBAAsB,EAAE,MAAM,GAAG;IAC5C,8BAA8B,CAAC,EAAE,OAAO,CAAC;CAoN1C,CAAC"}
@@ -390,10 +390,24 @@ export const crossChannelSendAction = {
390
390
  "DRAFT_MESSAGE",
391
391
  "SEND_ACROSS_CHANNEL",
392
392
  "SEND_MESSAGE",
393
+ "POST_TO_CHANNEL",
394
+ "POST_TO_DISCORD",
395
+ "POST_TO_SLACK",
396
+ "SEND_TELEGRAM",
397
+ "SEND_SIGNAL",
398
+ "SEND_WHATSAPP",
399
+ "SEND_IMESSAGE",
400
+ "SEND_SMS",
393
401
  ],
394
402
  description: "Draft or send a message across any connected channel (email, telegram, " +
395
403
  "discord, signal, sms, twilio_voice, imessage, whatsapp, notifications). Always " +
396
- "drafts first; caller must re-invoke with confirmed: true to dispatch.",
404
+ "drafts first; caller must re-invoke with confirmed: true to dispatch. " +
405
+ "Use this for any 'post <msg> to <channel>', 'send <msg> on <platform>', " +
406
+ "or 'dm <person> on <platform>' request — the channel name in the sentence " +
407
+ "(discord, telegram, signal, etc.) is the strongest signal. " +
408
+ "Do NOT use SCHEDULING for channel-send requests even if the message " +
409
+ "mentions a meeting-like word (e.g. 'standup', 'sync'); SCHEDULING is for " +
410
+ "negotiating calendar proposals, not relaying chat messages.",
397
411
  suppressPostActionContinuation: true,
398
412
  validate: async (runtime, message) => hasAdminAccess(runtime, message),
399
413
  parameters: [
@@ -1 +1 @@
1
- {"version":3,"file":"intent-sync.d.ts","sourceRoot":"","sources":["../../../../../../../apps/app-lifeops/src/actions/intent-sync.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,MAAM,EAMP,MAAM,eAAe,CAAC;AAmFvB,eAAO,MAAM,gBAAgB,EAAE,MAsO9B,CAAC"}
1
+ {"version":3,"file":"intent-sync.d.ts","sourceRoot":"","sources":["../../../../../../../apps/app-lifeops/src/actions/intent-sync.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,MAAM,EAMP,MAAM,eAAe,CAAC;AA+JvB,eAAO,MAAM,gBAAgB,EAAE,MAiR9B,CAAC"}
@@ -43,6 +43,78 @@ function fail(error, extra = {}) {
43
43
  data: { actionName: ACTION_NAME, error, ...extra },
44
44
  };
45
45
  }
46
+ // Validation terminates the turn cleanly: success: true at the ActionResult
47
+ // level (so the orchestrator does not retry), but values.success: false so
48
+ // downstream consumers see the logical failure. Carries descriptive text.
49
+ function validationTerminate(error, text, extra = {}) {
50
+ return {
51
+ text,
52
+ success: true,
53
+ values: { success: false, error, ...extra },
54
+ data: { actionName: ACTION_NAME, error, ...extra },
55
+ };
56
+ }
57
+ // Parse flat key=value params that arrive as a raw string instead of nested
58
+ // XML/JSON. Handles quoted and unquoted values.
59
+ function parseFlatParams(raw) {
60
+ const out = {};
61
+ const re = /(\w+)\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s]+))/g;
62
+ let m;
63
+ while ((m = re.exec(raw)) !== null) {
64
+ out[m[1]] = m[2] ?? m[3] ?? m[4] ?? "";
65
+ }
66
+ return out;
67
+ }
68
+ // Tolerate a wider shape: if `params` is a string (or carries a rawParams
69
+ // blob), attempt flat parsing and merge into a typed object.
70
+ function normalizeParams(raw) {
71
+ if (typeof raw === "string") {
72
+ return parseFlatParams(raw);
73
+ }
74
+ if (raw && typeof raw === "object") {
75
+ const obj = raw;
76
+ const merged = { ...obj };
77
+ const rawParams = obj.rawParams ?? obj.raw;
78
+ if (typeof rawParams === "string") {
79
+ const parsed = parseFlatParams(rawParams);
80
+ for (const [k, v] of Object.entries(parsed)) {
81
+ if (merged[k] === undefined)
82
+ merged[k] = v;
83
+ }
84
+ }
85
+ return merged;
86
+ }
87
+ return {};
88
+ }
89
+ function inferSubactionFromText(text) {
90
+ const t = text.toLowerCase();
91
+ if (/\b(broadcast|send|publish|push|ping)\b/.test(t))
92
+ return "broadcast";
93
+ if (/\b(list|show|what.*pending)\b/.test(t))
94
+ return "list_pending";
95
+ if (/\b(acknowledge|ack|mark\s+done)\b/.test(t))
96
+ return "acknowledge";
97
+ if (/\b(prune|expire|clean)\b/.test(t))
98
+ return "prune_expired";
99
+ return undefined;
100
+ }
101
+ function inferKindFromText(text) {
102
+ const t = text.toLowerCase();
103
+ if (/\b(reminder|stretch|break|vitamin|hydrate|water|walk)\b/.test(t)) {
104
+ if (isKind("routine_reminder"))
105
+ return "routine_reminder";
106
+ }
107
+ if (/\b(urgent|help|need)\b/.test(t)) {
108
+ if (isKind("attention_request"))
109
+ return "attention_request";
110
+ }
111
+ if (/\b(request|ask|please)\b/.test(t)) {
112
+ if (isKind("user_action_requested")) {
113
+ return "user_action_requested";
114
+ }
115
+ }
116
+ return undefined;
117
+ }
46
118
  export const intentSyncAction = {
47
119
  name: ACTION_NAME,
48
120
  similes: ["BROADCAST_INTENT", "SYNC_INTENT", "CROSS_DEVICE_INTENT"],
@@ -161,26 +233,47 @@ export const intentSyncAction = {
161
233
  if (!(await hasAdminAccess(runtime, message))) {
162
234
  return fail("PERMISSION_DENIED");
163
235
  }
164
- const params = options?.parameters ?? {};
165
- const subactionRaw = coerceString(params.subaction);
166
- if (!subactionRaw)
167
- return fail("MISSING_SUBACTION");
236
+ const rawParams = options?.parameters;
237
+ const params = normalizeParams(rawParams);
238
+ const messageText = typeof message.content?.text === "string" ? message.content.text : "";
239
+ let subactionRaw = coerceString(params.subaction);
240
+ if (!subactionRaw) {
241
+ // Tolerate LLMs that emit the verb in `intent` / `mode` / plain text.
242
+ subactionRaw =
243
+ coerceString(params.mode) ??
244
+ coerceString(params.action) ??
245
+ inferSubactionFromText(messageText);
246
+ }
247
+ if (!subactionRaw) {
248
+ return validationTerminate("MISSING_SUBACTION", "I couldn't tell whether you wanted to broadcast, list, acknowledge, or prune an intent. Please say which.");
249
+ }
168
250
  if (!isSubaction(subactionRaw)) {
169
- return fail("UNKNOWN_SUBACTION", { subaction: subactionRaw });
251
+ return validationTerminate("UNKNOWN_SUBACTION", `Unknown INTENT_SYNC subaction "${subactionRaw}". Expected one of: ${SUBACTIONS.join(", ")}.`, { subaction: subactionRaw });
170
252
  }
171
253
  const subaction = subactionRaw;
172
254
  if (subaction === "broadcast") {
173
- const kindRaw = coerceString(params.kind);
255
+ let kindRaw = coerceString(params.kind);
256
+ if (!kindRaw || !isKind(kindRaw)) {
257
+ // Only infer when the current value is clearly wrong/missing — not
258
+ // when it's already a valid kind.
259
+ const inferred = inferKindFromText(messageText);
260
+ if (inferred)
261
+ kindRaw = inferred;
262
+ }
174
263
  const title = coerceString(params.title);
175
264
  const body = coerceString(params.body);
176
- if (!kindRaw)
177
- return fail("MISSING_KIND");
178
- if (!isKind(kindRaw))
179
- return fail("UNKNOWN_KIND", { kind: kindRaw });
180
- if (!title)
181
- return fail("MISSING_TITLE");
182
- if (!body)
183
- return fail("MISSING_BODY");
265
+ if (!kindRaw) {
266
+ return validationTerminate("MISSING_KIND", `I need an intent kind to broadcast (one of: ${LIFE_INTENT_KINDS.join(", ")}).`);
267
+ }
268
+ if (!isKind(kindRaw)) {
269
+ return validationTerminate("UNKNOWN_KIND", `Unknown intent kind "${kindRaw}". Expected one of: ${LIFE_INTENT_KINDS.join(", ")}.`, { kind: kindRaw });
270
+ }
271
+ if (!title) {
272
+ return validationTerminate("MISSING_TITLE", "I need a short title for the intent before I can broadcast it.");
273
+ }
274
+ if (!body) {
275
+ return validationTerminate("MISSING_BODY", "I need a body for the intent before I can broadcast it.");
276
+ }
184
277
  const targetRaw = coerceString(params.target) ?? "all";
185
278
  if (!isTarget(targetRaw)) {
186
279
  return fail("UNKNOWN_TARGET", { target: targetRaw });
@@ -1 +1 @@
1
- {"version":3,"file":"relationships.d.ts","sourceRoot":"","sources":["../../../../../../../apps/app-lifeops/src/actions/relationships.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,MAAM,EAMP,MAAM,eAAe,CAAC;AA+XvB,eAAO,MAAM,kBAAkB,EAAE,MAAM,GAAG;IACxC,8BAA8B,CAAC,EAAE,OAAO,CAAC;CAia1C,CAAC"}
1
+ {"version":3,"file":"relationships.d.ts","sourceRoot":"","sources":["../../../../../../../apps/app-lifeops/src/actions/relationships.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,MAAM,EAMP,MAAM,eAAe,CAAC;AA+XvB,eAAO,MAAM,kBAAkB,EAAE,MAAM,GAAG;IACxC,8BAA8B,CAAC,EAAE,OAAO,CAAC;CAua1C,CAAC"}
@@ -270,13 +270,19 @@ function formatRelationshipLine(rel) {
270
270
  export const relationshipAction = {
271
271
  name: "RELATIONSHIP",
272
272
  similes: [
273
+ "RELATIONSHIPS",
273
274
  "CONTACT",
275
+ "CONTACTS",
274
276
  "ROLODEX",
275
277
  "FOLLOW_UP",
278
+ "FOLLOW_UPS",
276
279
  "LOG_INTERACTION",
277
280
  "ADD_CONTACT",
281
+ "DAYS_SINCE",
282
+ "LAST_CONTACTED",
278
283
  ],
279
- description: "Manage contacts, relationships, and follow-ups. Subactions: list_contacts, add_contact, log_interaction, add_follow_up, complete_follow_up, follow_up_list, days_since.",
284
+ description: "Manage contacts, relationships, and follow-ups. Subactions: list_contacts, add_contact, log_interaction, add_follow_up, complete_follow_up, follow_up_list, days_since." +
285
+ " Use for 'remind me to follow up with <person> [when]', 'add a follow-up with <person>', 'schedule a check-in with <person>' — subaction: add_follow_up. Use for 'how long since I talked to <person>' — subaction: days_since. Use for 'who do I need to follow up with' — subaction: follow_up_list.",
280
286
  suppressPostActionContinuation: true,
281
287
  validate: async (runtime, message) => hasLifeOpsAccess(runtime, message),
282
288
  handler: async (runtime, message, state, options, callback) => {
@@ -1 +1 @@
1
- {"version":3,"file":"scheduling.d.ts","sourceRoot":"","sources":["../../../../../../../apps/app-lifeops/src/actions/scheduling.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EACV,MAAM,EAOP,MAAM,eAAe,CAAC;AAMvB,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AAO9E,OAAO,EAIL,KAAK,yBAAyB,EAG/B,MAAM,6BAA6B,CAAC;AAUrC,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,6BAA6B,GAAG;IAC1C,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,2BAA2B,GAAG;IACxC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAkGF,wBAAgB,oBAAoB,CAAC,IAAI,EAAE;IACzC,GAAG,EAAE,IAAI,CAAC;IACV,WAAW,EAAE,IAAI,CAAC;IAClB,SAAS,EAAE,IAAI,CAAC;IAChB,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,yBAAyB,CAAC;IACvC,MAAM,EAAE,SAAS,oBAAoB,EAAE,CAAC;CACzC,GAAG,mBAAmB,EAAE,CAwExB;AAiCD,eAAO,MAAM,yBAAyB,EAAE,MAAM,GAAG;IAC/C,8BAA8B,CAAC,EAAE,OAAO,CAAC;CAgK1C,CAAC;AAEF,eAAO,MAAM,uBAAuB,EAAE,MAoGrC,CAAC;AAEF,eAAO,MAAM,8BAA8B,EAAE,MAAM,GAAG;IACpD,8BAA8B,CAAC,EAAE,OAAO,CAAC;CAqI1C,CAAC;AAsLF,eAAO,MAAM,gBAAgB,EAAE,MAwS9B,CAAC"}
1
+ {"version":3,"file":"scheduling.d.ts","sourceRoot":"","sources":["../../../../../../../apps/app-lifeops/src/actions/scheduling.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EACV,MAAM,EAOP,MAAM,eAAe,CAAC;AAMvB,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AAO9E,OAAO,EAIL,KAAK,yBAAyB,EAG/B,MAAM,6BAA6B,CAAC;AAUrC,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,6BAA6B,GAAG;IAC1C,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,2BAA2B,GAAG;IACxC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAkGF,wBAAgB,oBAAoB,CAAC,IAAI,EAAE;IACzC,GAAG,EAAE,IAAI,CAAC;IACV,WAAW,EAAE,IAAI,CAAC;IAClB,SAAS,EAAE,IAAI,CAAC;IAChB,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,yBAAyB,CAAC;IACvC,MAAM,EAAE,SAAS,oBAAoB,EAAE,CAAC;CACzC,GAAG,mBAAmB,EAAE,CAwExB;AAiCD,eAAO,MAAM,yBAAyB,EAAE,MAAM,GAAG;IAC/C,8BAA8B,CAAC,EAAE,OAAO,CAAC;CA8J1C,CAAC;AAEF,eAAO,MAAM,uBAAuB,EAAE,MAoGrC,CAAC;AAEF,eAAO,MAAM,8BAA8B,EAAE,MAAM,GAAG;IACpD,8BAA8B,CAAC,EAAE,OAAO,CAAC;CAqI1C,CAAC;AAsLF,eAAO,MAAM,gBAAgB,EAAE,MAyS9B,CAAC"}
@@ -185,16 +185,14 @@ export const proposeMeetingTimesAction = {
185
185
  "BUNDLE_MEETINGS_WHILE_TRAVELING",
186
186
  ],
187
187
  tags: [
188
- "always-include",
189
188
  "meeting slots",
190
- "bundle meetings",
191
- "travel scheduling",
192
189
  "reschedule options",
193
190
  ],
194
191
  description: "Propose candidate meeting time slots to offer to another person. " +
195
192
  "Reads the owner's calendar busy times and meeting preferences " +
196
193
  "(preferred hours, blackout windows, travel buffer) and returns " +
197
- "three available slots by default over the next seven days. Use this for bundled scheduling while traveling or when you need concrete reschedule options.",
194
+ "three available slots by default over the next seven days. Use this for bundled scheduling while traveling or when you need concrete reschedule options." +
195
+ " DO NOT use for small talk, weather, general conversation, or vague mentions of travel. Only fire when the user explicitly asks to propose / suggest / offer time slots to another person (e.g. 'propose three times for a meeting with Marco').",
198
196
  suppressPostActionContinuation: true,
199
197
  validate: async (runtime, message) => hasLifeOpsAccess(runtime, message),
200
198
  handler: async (runtime, message, _state, options, callback) => {
@@ -670,7 +668,8 @@ export const schedulingAction = {
670
668
  "Do not use this for first-turn calendar requests, recurring blocks, " +
671
669
  "travel-time bundling, missed-call repair, or fresh candidate-slot " +
672
670
  "searches; those belong to CALENDAR_ACTION, PROPOSE_MEETING_TIMES, INBOX, " +
673
- "or CROSS_CHANNEL_SEND.",
671
+ "or CROSS_CHANNEL_SEND." +
672
+ " Use for 'help me schedule a meeting with <person/team>', 'set up a sync with <person>', 'find a time with <team>' — subaction: start. Use for 'propose N times for a sync with <person>' — subaction: propose.",
674
673
  suppressPostActionContinuation: true,
675
674
  validate: async (runtime, message) => hasAdminAccess(runtime, message),
676
675
  handler: async (runtime, message, state, options, callback) => {
@@ -1 +1 @@
1
- {"version":3,"file":"subscriptions.d.ts","sourceRoot":"","sources":["../../../../../../../apps/app-lifeops/src/actions/subscriptions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,MAAM,EAOP,MAAM,eAAe,CAAC;AAqQvB,eAAO,MAAM,mBAAmB,EAAE,MAAM,GAAG;IACzC,8BAA8B,CAAC,EAAE,OAAO,CAAC;CAuC1C,CAAC"}
1
+ {"version":3,"file":"subscriptions.d.ts","sourceRoot":"","sources":["../../../../../../../apps/app-lifeops/src/actions/subscriptions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,MAAM,EAOP,MAAM,eAAe,CAAC;AAoUvB,eAAO,MAAM,mBAAmB,EAAE,MAAM,GAAG;IACzC,8BAA8B,CAAC,EAAE,OAAO,CAAC;CAuC1C,CAAC"}
@@ -1,5 +1,28 @@
1
1
  import { hasLifeOpsAccess, INTERNAL_URL } from "./lifeops-google-helpers.js";
2
2
  import { LifeOpsService, LifeOpsServiceError } from "../lifeops/service.js";
3
+ // Pre-seeded catalog of common subscription services so the cancel flow can
4
+ // resolve a user-friendly name like "Netflix" to a slug even when the live
5
+ // candidate audit has not populated the catalog yet.
6
+ const KNOWN_SUBSCRIPTION_SERVICES = {
7
+ netflix: { slug: "netflix", displayName: "Netflix", cancelUrl: "https://www.netflix.com/cancelplan" },
8
+ hulu: { slug: "hulu", displayName: "Hulu", cancelUrl: "https://www.hulu.com/account/cancel" },
9
+ disneyplus: { slug: "disney-plus", displayName: "Disney+", cancelUrl: "https://www.disneyplus.com/account/subscription" },
10
+ spotify: { slug: "spotify", displayName: "Spotify", cancelUrl: "https://www.spotify.com/account/subscription/" },
11
+ appletv: { slug: "apple-tv", displayName: "Apple TV+", cancelUrl: "https://tv.apple.com/account" },
12
+ youtubepremium: { slug: "youtube-premium", displayName: "YouTube Premium", cancelUrl: "https://www.youtube.com/paid_memberships" },
13
+ amazonprime: { slug: "amazon-prime", displayName: "Amazon Prime", cancelUrl: "https://www.amazon.com/gp/help/customer/display.html?nodeId=GKTRKLHHK7AJBJXE" },
14
+ applemusic: { slug: "apple-music", displayName: "Apple Music", cancelUrl: "https://music.apple.com/account/manage" },
15
+ hbomax: { slug: "hbo-max", displayName: "HBO Max", cancelUrl: "https://help.hbomax.com/us/article/cancellation-help" },
16
+ max: { slug: "hbo-max", displayName: "Max", cancelUrl: "https://help.hbomax.com/us/article/cancellation-help" },
17
+ paramountplus: { slug: "paramount-plus", displayName: "Paramount+", cancelUrl: "https://www.paramountplus.com/account/" },
18
+ peacock: { slug: "peacock", displayName: "Peacock", cancelUrl: "https://www.peacocktv.com/account/plan" },
19
+ };
20
+ function lookupKnownService(name) {
21
+ if (!name)
22
+ return null;
23
+ const normalized = name.toLowerCase().replace(/[\s+\-_]+/g, "");
24
+ return KNOWN_SUBSCRIPTION_SERVICES[normalized] ?? null;
25
+ }
3
26
  const ACTION_NAME = "SUBSCRIPTIONS";
4
27
  function messageText(message) {
5
28
  return typeof message.content?.text === "string" ? message.content.text : "";
@@ -95,23 +118,54 @@ async function runSubscriptionsAction(runtime, message, state, options) {
95
118
  };
96
119
  }
97
120
  case "cancel": {
98
- const summary = await service.cancelSubscription({
99
- candidateId: params.candidateId ?? null,
100
- serviceName,
101
- serviceSlug,
102
- executor: params.executor ?? inferred.executor ?? null,
103
- confirmed: parseConfirmed(text, params),
104
- });
105
- return {
106
- success: summary.cancellation.status !== "failed" &&
107
- summary.cancellation.status !== "unsupported_surface",
108
- text: service.summarizeSubscriptionCancellation(summary),
109
- data: {
110
- cancellation: summary.cancellation,
111
- candidate: summary.candidate,
112
- browserTask: browserTaskData(summary),
113
- },
114
- };
121
+ const known = lookupKnownService(serviceName ?? serviceSlug);
122
+ const resolvedSlug = serviceSlug ?? known?.slug ?? null;
123
+ const resolvedName = serviceName ?? known?.displayName ?? null;
124
+ try {
125
+ const summary = await service.cancelSubscription({
126
+ candidateId: params.candidateId ?? null,
127
+ serviceName: resolvedName,
128
+ serviceSlug: resolvedSlug,
129
+ executor: params.executor ?? inferred.executor ?? null,
130
+ confirmed: parseConfirmed(text, params),
131
+ });
132
+ return {
133
+ success: summary.cancellation.status !== "failed" &&
134
+ summary.cancellation.status !== "unsupported_surface",
135
+ text: service.summarizeSubscriptionCancellation(summary),
136
+ data: {
137
+ cancellation: summary.cancellation,
138
+ candidate: summary.candidate,
139
+ browserTask: browserTaskData(summary),
140
+ },
141
+ };
142
+ }
143
+ catch (err) {
144
+ // If the service catalog can't resolve the candidate, fall back to
145
+ // the pre-seeded known-service map and hand off to computer-use.
146
+ const msg = err instanceof Error ? err.message : String(err);
147
+ if (known && /candidate|serviceName|serviceSlug/i.test(msg)) {
148
+ return {
149
+ success: true,
150
+ text: `I don't have an active subscription record for ${known.displayName} yet, but I know the cancellation URL ` +
151
+ `(${known.cancelUrl ?? "not on file"}). I'll need to drive the browser to cancel it — ` +
152
+ `shall I continue with LIFEOPS_COMPUTER_USE?`,
153
+ values: {
154
+ success: false,
155
+ handoff: "LIFEOPS_COMPUTER_USE",
156
+ service: known.slug,
157
+ cancelUrl: known.cancelUrl ?? null,
158
+ },
159
+ data: {
160
+ handoff: "LIFEOPS_COMPUTER_USE",
161
+ service: known.slug,
162
+ displayName: known.displayName,
163
+ cancelUrl: known.cancelUrl ?? null,
164
+ },
165
+ };
166
+ }
167
+ throw err;
168
+ }
115
169
  }
116
170
  case "status": {
117
171
  const summary = await service.getSubscriptionCancellationStatus({
@@ -1 +1 @@
1
- {"version":3,"file":"twilio-call.d.ts","sourceRoot":"","sources":["../../../../../../../apps/app-lifeops/src/actions/twilio-call.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,MAAM,EAMZ,MAAM,eAAe,CAAC;AA4BvB,eAAO,MAAM,gBAAgB,EAAE,MAiM9B,CAAC;AA4BF,iBAAS,eAAe,CACtB,OAAO,EAAE;IAAE,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAA;CAAE,GAAG,SAAS,GAC7D,MAAM,GAAG,IAAI,CAUf;AAED,iBAAS,qBAAqB,CAC5B,OAAO,EAAE;IAAE,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAA;CAAE,GAAG,SAAS,GAC7D,MAAM,EAAE,CAiBV;AA0BD,eAAO,MAAM,cAAc,EAAE,MAAM,GAAG;IACpC,8BAA8B,CAAC,EAAE,OAAO,CAAC;CAgI1C,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,MAAM,GAAG;IACxC,8BAA8B,CAAC,EAAE,OAAO,CAAC;CA2M1C,CAAC;AAGF,eAAO,MAAM,UAAU;;;CAGtB,CAAC"}
1
+ {"version":3,"file":"twilio-call.d.ts","sourceRoot":"","sources":["../../../../../../../apps/app-lifeops/src/actions/twilio-call.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,MAAM,EAMZ,MAAM,eAAe,CAAC;AAmEvB,eAAO,MAAM,gBAAgB,EAAE,MA4M9B,CAAC;AA6BF,iBAAS,eAAe,CACtB,OAAO,EAAE;IAAE,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAA;CAAE,GAAG,SAAS,GAC7D,MAAM,GAAG,IAAI,CAUf;AAED,iBAAS,qBAAqB,CAC5B,OAAO,EAAE;IAAE,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAA;CAAE,GAAG,SAAS,GAC7D,MAAM,EAAE,CAiBV;AA0BD,eAAO,MAAM,cAAc,EAAE,MAAM,GAAG;IACpC,8BAA8B,CAAC,EAAE,OAAO,CAAC;CA0I1C,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,MAAM,GAAG;IACxC,8BAA8B,CAAC,EAAE,OAAO,CAAC;CA4N1C,CAAC;AAGF,eAAO,MAAM,UAAU;;;CAGtB,CAAC"}
@@ -15,6 +15,35 @@ function coerceBool(value) {
15
15
  return value.toLowerCase() === "true";
16
16
  return false;
17
17
  }
18
+ // E.164: leading +, 1-15 digits total, first digit non-zero.
19
+ const E164_RE = /^\+[1-9]\d{1,14}$/;
20
+ // All-5s placeholder (the classic "555" fake number, with common punctuation).
21
+ const PLACEHOLDER_555_RE = /^\+?1?[-\s]?\(?5{3}\)?[-\s]?5{3}[-\s]?5{4}$/;
22
+ function isE164(value) {
23
+ return E164_RE.test(value);
24
+ }
25
+ function isPlaceholderOrNonNumeric(value) {
26
+ if (PLACEHOLDER_555_RE.test(value))
27
+ return true;
28
+ // any letter indicates a natural-language phrase like "owner's cable company"
29
+ if (/[a-zA-Z]/.test(value))
30
+ return true;
31
+ return false;
32
+ }
33
+ function invalidPhoneResult(to, contact, actionName, errorCode) {
34
+ const subject = contact ?? "this contact";
35
+ const text = errorCode === "PLACEHOLDER_PHONE_NUMBER"
36
+ ? `"${to}" looks like a placeholder phone number. Please share the real E.164 number (e.g. +15551234567) for ${subject} before I can place the call.`
37
+ : `I need a valid phone number in E.164 format (e.g. +15551234567) to place the call. Please confirm the number for ${subject}.`;
38
+ return {
39
+ text,
40
+ // success: true so the agent loop treats the turn as complete and does
41
+ // not silently retry the handler.
42
+ success: true,
43
+ values: { success: false, error: errorCode, to, contact: contact ?? null },
44
+ data: { actionName, error: errorCode, to, contact: contact ?? null },
45
+ };
46
+ }
18
47
  export const twilioCallAction = {
19
48
  name: ACTION_NAME,
20
49
  similes: [
@@ -123,6 +152,12 @@ export const twilioCallAction = {
123
152
  data: { actionName: ACTION_NAME },
124
153
  };
125
154
  }
155
+ if (isPlaceholderOrNonNumeric(to)) {
156
+ return invalidPhoneResult(to, undefined, ACTION_NAME, "PLACEHOLDER_PHONE_NUMBER");
157
+ }
158
+ if (!isE164(to)) {
159
+ return invalidPhoneResult(to, undefined, ACTION_NAME, "INVALID_PHONE_NUMBER");
160
+ }
126
161
  if (!messageBody) {
127
162
  return {
128
163
  text: "Missing required parameter: message.",
@@ -307,6 +342,11 @@ export const callUserAction = {
307
342
  },
308
343
  };
309
344
  }
345
+ if (!isE164(to) || isPlaceholderOrNonNumeric(to)) {
346
+ return invalidPhoneResult(to, "the owner", "CALL_USER", isPlaceholderOrNonNumeric(to)
347
+ ? "PLACEHOLDER_PHONE_NUMBER"
348
+ : "INVALID_PHONE_NUMBER");
349
+ }
310
350
  const credentials = readTwilioCredentialsFromEnv();
311
351
  if (!credentials) {
312
352
  return {
@@ -406,14 +446,21 @@ export const callExternalAction = {
406
446
  }
407
447
  const params = options?.parameters ?? {};
408
448
  const to = params.to?.trim();
449
+ const contact = params.contact?.trim();
409
450
  if (!to) {
410
451
  return {
411
452
  text: "Who should I call, or which saved contact/phone number should I use?",
412
- success: false,
453
+ success: true,
413
454
  values: { success: false, error: "MISSING_RECIPIENT" },
414
455
  data: { actionName: "CALL_EXTERNAL", error: "MISSING_RECIPIENT" },
415
456
  };
416
457
  }
458
+ if (isPlaceholderOrNonNumeric(to)) {
459
+ return invalidPhoneResult(to, contact, "CALL_EXTERNAL", "PLACEHOLDER_PHONE_NUMBER");
460
+ }
461
+ if (!isE164(to)) {
462
+ return invalidPhoneResult(to, contact, "CALL_EXTERNAL", "INVALID_PHONE_NUMBER");
463
+ }
417
464
  if (params.confirmed !== true) {
418
465
  logger.info({ action: "CALL_EXTERNAL", to }, "[CALL_EXTERNAL] confirmation required");
419
466
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"website-blocker.d.ts","sourceRoot":"","sources":["../../../../../../../apps/app-lifeops/src/actions/website-blocker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,MAAM,EAKP,MAAM,eAAe,CAAC;AAsPvB,eAAO,MAAM,mBAAmB,EAAE,MAAM,GAAG;IACzC,8BAA8B,CAAC,EAAE,OAAO,CAAC;CAyQ1C,CAAC;AAEF,eAAO,MAAM,2BAA2B,EAAE,MAuDzC,CAAC;AAEF,eAAO,MAAM,sCAAsC,EAAE,MA8DpD,CAAC;AAEF,eAAO,MAAM,qBAAqB,EAAE,MA6FnC,CAAC;AAEF,eAAO,MAAM,8BAA8B;qCAneR,OAAO;CAmeuB,CAAC;AAClE,eAAO,MAAM,0BAA0B,QAA8B,CAAC;AACtE,eAAO,MAAM,kCAAkC,QACP,CAAC;AACzC,eAAO,MAAM,gCAAgC,QAAwB,CAAC"}
1
+ {"version":3,"file":"website-blocker.d.ts","sourceRoot":"","sources":["../../../../../../../apps/app-lifeops/src/actions/website-blocker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,MAAM,EAKP,MAAM,eAAe,CAAC;AAsPvB,eAAO,MAAM,mBAAmB,EAAE,MAAM,GAAG;IACzC,8BAA8B,CAAC,EAAE,OAAO,CAAC;CAuQ1C,CAAC;AAEF,eAAO,MAAM,2BAA2B,EAAE,MAuDzC,CAAC;AAEF,eAAO,MAAM,sCAAsC,EAAE,MA8DpD,CAAC;AAEF,eAAO,MAAM,qBAAqB,EAAE,MA6FnC,CAAC;AAEF,eAAO,MAAM,8BAA8B;qCAjeR,OAAO;CAieuB,CAAC;AAClE,eAAO,MAAM,0BAA0B,QAA8B,CAAC;AACtE,eAAO,MAAM,kCAAkC,QACP,CAAC;AACzC,eAAO,MAAM,gCAAgC,QAAwB,CAAC"}
@@ -187,16 +187,14 @@ export const blockWebsitesAction = {
187
187
  "START_FOCUS_BLOCK",
188
188
  "BLOCK_SITE",
189
189
  "BLOCK_DISTRACTING_SITES",
190
- "FOCUS_BLOCK",
191
- "BLOCK_SOCIAL_MEDIA",
192
- "SOCIAL_MEDIA_BLOCK",
193
190
  ],
194
191
  description: "Admin-only. Start a local website block by editing the system hosts file. " +
195
192
  "Use this for fixed-duration or generic focus blocks like 'block twitter and reddit for the next 2 hours', 'turn on a focus block for all social media sites', or 'block youtube'. " +
196
193
  "Use recent conversation context to block public websites like x.com for a fixed duration or until manually unblocked. " +
197
194
  "Do not use this when the unblock condition is finishing a task, workout, or todo; that is BLOCK_UNTIL_TASK_COMPLETE. " +
198
195
  "Always drafts first; the owner must pass confirmed: true (e.g. by replying 'confirm') to actually edit the hosts file. " +
199
- "If the user confirms a block in a follow-up message without repeating the hostnames, reuse that context through the action planner.",
196
+ "If the user confirms a block in a follow-up message without repeating the hostnames, reuse that context through the action planner." +
197
+ " DO NOT use this action when the user references apps, games, or things 'on my phone' / 'on my device' — use BLOCK_APPS for those. Do not pair this action with a speculative REPLY; this action provides the final reply itself.",
200
198
  descriptionCompressed: "Admin: block websites via hosts file for set duration.",
201
199
  suppressPostActionContinuation: true,
202
200
  validate: async (runtime, message) => {
@@ -1 +1 @@
1
- {"version":3,"file":"atropos.d.ts","sourceRoot":"","sources":["../../../../../../../apps/app-training/src/backends/atropos.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAMH,MAAM,WAAW,qBAAqB;IACrC,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,oBAAoB;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAaD,wBAAsB,iBAAiB,CACtC,OAAO,EAAE,qBAAqB,GAC5B,OAAO,CAAC,oBAAoB,CAAC,CAoC/B"}
1
+ {"version":3,"file":"atropos.d.ts","sourceRoot":"","sources":["../../../../../../../apps/app-training/src/backends/atropos.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAOH,MAAM,WAAW,qBAAqB;IACrC,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,oBAAoB;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AASD,wBAAsB,iBAAiB,CACtC,OAAO,EAAE,qBAAqB,GAC5B,OAAO,CAAC,oBAAoB,CAAC,CAoC/B"}
@@ -16,16 +16,14 @@
16
16
  import { mkdirSync, copyFileSync, existsSync } from "node:fs";
17
17
  import { join, basename, resolve } from "node:path";
18
18
  import { spawnSync } from "node:child_process";
19
+ import { resolveStateDir } from "@elizaos/core";
19
20
  function resolveDataDir(override) {
20
21
  if (override)
21
22
  return override;
22
23
  const fromEnv = process.env.ATROPOS_DATA_DIR?.trim();
23
24
  if (fromEnv)
24
25
  return fromEnv;
25
- const stateDir = process.env.MILADY_STATE_DIR?.trim() ||
26
- process.env.ELIZA_STATE_DIR?.trim() ||
27
- join(process.env.HOME ?? "", ".milady");
28
- return join(stateDir, "training", "atropos");
26
+ return join(resolveStateDir(), "training", "atropos");
29
27
  }
30
28
  export async function runAtroposBackend(options) {
31
29
  if (!existsSync(options.datasetPath)) {
@@ -1 +1 @@
1
- {"version":3,"file":"native.d.ts","sourceRoot":"","sources":["../../../../../../../apps/app-training/src/backends/native.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,OAAO,EAGN,KAAK,UAAU,EAEf,KAAK,aAAa,EAClB,KAAK,eAAe,EAIpB,KAAK,eAAe,EACpB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,qCAAqC,CAAC;AAElF,MAAM,WAAW,oBAAoB;IACpC;;;OAGG;IACH,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,sBAAsB,CAAC;IAC7B,SAAS,EAAE,aAAa,CAAC;IACzB,kDAAkD;IAClD,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uDAAuD;IACvD,OAAO,EAAE;QAAE,QAAQ,EAAE,eAAe,CAAA;KAAE,CAAC;IACvC,gCAAgC;IAChC,OAAO,CAAC,EAAE,UAAU,CAAC;CACrB;AAED,MAAM,WAAW,mBAAmB;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,aAAa,CAAC;IACzB,IAAI,EAAE,sBAAsB,CAAC;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,eAAe,CAAC;IACxB,KAAK,EAAE,MAAM,EAAE,CAAC;CAChB;AAsFD,wBAAsB,gBAAgB,CACrC,OAAO,EAAE,oBAAoB,GAC3B,OAAO,CAAC,mBAAmB,CAAC,CA2C9B;AAED,eAAO,MAAM,iBAAiB,EAAE,SAAS,aAAa,EAI5C,CAAC"}
1
+ {"version":3,"file":"native.d.ts","sourceRoot":"","sources":["../../../../../../../apps/app-training/src/backends/native.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,OAAO,EAGN,KAAK,UAAU,EAEf,KAAK,aAAa,EAClB,KAAK,eAAe,EAKpB,KAAK,eAAe,EACpB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,qCAAqC,CAAC;AAElF,MAAM,WAAW,oBAAoB;IACpC;;;OAGG;IACH,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,sBAAsB,CAAC;IAC7B,SAAS,EAAE,aAAa,CAAC;IACzB,kDAAkD;IAClD,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uDAAuD;IACvD,OAAO,EAAE;QAAE,QAAQ,EAAE,eAAe,CAAA;KAAE,CAAC;IACvC,gCAAgC;IAChC,OAAO,CAAC,EAAE,UAAU,CAAC;CACrB;AAED,MAAM,WAAW,mBAAmB;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,aAAa,CAAC;IACzB,IAAI,EAAE,sBAAsB,CAAC;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,eAAe,CAAC;IACxB,KAAK,EAAE,MAAM,EAAE,CAAC;CAChB;AAsFD,wBAAsB,gBAAgB,CACrC,OAAO,EAAE,oBAAoB,GAC3B,OAAO,CAAC,mBAAmB,CAAC,CA6C9B;AAED,eAAO,MAAM,iBAAiB,EAAE,SAAS,aAAa,EAI5C,CAAC"}
@@ -17,7 +17,7 @@
17
17
  */
18
18
  import { existsSync, readFileSync } from "node:fs";
19
19
  import { basename } from "node:path";
20
- import { createPromptScorer, createRuntimeAdapter, runBootstrapFewshot, runInstructionSearch, runPromptEvolution, } from "../optimizers/index.js";
20
+ import { createPromptScorer, createRuntimeAdapter, runBootstrapFewshot, runInstructionSearch, runPromptEvolution, scorePlannerAction, } from "../optimizers/index.js";
21
21
  function parseJsonlDataset(path) {
22
22
  if (!existsSync(path)) {
23
23
  throw new Error(`[native-backend] dataset not found at ${path}`);
@@ -101,7 +101,9 @@ export async function runNativeBackend(options) {
101
101
  };
102
102
  }
103
103
  const adapter = options.adapter ?? createRuntimeAdapter(options.runtime.useModel);
104
- const scorer = createPromptScorer(adapter);
104
+ const scorer = createPromptScorer(adapter, {
105
+ compare: options.task === "action_planner" ? scorePlannerAction : undefined,
106
+ });
105
107
  const result = await dispatchOptimizer(options.optimizer, {
106
108
  baselinePrompt: options.baselinePrompt,
107
109
  dataset,
@@ -1 +1 @@
1
- {"version":3,"file":"training-config.d.ts","sourceRoot":"","sources":["../../../../../../../apps/app-training/src/core/training-config.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAE5E,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAEzE,eAAO,MAAM,qBAAqB,EAAE,SAAS,eAAe,EAKlD,CAAC;AAEX,eAAO,MAAM,kBAAkB,EAAE,SAAS,sBAAsB,EAMtD,CAAC;AAEX,MAAM,WAAW,eAAe;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,eAAe,CAAC;CAC3B;AAED,MAAM,WAAW,cAAc;IAC7B,qCAAqC;IACrC,SAAS,EAAE,OAAO,CAAC;IACnB,qDAAqD;IACrD,gBAAgB,EAAE,MAAM,CAAC;IACzB,gEAAgE;IAChE,oBAAoB,EAAE,MAAM,CAAC;IAC7B;;;;;;;OAOG;IACH,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,gBAAgB,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,sBAAsB,EAAE,eAAe,CAAC,CAAC,CAAC;CAC7E;AAED,eAAO,MAAM,uBAAuB,EAAE,cASlB,CAAC;AAUrB,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAuCD;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,cAAc,CA8BtE;AAED,wBAAgB,kBAAkB,IAAI,cAAc,CAKnD;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI,CAK/D;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,eAAe,GAAG,IAAI,CAAC;CACjC;AAED,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,cAAc,EACtB,IAAI,EAAE,sBAAsB,GAC3B,kBAAkB,CAUpB"}
1
+ {"version":3,"file":"training-config.d.ts","sourceRoot":"","sources":["../../../../../../../apps/app-training/src/core/training-config.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAE5E,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAEzE,eAAO,MAAM,qBAAqB,EAAE,SAAS,eAAe,EAKlD,CAAC;AAEX,eAAO,MAAM,kBAAkB,EAAE,SAAS,sBAAsB,EAMtD,CAAC;AAEX,MAAM,WAAW,eAAe;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,eAAe,CAAC;CAC3B;AAED,MAAM,WAAW,cAAc;IAC7B,qCAAqC;IACrC,SAAS,EAAE,OAAO,CAAC;IACnB,qDAAqD;IACrD,gBAAgB,EAAE,MAAM,CAAC;IACzB,gEAAgE;IAChE,oBAAoB,EAAE,MAAM,CAAC;IAC7B;;;;;;;OAOG;IACH,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,gBAAgB,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,sBAAsB,EAAE,eAAe,CAAC,CAAC,CAAC;CAC7E;AAED,eAAO,MAAM,uBAAuB,EAAE,cASlB,CAAC;AAErB,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAuCD;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,cAAc,CA8BtE;AAED,wBAAgB,kBAAkB,IAAI,cAAc,CAKnD;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI,CAK/D;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,eAAe,GAAG,IAAI,CAAC;CACjC;AAED,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,cAAc,EACtB,IAAI,EAAE,sBAAsB,GAC3B,kBAAkB,CAUpB"}
@@ -7,8 +7,8 @@
7
7
  * over typed defaults; absent fields fall through to the defaults.
8
8
  */
9
9
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
10
- import { homedir } from "node:os";
11
10
  import { dirname, join } from "node:path";
11
+ import { resolveStateDir } from "@elizaos/core";
12
12
  export const ALL_TRAINING_BACKENDS = [
13
13
  "vertex",
14
14
  "atropos",
@@ -32,11 +32,6 @@ export const DEFAULT_TRAINING_CONFIG = Object.freeze({
32
32
  // (vertex/atropos/tinker) when they want hosted training instead.
33
33
  backends: ["native"],
34
34
  });
35
- function resolveStateDir() {
36
- return (process.env.MILADY_STATE_DIR?.trim() ||
37
- process.env.ELIZA_STATE_DIR?.trim() ||
38
- join(homedir(), ".milady"));
39
- }
40
35
  export function trainingStateRoot() {
41
36
  return join(resolveStateDir(), "training");
42
37
  }
@@ -1,5 +1,5 @@
1
1
  export type { LlmAdapter, OptimizationExample, OptimizedPromptArtifact, OptimizerLineageEntry, OptimizerName, OptimizerResult, PromptScorer, } from "./types.js";
2
- export { createPromptScorer, createRuntimeAdapter, scoreAgreement, subsample, type UseModelHandler, } from "./scoring.js";
2
+ export { createPromptScorer, createRuntimeAdapter, extractPlannerAction, scoreAgreement, scorePlannerAction, subsample, type UseModelHandler, } from "./scoring.js";
3
3
  export { runInstructionSearch, type InstructionSearchInput, type InstructionSearchOptions, } from "./instruction-search.js";
4
4
  export { runPromptEvolution, type PromptEvolutionInput, type PromptEvolutionOptions, } from "./prompt-evolution.js";
5
5
  export { renderDemonstrations, runBootstrapFewshot, withDemonstrations, type BootstrapFewshotInput, type BootstrapFewshotOptions, } from "./bootstrap-fewshot.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../apps/app-training/src/optimizers/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACX,UAAU,EACV,mBAAmB,EACnB,uBAAuB,EACvB,qBAAqB,EACrB,aAAa,EACb,eAAe,EACf,YAAY,GACZ,MAAM,YAAY,CAAC;AACpB,OAAO,EACN,kBAAkB,EAClB,oBAAoB,EACpB,cAAc,EACd,SAAS,EACT,KAAK,eAAe,GACpB,MAAM,cAAc,CAAC;AACtB,OAAO,EACN,oBAAoB,EACpB,KAAK,sBAAsB,EAC3B,KAAK,wBAAwB,GAC7B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACN,kBAAkB,EAClB,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,GAC3B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACN,oBAAoB,EACpB,mBAAmB,EACnB,kBAAkB,EAClB,KAAK,qBAAqB,EAC1B,KAAK,uBAAuB,GAC5B,MAAM,wBAAwB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../apps/app-training/src/optimizers/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACX,UAAU,EACV,mBAAmB,EACnB,uBAAuB,EACvB,qBAAqB,EACrB,aAAa,EACb,eAAe,EACf,YAAY,GACZ,MAAM,YAAY,CAAC;AACpB,OAAO,EACN,kBAAkB,EAClB,oBAAoB,EACpB,oBAAoB,EACpB,cAAc,EACd,kBAAkB,EAClB,SAAS,EACT,KAAK,eAAe,GACpB,MAAM,cAAc,CAAC;AACtB,OAAO,EACN,oBAAoB,EACpB,KAAK,sBAAsB,EAC3B,KAAK,wBAAwB,GAC7B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACN,kBAAkB,EAClB,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,GAC3B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACN,oBAAoB,EACpB,mBAAmB,EACnB,kBAAkB,EAClB,KAAK,qBAAqB,EAC1B,KAAK,uBAAuB,GAC5B,MAAM,wBAAwB,CAAC"}
@@ -1,4 +1,4 @@
1
- export { createPromptScorer, createRuntimeAdapter, scoreAgreement, subsample, } from "./scoring.js";
1
+ export { createPromptScorer, createRuntimeAdapter, extractPlannerAction, scoreAgreement, scorePlannerAction, subsample, } from "./scoring.js";
2
2
  export { runInstructionSearch, } from "./instruction-search.js";
3
3
  export { runPromptEvolution, } from "./prompt-evolution.js";
4
4
  export { renderDemonstrations, runBootstrapFewshot, withDemonstrations, } from "./bootstrap-fewshot.js";