@rubytech/create-realagent-code 0.1.612 → 0.1.614

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 (64) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/lib/agent-dispatch-rule/dist/index.d.ts +34 -0
  3. package/payload/platform/lib/agent-dispatch-rule/dist/index.d.ts.map +1 -1
  4. package/payload/platform/lib/agent-dispatch-rule/dist/index.js +39 -0
  5. package/payload/platform/lib/agent-dispatch-rule/dist/index.js.map +1 -1
  6. package/payload/platform/lib/agent-dispatch-rule/src/__tests__/carrier-verdict.test.ts +92 -0
  7. package/payload/platform/lib/agent-dispatch-rule/src/index.ts +59 -0
  8. package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +67 -10
  9. package/payload/platform/plugins/admin/skills/whats-new/SKILL.md +11 -0
  10. package/payload/platform/plugins/docs/references/telegram-guide.md +66 -9
  11. package/payload/platform/plugins/scheduling/mcp/dist/index.js +2 -0
  12. package/payload/platform/plugins/scheduling/mcp/dist/index.js.map +1 -1
  13. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/agent-dispatch-carrier.test.d.ts +2 -0
  14. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/agent-dispatch-carrier.test.d.ts.map +1 -0
  15. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/agent-dispatch-carrier.test.js +72 -0
  16. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/agent-dispatch-carrier.test.js.map +1 -0
  17. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/routine-delivery-reconcile.test.d.ts +2 -0
  18. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/routine-delivery-reconcile.test.d.ts.map +1 -0
  19. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/routine-delivery-reconcile.test.js +327 -0
  20. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/routine-delivery-reconcile.test.js.map +1 -0
  21. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/routine-delivery.test.d.ts +2 -0
  22. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/routine-delivery.test.d.ts.map +1 -0
  23. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/routine-delivery.test.js +130 -0
  24. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/routine-delivery.test.js.map +1 -0
  25. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/routine-run.test.js +27 -58
  26. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/routine-run.test.js.map +1 -1
  27. package/payload/platform/plugins/scheduling/mcp/dist/lib/agent-dispatch.d.ts +8 -3
  28. package/payload/platform/plugins/scheduling/mcp/dist/lib/agent-dispatch.d.ts.map +1 -1
  29. package/payload/platform/plugins/scheduling/mcp/dist/lib/agent-dispatch.js +37 -3
  30. package/payload/platform/plugins/scheduling/mcp/dist/lib/agent-dispatch.js.map +1 -1
  31. package/payload/platform/plugins/scheduling/mcp/dist/lib/routine-delivery.d.ts +67 -0
  32. package/payload/platform/plugins/scheduling/mcp/dist/lib/routine-delivery.d.ts.map +1 -0
  33. package/payload/platform/plugins/scheduling/mcp/dist/lib/routine-delivery.js +133 -0
  34. package/payload/platform/plugins/scheduling/mcp/dist/lib/routine-delivery.js.map +1 -0
  35. package/payload/platform/plugins/scheduling/mcp/dist/lib/routine-run.d.ts +67 -12
  36. package/payload/platform/plugins/scheduling/mcp/dist/lib/routine-run.d.ts.map +1 -1
  37. package/payload/platform/plugins/scheduling/mcp/dist/lib/routine-run.js +226 -72
  38. package/payload/platform/plugins/scheduling/mcp/dist/lib/routine-run.js.map +1 -1
  39. package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/agent-turn-dispatch.test.js +66 -4
  40. package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/agent-turn-dispatch.test.js.map +1 -1
  41. package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/reconcile-run-controls.test.d.ts +2 -0
  42. package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/reconcile-run-controls.test.d.ts.map +1 -0
  43. package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/reconcile-run-controls.test.js +45 -0
  44. package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/reconcile-run-controls.test.js.map +1 -0
  45. package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.d.ts +3 -1
  46. package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.d.ts.map +1 -1
  47. package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.js +32 -7
  48. package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.js.map +1 -1
  49. package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js +12 -1
  50. package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js.map +1 -1
  51. package/payload/platform/plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js +15 -2
  52. package/payload/platform/plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js.map +1 -1
  53. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.d.ts +14 -0
  54. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.d.ts.map +1 -1
  55. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.js +4 -0
  56. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.js.map +1 -1
  57. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-get.d.ts +3 -0
  58. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-get.d.ts.map +1 -1
  59. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-get.js +2 -0
  60. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-get.js.map +1 -1
  61. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-update.d.ts.map +1 -1
  62. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-update.js +14 -0
  63. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-update.js.map +1 -1
  64. package/payload/server/server.js +804 -724
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rubytech/create-realagent-code",
3
- "version": "0.1.612",
3
+ "version": "0.1.614",
4
4
  "description": "Install Real Agent — Built for agents. By agents.",
5
5
  "bin": {
6
6
  "create-realagent-code": "./dist/index.js"
@@ -155,5 +155,39 @@ export declare function isDispatchable(fields: DispatchFields): boolean;
155
155
  * (Task 2393), which re-exports it so its fire-site callers are unchanged.
156
156
  */
157
157
  export declare function dispatchGapReason(fields: DispatchFields): string;
158
+ /**
159
+ * Task 2776 — why a named carrier bot may not carry a destination.
160
+ *
161
+ * Three reasons, kept apart because they call for different operator actions: a
162
+ * bot id that names nothing (`absent`), a bot that exists on another role
163
+ * (`not-admin`), and an admin bot that does not admit this chat (`not-listed`).
164
+ *
165
+ * `not-admin` is the measured case. A routine authored against one bot silently
166
+ * changed carrier when that bot's `role` changed elsewhere, and every report
167
+ * landed in that bot's conversation rather than the operator's, with no event
168
+ * and no refusal naming the switch.
169
+ */
170
+ export type CarrierReason = "absent" | "not-admin" | "not-listed";
171
+ export type CarrierVerdict = {
172
+ ok: true;
173
+ } | {
174
+ ok: false;
175
+ reason: CarrierReason;
176
+ };
177
+ /**
178
+ * May `botId` carry `destination` for the account at `accountDir`?
179
+ *
180
+ * Reads the RAW `telegram.bots` array rather than `readChannelAdmins().byBot`,
181
+ * because that projection drops every entry whose role is not `admin` and so
182
+ * cannot tell a missing bot from a demoted one — the distinction the three
183
+ * reasons exist for. Fail-closed: unreadable or malformed config yields
184
+ * `absent`, matching the empty-list default `readChannelAdmins` already applies.
185
+ *
186
+ * The ONE authority for a named carrier. `validateAgentDispatch` calls it at
187
+ * write time and `schedule-inject` calls it at fire time, so the picker, the
188
+ * save and the dispatch cannot disagree — the guarantee Task 2368 states for
189
+ * the resolver path, extended to the named one.
190
+ */
191
+ export declare function carrierVerdict(accountDir: string, botId: string, destination: string): CarrierVerdict;
158
192
  export {};
159
193
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -9,6 +9,7 @@ exports.validateAgentDestination = validateAgentDestination;
9
9
  exports.listDispatchDestinations = listDispatchDestinations;
10
10
  exports.isDispatchable = isDispatchable;
11
11
  exports.dispatchGapReason = dispatchGapReason;
12
+ exports.carrierVerdict = carrierVerdict;
12
13
  /**
13
14
  * The dispatch-destination rule, shared by the scheduling plugin and the admin
14
15
  * UI so create-time, fire-time and dashboard-time cannot diverge on the rule or
@@ -301,4 +302,42 @@ function dispatchGapReason(fields) {
301
302
  }
302
303
  return "no-dispatch-configured";
303
304
  }
305
+ /**
306
+ * May `botId` carry `destination` for the account at `accountDir`?
307
+ *
308
+ * Reads the RAW `telegram.bots` array rather than `readChannelAdmins().byBot`,
309
+ * because that projection drops every entry whose role is not `admin` and so
310
+ * cannot tell a missing bot from a demoted one — the distinction the three
311
+ * reasons exist for. Fail-closed: unreadable or malformed config yields
312
+ * `absent`, matching the empty-list default `readChannelAdmins` already applies.
313
+ *
314
+ * The ONE authority for a named carrier. `validateAgentDispatch` calls it at
315
+ * write time and `schedule-inject` calls it at fire time, so the picker, the
316
+ * save and the dispatch cannot disagree — the guarantee Task 2368 states for
317
+ * the resolver path, extended to the named one.
318
+ */
319
+ function carrierVerdict(accountDir, botId, destination) {
320
+ let config = {};
321
+ try {
322
+ config = JSON.parse((0, node_fs_1.readFileSync)((0, node_path_1.resolve)(accountDir, "account.json"), "utf-8"));
323
+ }
324
+ catch {
325
+ return { ok: false, reason: "absent" };
326
+ }
327
+ const bots = Array.isArray(config.telegram?.bots) ? config.telegram.bots : [];
328
+ const entry = bots.find((raw) => raw && typeof raw === "object" && raw.id === botId);
329
+ if (!entry)
330
+ return { ok: false, reason: "absent" };
331
+ if (entry.role !== "admin")
332
+ return { ok: false, reason: "not-admin" };
333
+ const users = Array.isArray(entry.adminUsers)
334
+ ? entry.adminUsers.filter((u) => typeof u === "number")
335
+ : [];
336
+ // The destination is a string everywhere on the dispatch path; the stored list
337
+ // is numeric. A non-numeric destination yields NaN, which is in no list, so it
338
+ // lands on not-listed rather than throwing.
339
+ return users.includes(Number(destination))
340
+ ? { ok: true }
341
+ : { ok: false, reason: "not-listed" };
342
+ }
304
343
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Task 2776 — the named-carrier rule.
3
+ *
4
+ * The three refusal reasons are kept apart because they call for different
5
+ * operator actions, and because `readChannelAdmins().byBot` cannot tell them
6
+ * apart: it drops every non-admin entry, so a demoted bot and a missing one
7
+ * look identical there. Demoted is the measured case.
8
+ */
9
+ import { describe, it, expect, afterEach } from "vitest";
10
+ import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
11
+ import { tmpdir } from "node:os";
12
+ import { join } from "node:path";
13
+ import { carrierVerdict } from "../index.js";
14
+
15
+ const dirs: string[] = [];
16
+
17
+ function accountDir(bots?: unknown): string {
18
+ const dir = mkdtempSync(join(tmpdir(), "carrier-"));
19
+ dirs.push(dir);
20
+ if (bots !== undefined) {
21
+ writeFileSync(join(dir, "account.json"), JSON.stringify({ telegram: { bots } }));
22
+ }
23
+ return dir;
24
+ }
25
+
26
+ afterEach(() => {
27
+ while (dirs.length > 0) rmSync(dirs.pop() as string, { recursive: true, force: true });
28
+ });
29
+
30
+ const ADMIN = { id: "8711566959", role: "admin", adminUsers: [8992591236] };
31
+ const SPECIALIST = { id: "8804050655", role: "specialist", adminUsers: [1311221864] };
32
+
33
+ describe("carrierVerdict", () => {
34
+ it("accepts an admin bot that lists the destination", () => {
35
+ expect(carrierVerdict(accountDir([ADMIN]), "8711566959", "8992591236")).toEqual({ ok: true });
36
+ });
37
+
38
+ it("refuses reason=absent when no bot carries that id", () => {
39
+ expect(carrierVerdict(accountDir([ADMIN]), "1234567890", "8992591236")).toEqual({
40
+ ok: false,
41
+ reason: "absent",
42
+ });
43
+ });
44
+
45
+ it("refuses reason=not-admin when the bot exists on another role", () => {
46
+ // The measured case: a routine's carrier demoted to role:'specialist'
47
+ // elsewhere, which moved the carrier with no event and no refusal.
48
+ expect(carrierVerdict(accountDir([SPECIALIST]), "8804050655", "1311221864")).toEqual({
49
+ ok: false,
50
+ reason: "not-admin",
51
+ });
52
+ });
53
+
54
+ it("refuses reason=not-listed when an admin bot does not list the destination", () => {
55
+ expect(carrierVerdict(accountDir([ADMIN]), "8711566959", "1311221864")).toEqual({
56
+ ok: false,
57
+ reason: "not-listed",
58
+ });
59
+ });
60
+
61
+ it("refuses reason=absent on missing config (fail closed)", () => {
62
+ expect(carrierVerdict(accountDir(), "8711566959", "8992591236")).toEqual({
63
+ ok: false,
64
+ reason: "absent",
65
+ });
66
+ });
67
+
68
+ it("refuses reason=absent when the bots array is malformed", () => {
69
+ expect(carrierVerdict(accountDir("not-an-array"), "8711566959", "8992591236")).toEqual({
70
+ ok: false,
71
+ reason: "absent",
72
+ });
73
+ });
74
+
75
+ it("refuses reason=not-listed on a non-numeric destination", () => {
76
+ // Number("not-a-number") is NaN, which is in no list, so this lands on
77
+ // not-listed rather than throwing.
78
+ expect(carrierVerdict(accountDir([ADMIN]), "8711566959", "not-a-number")).toEqual({
79
+ ok: false,
80
+ reason: "not-listed",
81
+ });
82
+ });
83
+
84
+ it("picks the named bot out of several, not merely the first", () => {
85
+ const dir = accountDir([SPECIALIST, ADMIN]);
86
+ expect(carrierVerdict(dir, "8711566959", "8992591236")).toEqual({ ok: true });
87
+ expect(carrierVerdict(dir, "8804050655", "1311221864")).toEqual({
88
+ ok: false,
89
+ reason: "not-admin",
90
+ });
91
+ });
92
+ });
@@ -375,3 +375,62 @@ export function dispatchGapReason(fields: DispatchFields): string {
375
375
  }
376
376
  return "no-dispatch-configured";
377
377
  }
378
+
379
+ /**
380
+ * Task 2776 — why a named carrier bot may not carry a destination.
381
+ *
382
+ * Three reasons, kept apart because they call for different operator actions: a
383
+ * bot id that names nothing (`absent`), a bot that exists on another role
384
+ * (`not-admin`), and an admin bot that does not admit this chat (`not-listed`).
385
+ *
386
+ * `not-admin` is the measured case. A routine authored against one bot silently
387
+ * changed carrier when that bot's `role` changed elsewhere, and every report
388
+ * landed in that bot's conversation rather than the operator's, with no event
389
+ * and no refusal naming the switch.
390
+ */
391
+ export type CarrierReason = "absent" | "not-admin" | "not-listed";
392
+ export type CarrierVerdict = { ok: true } | { ok: false; reason: CarrierReason };
393
+
394
+ /**
395
+ * May `botId` carry `destination` for the account at `accountDir`?
396
+ *
397
+ * Reads the RAW `telegram.bots` array rather than `readChannelAdmins().byBot`,
398
+ * because that projection drops every entry whose role is not `admin` and so
399
+ * cannot tell a missing bot from a demoted one — the distinction the three
400
+ * reasons exist for. Fail-closed: unreadable or malformed config yields
401
+ * `absent`, matching the empty-list default `readChannelAdmins` already applies.
402
+ *
403
+ * The ONE authority for a named carrier. `validateAgentDispatch` calls it at
404
+ * write time and `schedule-inject` calls it at fire time, so the picker, the
405
+ * save and the dispatch cannot disagree — the guarantee Task 2368 states for
406
+ * the resolver path, extended to the named one.
407
+ */
408
+ export function carrierVerdict(
409
+ accountDir: string,
410
+ botId: string,
411
+ destination: string,
412
+ ): CarrierVerdict {
413
+ let config: { telegram?: { bots?: unknown } } = {};
414
+ try {
415
+ config = JSON.parse(readFileSync(resolve(accountDir, "account.json"), "utf-8")) as {
416
+ telegram?: { bots?: unknown };
417
+ };
418
+ } catch {
419
+ return { ok: false, reason: "absent" };
420
+ }
421
+ const bots = Array.isArray(config.telegram?.bots) ? config.telegram.bots : [];
422
+ const entry = bots.find(
423
+ (raw) => raw && typeof raw === "object" && (raw as { id?: unknown }).id === botId,
424
+ ) as { role?: unknown; adminUsers?: unknown } | undefined;
425
+ if (!entry) return { ok: false, reason: "absent" };
426
+ if (entry.role !== "admin") return { ok: false, reason: "not-admin" };
427
+ const users = Array.isArray(entry.adminUsers)
428
+ ? entry.adminUsers.filter((u): u is number => typeof u === "number")
429
+ : [];
430
+ // The destination is a string everywhere on the dispatch path; the stored list
431
+ // is numeric. A non-numeric destination yields NaN, which is in no list, so it
432
+ // lands on not-listed rather than throwing.
433
+ return users.includes(Number(destination))
434
+ ? { ok: true }
435
+ : { ok: false, reason: "not-listed" };
436
+ }
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: platform-architecture
3
3
  description: Use when grounding any documented-surface claim about what Real Agent ships — plugins, skills, specialists, install/deploy flows, internals. This is the install catalogue, not evidence of what is enabled on the current account. For install state on this account, call `capabilities-here`; for documented surface, cite the `Source:` URL inline.
4
- content-hash: sha256:5e127a3b4f988e5c2a96441ca87d017d72efde5c773223579f54ec14b4ea6fd6
4
+ content-hash: sha256:74072717ff2ef2238bb8ab02aa3d0a7b2682ce65f4a7edf39cebbbe0e7bb1a82
5
5
  brand: realagent-code
6
6
  product-name: Real Agent
7
7
  ---
@@ -2961,10 +2961,48 @@ Telegram profile name and will tell you plainly that it cannot put a name to the
2961
2961
  Ask Real Agent to save the Telegram ID against the contact. It is one change to one contact, and
2962
2962
  it takes effect on the very next message.
2963
2963
 
2964
- ## Correcting what a public agent told a visitor
2964
+ ## Which bot a routine sends from
2965
2965
 
2966
- When one of your public bots tells a visitor something wrong, the fix is to instruct the agent that
2967
- is talking to them, not to message the visitor yourself.
2966
+ A routine that reports to you on Telegram has to go out through one of your bots. If the routine does
2967
+ not say which, Real Agent picks whichever of your admin bots has your chat on its list at the
2968
+ moment the routine runs.
2969
+
2970
+ That is the right answer when you have one admin bot, which is the usual case. It goes wrong when you
2971
+ have several. If the bot that was carrying a routine is later changed to a specialist role, it stops
2972
+ counting as an admin bot, and the routine moves to a different one. Your reports keep being written
2973
+ and keep being delivered, but into a different conversation, and nothing announces the move.
2974
+
2975
+ So you can name the bot when you set the routine up. Tell Real Agent which bot a routine should
2976
+ report through and it stays on that bot until you change the routine yourself. Ask "which bot does
2977
+ this routine report through?" at any time and it will tell you.
2978
+
2979
+ If you name a bot that Real Agent cannot use, the routine does not run and you are told why,
2980
+ rather than being quietly moved to another bot. There are three reasons it can give: there is no such
2981
+ bot on your account, the bot exists but is no longer an admin bot, or the bot is an admin bot but
2982
+ your chat is not on its list. Each one points at a different fix.
2983
+
2984
+ ## Knowing whether a routine actually reported
2985
+
2986
+ A routine that wakes up and a routine that sends you something are two different things, and
2987
+ Real Agent now records them separately.
2988
+
2989
+ Waking up means the routine started and had its say. Whether it then sent you a message depends on
2990
+ what it found. A routine told to report only when something has changed is meant to stay quiet most
2991
+ of the time, and that silence is it working correctly.
2992
+
2993
+ Every message a routine sends you is recorded against the run that sent it, so a routine's history
2994
+ shows which runs reported and which did not. Ask "has this routine actually been messaging me?" and
2995
+ you will get the answer from that record rather than from the fact it has been running.
2996
+
2997
+ Real Agent also checks this on its own, once a sweep, per account: how many routine wakes were
2998
+ accepted, how many produced a message, and which routines account for the difference. A routine that
2999
+ has been waking without ever reporting shows up there, named, without you having to notice the
3000
+ absence of messages first.
3001
+
3002
+ ## Correcting what an agent told someone
3003
+
3004
+ When one of your bots tells someone something wrong, the fix is to instruct the agent that is talking
3005
+ to them, not to message that person yourself.
2968
3006
 
2969
3007
  The reason is worth understanding, because the obvious approach quietly fails. Every conversation is
2970
3008
  its own separate agent with its own memory. If you send the visitor a correction from your chat, they
@@ -2979,16 +3017,28 @@ own conversation. The agent writes the message itself, in the same voice it has
2979
3017
  own memory now holds what it said, so it will not contradict it a moment later. The visitor sees a
2980
3018
  normal message from the assistant they have been talking to, with no sign that anybody stepped in.
2981
3019
 
3020
+ The same is true of your specialist bots. If a specialist relays for a driver, a supplier or a
3021
+ colleague, and you card that person yourself, the specialist never learns you did. It answers their
3022
+ next message with no idea what they are replying to. That happened on a live conversation: a driver
3023
+ was sent a job by card, and when he came back twelve minutes later with his prices, the bot filed
3024
+ them as a passing remark and thanked him. Instruct it the same way, naming its bot and their chat,
3025
+ and it writes the message and remembers writing it.
3026
+
2982
3027
  Write the intent rather than the exact sentence. This is an instruction to the agent, not text
2983
3028
  delivered word for word, so "tell them we can do Thursday morning but not the afternoon" works better
2984
3029
  than a script.
2985
3030
 
2986
- Four situations are refused, and each one says why rather than failing quietly:
2987
-
2988
- - The bot is not a public bot. Your own admin bot and any specialist bot are conversations with your
2989
- own side, not with a visitor, so there is nothing to instruct.
2990
- - The agent has been switched off. Nothing is resurrected behind your back; turn it back on, or
2991
- message the person yourself.
3031
+ Six situations are refused, and each one says why rather than failing quietly:
3032
+
3033
+ - The bot is your own admin bot. That chat is your conversation with the agent, so instructing it
3034
+ there is the agent talking to itself.
3035
+ - The bot is bound to nothing. It answers nobody, so there is no agent to instruct.
3036
+ - The agent has been switched off, or a specialist's card has been renamed or deleted. Nothing is
3037
+ resurrected behind your back; turn it back on, or message the person yourself.
3038
+ - The bot is not allowed to talk to that person. Every bot has its own rule about who it answers, and
3039
+ a specialist answers a named list and nobody else. Starting a conversation the bot would refuse to
3040
+ continue leaves the person holding a message nobody can follow up, so it is refused instead. Most
3041
+ often this is a mistyped chat ID.
2992
3042
  - The chat belongs to a connected business account. Those conversations are held separately and this
2993
3043
  route cannot reach them.
2994
3044
  - The chat is a broadcast channel the bot does not allow. A channel post reaches every subscriber and
@@ -3152,6 +3202,13 @@ your conversation view shows the button's own wording — "1 passenger", "One wa
3152
3202
  chat appears in that chat's conversation, where the person who received it is,
3153
3203
  and not in the conversation you asked for it from.
3154
3204
 
3205
+ Every card is recorded, whoever sent it. When Real Agent hands a job to one
3206
+ of your specialists and that specialist cards someone, the card now shows up in
3207
+ that person's conversation exactly as one you asked for yourself would. Before,
3208
+ it did not: the card reached Telegram, the person read it, and your side held no
3209
+ record of it at all, so asking Real Agent what it had sent got an answer
3210
+ drawn from Telegram rather than from your own history.
3211
+
3155
3212
  The same is now true of most of what Telegram sends. Reply to one of
3156
3213
  Real Agent's messages and it sees the message you replied to, so "yes, do
3157
3214
  that one" means something. React to a message with an emoji and it hears the
@@ -9,6 +9,17 @@ Invoked by the admin agent directly.
9
9
 
10
10
  This is the platform's release timeline, newest first. Each entry shows the date it shipped and the version it shipped in, so you can tell the operator how current their install is. To compare, read the installed version from `capabilities-here` and match it against the versions below. Keep answers high level and in plain English; this is a summary, not a full commit log.
11
11
 
12
+ ## 2026-08-16 (0.1.614)
13
+
14
+ - A routine that woke the assistant is no longer counted as having reached you. A wake is now recorded as a wake, and a run records the message that actually arrived in the chat, checked against what was really sent.
15
+ - A Telegram routine can name the bot that carries it. A named bot is used exactly as given, or refused with the reason.
16
+ - A card sent by a specialist is recorded in the conversation. It reached Telegram and was written down nowhere.
17
+
18
+ ## 2026-08-16 (0.1.613)
19
+
20
+ - You can now tell the assistant what to say to someone one of your specialist bots is handling, the same way you already could for a public bot. Until now that was refused, so the only way through was to message the person yourself, and the specialist never learned you had. It would answer their next message with no idea what they were replying to.
21
+ - A bot will no longer start a conversation with someone it is set up never to answer. A mistyped chat ID used to send one message and then go silent, because every reply came back to a bot that refused it.
22
+
12
23
  ## 2026-08-15 (0.1.612)
13
24
 
14
25
  - A conversation opened from the dashboard could show as completely empty even though the agent had answered in it. The reader was discarding the agent's replies instead of drawing them, so the thread looked like nothing had ever been said. Those replies now appear.
@@ -138,10 +138,48 @@ Telegram profile name and will tell you plainly that it cannot put a name to the
138
138
  Ask {{productName}} to save the Telegram ID against the contact. It is one change to one contact, and
139
139
  it takes effect on the very next message.
140
140
 
141
- ## Correcting what a public agent told a visitor
141
+ ## Which bot a routine sends from
142
142
 
143
- When one of your public bots tells a visitor something wrong, the fix is to instruct the agent that
144
- is talking to them, not to message the visitor yourself.
143
+ A routine that reports to you on Telegram has to go out through one of your bots. If the routine does
144
+ not say which, {{productName}} picks whichever of your admin bots has your chat on its list at the
145
+ moment the routine runs.
146
+
147
+ That is the right answer when you have one admin bot, which is the usual case. It goes wrong when you
148
+ have several. If the bot that was carrying a routine is later changed to a specialist role, it stops
149
+ counting as an admin bot, and the routine moves to a different one. Your reports keep being written
150
+ and keep being delivered, but into a different conversation, and nothing announces the move.
151
+
152
+ So you can name the bot when you set the routine up. Tell {{productName}} which bot a routine should
153
+ report through and it stays on that bot until you change the routine yourself. Ask "which bot does
154
+ this routine report through?" at any time and it will tell you.
155
+
156
+ If you name a bot that {{productName}} cannot use, the routine does not run and you are told why,
157
+ rather than being quietly moved to another bot. There are three reasons it can give: there is no such
158
+ bot on your account, the bot exists but is no longer an admin bot, or the bot is an admin bot but
159
+ your chat is not on its list. Each one points at a different fix.
160
+
161
+ ## Knowing whether a routine actually reported
162
+
163
+ A routine that wakes up and a routine that sends you something are two different things, and
164
+ {{productName}} now records them separately.
165
+
166
+ Waking up means the routine started and had its say. Whether it then sent you a message depends on
167
+ what it found. A routine told to report only when something has changed is meant to stay quiet most
168
+ of the time, and that silence is it working correctly.
169
+
170
+ Every message a routine sends you is recorded against the run that sent it, so a routine's history
171
+ shows which runs reported and which did not. Ask "has this routine actually been messaging me?" and
172
+ you will get the answer from that record rather than from the fact it has been running.
173
+
174
+ {{productName}} also checks this on its own, once a sweep, per account: how many routine wakes were
175
+ accepted, how many produced a message, and which routines account for the difference. A routine that
176
+ has been waking without ever reporting shows up there, named, without you having to notice the
177
+ absence of messages first.
178
+
179
+ ## Correcting what an agent told someone
180
+
181
+ When one of your bots tells someone something wrong, the fix is to instruct the agent that is talking
182
+ to them, not to message that person yourself.
145
183
 
146
184
  The reason is worth understanding, because the obvious approach quietly fails. Every conversation is
147
185
  its own separate agent with its own memory. If you send the visitor a correction from your chat, they
@@ -156,16 +194,28 @@ own conversation. The agent writes the message itself, in the same voice it has
156
194
  own memory now holds what it said, so it will not contradict it a moment later. The visitor sees a
157
195
  normal message from the assistant they have been talking to, with no sign that anybody stepped in.
158
196
 
197
+ The same is true of your specialist bots. If a specialist relays for a driver, a supplier or a
198
+ colleague, and you card that person yourself, the specialist never learns you did. It answers their
199
+ next message with no idea what they are replying to. That happened on a live conversation: a driver
200
+ was sent a job by card, and when he came back twelve minutes later with his prices, the bot filed
201
+ them as a passing remark and thanked him. Instruct it the same way, naming its bot and their chat,
202
+ and it writes the message and remembers writing it.
203
+
159
204
  Write the intent rather than the exact sentence. This is an instruction to the agent, not text
160
205
  delivered word for word, so "tell them we can do Thursday morning but not the afternoon" works better
161
206
  than a script.
162
207
 
163
- Four situations are refused, and each one says why rather than failing quietly:
164
-
165
- - The bot is not a public bot. Your own admin bot and any specialist bot are conversations with your
166
- own side, not with a visitor, so there is nothing to instruct.
167
- - The agent has been switched off. Nothing is resurrected behind your back; turn it back on, or
168
- message the person yourself.
208
+ Six situations are refused, and each one says why rather than failing quietly:
209
+
210
+ - The bot is your own admin bot. That chat is your conversation with the agent, so instructing it
211
+ there is the agent talking to itself.
212
+ - The bot is bound to nothing. It answers nobody, so there is no agent to instruct.
213
+ - The agent has been switched off, or a specialist's card has been renamed or deleted. Nothing is
214
+ resurrected behind your back; turn it back on, or message the person yourself.
215
+ - The bot is not allowed to talk to that person. Every bot has its own rule about who it answers, and
216
+ a specialist answers a named list and nobody else. Starting a conversation the bot would refuse to
217
+ continue leaves the person holding a message nobody can follow up, so it is refused instead. Most
218
+ often this is a mistyped chat ID.
169
219
  - The chat belongs to a connected business account. Those conversations are held separately and this
170
220
  route cannot reach them.
171
221
  - The chat is a broadcast channel the bot does not allow. A channel post reaches every subscriber and
@@ -329,6 +379,13 @@ your conversation view shows the button's own wording — "1 passenger", "One wa
329
379
  chat appears in that chat's conversation, where the person who received it is,
330
380
  and not in the conversation you asked for it from.
331
381
 
382
+ Every card is recorded, whoever sent it. When {{productName}} hands a job to one
383
+ of your specialists and that specialist cards someone, the card now shows up in
384
+ that person's conversation exactly as one you asked for yourself would. Before,
385
+ it did not: the card reached Telegram, the person read it, and your side held no
386
+ record of it at all, so asking {{productName}} what it had sent got an answer
387
+ drawn from Telegram rather than from your own history.
388
+
332
389
  The same is now true of most of what Telegram sends. Reply to one of
333
390
  {{productName}}'s messages and it sees the message you replied to, so "yes, do
334
391
  that one" means something. React to a message with an emoji and it hears the
@@ -102,6 +102,7 @@ eagerTool(server, "schedule-event", "Create a scheduled event or appointment. A
102
102
  channel: z.enum(["whatsapp", "telegram"]).describe("Native channel the agent turn is delivered over"),
103
103
  destination: z.string().describe("E.164 phone (WhatsApp) or Telegram chat id — must already be a registered admin/account-manager on that channel"),
104
104
  prompt: z.string().describe("The instruction the agent runs when the event fires"),
105
+ botId: z.string().optional().describe("Telegram only — the bot that carries this routine. Omit to let the fire-time resolver pick whichever admin bot lists the chat id, which is correct for a single-admin-bot account. Name one to pin the carrier, so the routine cannot silently change bot when another bot's role changes."),
105
106
  }).optional().describe("Agent-bearing dispatch: when the event fires, spawns or resumes the admin channel session for `destination` and runs `prompt` with full admin tools, delivering the answer back over the channel. Mutually exclusive with `action`. Always records an event, never a meeting."),
106
107
  gate: z.object(gateShape).optional().describe(GATE_DESCRIPTION),
107
108
  gateWaived: z.string().optional().describe(GATE_WAIVED_DESCRIPTION),
@@ -351,6 +352,7 @@ eagerTool(server, "schedule-update", "Update an event's properties or append a n
351
352
  channel: z.enum(["whatsapp", "telegram"]).describe("Native channel the agent turn is delivered over"),
352
353
  destination: z.string().describe("E.164 phone (WhatsApp) or Telegram chat id — must already be a registered admin/account-manager on that channel"),
353
354
  prompt: z.string().describe("The instruction the agent runs when the event fires"),
355
+ botId: z.string().optional().describe("Telegram only — the bot that carries this routine. Omit to let the fire-time resolver pick whichever admin bot lists the chat id, which is correct for a single-admin-bot account. Name one to pin the carrier, so the routine cannot silently change bot when another bot's role changes."),
354
356
  }).nullable().optional().describe("Set/replace the agent-bearing dispatch, or pass null to clear it. Mutually exclusive with action."),
355
357
  gate: z.object(gateShape).nullable().optional().describe(`${GATE_DESCRIPTION} Pass null to clear it.`),
356
358
  }, async (params) => {