@rubytech/create-realagent-code 0.1.606 → 0.1.608
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.js +40 -1
- package/package.json +1 -1
- package/payload/platform/lib/admins-write/vitest.config.ts +1 -0
- package/payload/platform/lib/agent-dispatch-rule/vitest.config.ts +1 -0
- package/payload/platform/lib/brand-templating/vitest.config.ts +1 -0
- package/payload/platform/lib/canonical-instant/vitest.config.ts +1 -0
- package/payload/platform/lib/dispatch-read/vitest.config.ts +1 -0
- package/payload/platform/lib/graph-search/vitest.config.ts +1 -0
- package/payload/platform/lib/graph-style/vitest.config.ts +1 -0
- package/payload/platform/lib/mcp-lifeline/vitest.config.ts +1 -0
- package/payload/platform/lib/routine-templates/vitest.config.ts +1 -0
- package/payload/platform/lib/task-secrets/vitest.config.ts +1 -0
- package/payload/platform/lib/telegram-button-labels/vitest.config.ts +1 -0
- package/payload/platform/lib/telegram-managed-bot/vitest.config.ts +1 -0
- package/payload/platform/lib/telegram-media/vitest.config.ts +1 -0
- package/payload/platform/lib/telegram-reach/vitest.config.ts +1 -0
- package/payload/platform/lib/telegram-store-read/vitest.config.ts +1 -0
- package/payload/platform/plugins/admin/mcp/vitest.config.ts +1 -0
- package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +39 -2
- package/payload/platform/plugins/admin/skills/whats-new/SKILL.md +10 -0
- package/payload/platform/plugins/aeo/mcp/vitest.config.ts +1 -0
- package/payload/platform/plugins/cloudflare/mcp/vitest.config.ts +1 -0
- package/payload/platform/plugins/connector/mcp/vitest.config.ts +1 -0
- package/payload/platform/plugins/contacts/mcp/vitest.config.ts +1 -0
- package/payload/platform/plugins/docs/references/telegram-guide.md +38 -1
- package/payload/platform/plugins/email/mcp/vitest.config.ts +1 -0
- package/payload/platform/plugins/filesystem/mcp/vitest.config.ts +1 -0
- package/payload/platform/plugins/graph-viewer/mcp/vitest.config.ts +1 -0
- package/payload/platform/plugins/memory/mcp/vitest.config.ts +1 -0
- package/payload/platform/plugins/scheduling/mcp/vitest.config.ts +1 -0
- package/payload/platform/plugins/storage-broker/mcp/vitest.config.ts +6 -1
- package/payload/platform/plugins/url-get/mcp/vitest.config.ts +1 -0
- package/payload/platform/plugins/whatsapp/mcp/vitest.config.ts +1 -0
- package/payload/platform/scripts/repair-misfiled-card-rows.sh +276 -0
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js +1 -0
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js.map +1 -1
- package/payload/platform/services/claude-session-manager/vitest.config.ts +1 -1
- package/payload/platform/services/telegram-channel/dist/instructions.d.ts +1 -0
- package/payload/platform/services/telegram-channel/dist/instructions.d.ts.map +1 -1
- package/payload/platform/services/telegram-channel/dist/instructions.js +23 -0
- package/payload/platform/services/telegram-channel/dist/instructions.js.map +1 -1
- package/payload/platform/services/telegram-channel/dist/notification.d.ts +22 -7
- package/payload/platform/services/telegram-channel/dist/notification.d.ts.map +1 -1
- package/payload/platform/services/telegram-channel/dist/notification.js +17 -1
- package/payload/platform/services/telegram-channel/dist/notification.js.map +1 -1
- package/payload/platform/test/tmpdir-setup.ts +54 -0
- package/payload/server/public/operator.html +1 -1
- package/payload/server/server.js +1488 -1091
package/dist/index.js
CHANGED
|
@@ -3,7 +3,7 @@ import { execFileSync, spawn, spawnSync } from "node:child_process";
|
|
|
3
3
|
import { existsSync, mkdirSync, writeFileSync, cpSync, readFileSync, rmSync, readdirSync, appendFileSync, openSync, closeSync, chmodSync, statSync, realpathSync, accessSync, constants as fsConstants } from "node:fs";
|
|
4
4
|
import { clearBrandAgentRoot } from "./brand-agent-root.js";
|
|
5
5
|
import { seedBypassPermissionsSettings, assertBypassPermissionsSeed } from "./permissions-seed.js";
|
|
6
|
-
import { resolve, join, dirname } from "node:path";
|
|
6
|
+
import { resolve, join, dirname, basename } from "node:path";
|
|
7
7
|
import { randomBytes } from "node:crypto";
|
|
8
8
|
import { resolveInstallPortFromFs, buildMaxyUnitFile, buildClaudeSessionManagerUnitFile, buildEmailSamplerUnitFile, buildClaudePtysSliceUnitFile, buildCloudflaredSliceUnitFile, buildDarwinServiceEnvPath } from "./port-resolution.js";
|
|
9
9
|
import { buildBrandCronBlock, mergeBrandCronBlock } from "./cron-registration.js";
|
|
@@ -570,6 +570,7 @@ function ensureNonSnapChromium() {
|
|
|
570
570
|
}
|
|
571
571
|
RESOLVED_CHROMIUM_BIN = decision.resolvedPath;
|
|
572
572
|
}
|
|
573
|
+
RESOLVED_CHROMIUM_BIN = preferUnwrappedChromium(RESOLVED_CHROMIUM_BIN);
|
|
573
574
|
// Defensive: never persist a snap-confined path. If realpath of the resolved
|
|
574
575
|
// binary still lands under /snap/ (e.g. apt landed a snap package by mistake
|
|
575
576
|
// on a misconfigured device), throw before writeChromiumBinaryPathFile sees
|
|
@@ -622,6 +623,44 @@ function runChromiumPostInstallGate(chromiumBin) {
|
|
|
622
623
|
console.log(" Chromium post-install gate passed.");
|
|
623
624
|
logFile(` [snap-chromium] post-install gate ok: ${chromiumBin} exit=0`);
|
|
624
625
|
}
|
|
626
|
+
/**
|
|
627
|
+
* Prefer the real Chromium ELF binary over a distro shell wrapper.
|
|
628
|
+
*
|
|
629
|
+
* Debian and Raspberry Pi OS ship `/usr/bin/chromium` as a POSIX shell script
|
|
630
|
+
* that appends its own flags and then `exec $LIBDIR/$APPNAME "$@"`, where
|
|
631
|
+
* `LIBDIR=/usr/lib/$APPNAME` — so the real binary is derivable from the
|
|
632
|
+
* wrapper's own layout rather than guessed.
|
|
633
|
+
*
|
|
634
|
+
* On aarch64 with a page size above 4096 that wrapper adds
|
|
635
|
+
* `--js-flags=--no-decommit-pooled-pages` (its workaround for Debian #1089647).
|
|
636
|
+
* Current Chromium's V8 has removed that flag, so V8 exits "unrecognized flag",
|
|
637
|
+
* the GPU process dies with it, and the installer's CDP check then correctly
|
|
638
|
+
* finds nothing listening and aborts the upgrade. Measured on the beacons Pi
|
|
639
|
+
* 2026-08-14: Chromium 148.0.7778.167, `getconf PAGESIZE` 16384, and
|
|
640
|
+
* `chromium --js-flags=--no-decommit-pooled-pages` reproduces it directly.
|
|
641
|
+
*
|
|
642
|
+
* Execing the binary skips the wrapper and every flag it would inject. The
|
|
643
|
+
* wrapper is returned unchanged whenever the shape does not match — not a
|
|
644
|
+
* script, no binary at the derived path, or that path is not ELF — so a distro
|
|
645
|
+
* laying Chromium out differently is untouched.
|
|
646
|
+
*/
|
|
647
|
+
function preferUnwrappedChromium(binPath) {
|
|
648
|
+
const fileType = (p) => {
|
|
649
|
+
const r = spawnSync("file", ["-b", p], { encoding: "utf-8", stdio: "pipe", timeout: 5_000 });
|
|
650
|
+
return r.status === 0 ? (r.stdout ?? "").trim() : "";
|
|
651
|
+
};
|
|
652
|
+
if (!/shell script/i.test(fileType(binPath)))
|
|
653
|
+
return binPath;
|
|
654
|
+
const appName = basename(binPath);
|
|
655
|
+
const real = `/usr/lib/${appName}/${appName}`;
|
|
656
|
+
if (!existsSync(real) || !/^ELF/.test(fileType(real))) {
|
|
657
|
+
logFile(` [chromium-wrapper] ${binPath} is a wrapper but ${real} is not a usable binary — keeping the wrapper`);
|
|
658
|
+
return binPath;
|
|
659
|
+
}
|
|
660
|
+
console.log(` Chromium wrapper bypassed: ${binPath} → ${real}`);
|
|
661
|
+
logFile(` [chromium-wrapper] bypassed wrapper=${binPath} binary=${real}`);
|
|
662
|
+
return real;
|
|
663
|
+
}
|
|
625
664
|
/**
|
|
626
665
|
* write the resolved Chromium absolute path to
|
|
627
666
|
* `<INSTALL_DIR>/platform/config/chromium-binary.path` so vnc.sh and
|
package/package.json
CHANGED
|
@@ -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:
|
|
4
|
+
content-hash: sha256:91d181f269c43daa00e505bc526da955baa0aa8df0a096c7c4e23c31afb58200
|
|
5
5
|
brand: realagent-code
|
|
6
6
|
product-name: Real Agent
|
|
7
7
|
---
|
|
@@ -2961,6 +2961,41 @@ 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
|
|
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.
|
|
2968
|
+
|
|
2969
|
+
The reason is worth understanding, because the obvious approach quietly fails. Every conversation is
|
|
2970
|
+
its own separate agent with its own memory. If you send the visitor a correction from your chat, they
|
|
2971
|
+
receive it, but the agent that has been talking to them never sees it: it is a different
|
|
2972
|
+
conversation, and nothing carries a message from yours into theirs. It carries on from what it
|
|
2973
|
+
believes, and repeats the mistake on the next question. That is exactly what happened on a live
|
|
2974
|
+
conversation where a corrected price was quoted wrong again ninety-seven seconds later.
|
|
2975
|
+
|
|
2976
|
+
So tell Real Agent what the visitor should be told, and name the bot and the chat: "Tell the
|
|
2977
|
+
visitor on chat 1234567890 that the price is 75, not 65." The instruction goes into that visitor's
|
|
2978
|
+
own conversation. The agent writes the message itself, in the same voice it has been using, and its
|
|
2979
|
+
own memory now holds what it said, so it will not contradict it a moment later. The visitor sees a
|
|
2980
|
+
normal message from the assistant they have been talking to, with no sign that anybody stepped in.
|
|
2981
|
+
|
|
2982
|
+
Write the intent rather than the exact sentence. This is an instruction to the agent, not text
|
|
2983
|
+
delivered word for word, so "tell them we can do Thursday morning but not the afternoon" works better
|
|
2984
|
+
than a script.
|
|
2985
|
+
|
|
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.
|
|
2992
|
+
- The chat belongs to a connected business account. Those conversations are held separately and this
|
|
2993
|
+
route cannot reach them.
|
|
2994
|
+
- The chat is a broadcast channel the bot does not allow. A channel post reaches every subscriber and
|
|
2995
|
+
cannot be unsent.
|
|
2996
|
+
|
|
2997
|
+
If you need the chat ID, ask "who can you reach on Telegram?" first.
|
|
2998
|
+
|
|
2964
2999
|
## Getting a Chat ID
|
|
2965
3000
|
|
|
2966
3001
|
To message a specific person or group, Real Agent needs their chat ID. The easiest way:
|
|
@@ -3047,7 +3082,9 @@ it puts the answer in the card itself and does not add a sentence beside it. On
|
|
|
3047
3082
|
public bot, that following sentence is held back on purpose, so the visitor sees
|
|
3048
3083
|
the card once and not the same thing twice. And when someone presses a button,
|
|
3049
3084
|
your conversation view shows the button's own wording — "1 passenger", "One way"
|
|
3050
|
-
— rather than the code behind it.
|
|
3085
|
+
— rather than the code behind it. A card Real Agent sends into a different
|
|
3086
|
+
chat appears in that chat's conversation, where the person who received it is,
|
|
3087
|
+
and not in the conversation you asked for it from.
|
|
3051
3088
|
|
|
3052
3089
|
The same is now true of most of what Telegram sends. Reply to one of
|
|
3053
3090
|
Real Agent's messages and it sees the message you replied to, so "yes, do
|
|
@@ -9,6 +9,16 @@ 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-15 (0.1.608)
|
|
13
|
+
|
|
14
|
+
- You can now steer a public agent while it is mid-conversation with someone, rather than waiting for the exchange to end.
|
|
15
|
+
- A card sent into a different chat is filed in that chat, not in the conversation of whoever sent it.
|
|
16
|
+
- Routines already running on your installs now use the work-check gates added over the past week. They kept their old always-run behaviour until this backfill, and routines left behind with nothing to run are removed.
|
|
17
|
+
|
|
18
|
+
## 2026-08-14 (0.1.607)
|
|
19
|
+
|
|
20
|
+
- Upgrades no longer fail on a Raspberry Pi with a 16K page size. The system's own Chromium launcher adds a setting that current Chromium has removed, so the browser exited on startup and the install stopped when it could not reach it. The installer now runs Chromium directly, skipping that launcher.
|
|
21
|
+
|
|
12
22
|
## 2026-08-14 (0.1.606)
|
|
13
23
|
|
|
14
24
|
- Conversations start after an install again. The installer marked only your home folder as trusted, and the assistant now asks about the folder each account actually runs from, so a session would stop at a trust prompt nobody could answer.
|
|
@@ -2,6 +2,7 @@ import { defineConfig } from "vitest/config";
|
|
|
2
2
|
|
|
3
3
|
export default defineConfig({
|
|
4
4
|
test: {
|
|
5
|
+
setupFiles: ["../../../test/tmpdir-setup.ts"],
|
|
5
6
|
environment: "node",
|
|
6
7
|
include: ["__tests__/**/*.test.ts"],
|
|
7
8
|
exclude: process.env.RUN_LIVE === "1" ? [] : ["__tests__/live/**"],
|
|
@@ -2,6 +2,7 @@ import { defineConfig } from "vitest/config";
|
|
|
2
2
|
|
|
3
3
|
export default defineConfig({
|
|
4
4
|
test: {
|
|
5
|
+
setupFiles: ["../../../test/tmpdir-setup.ts"],
|
|
5
6
|
environment: "node",
|
|
6
7
|
// Scoped to src, matching plugins/telegram/mcp: without it vitest also
|
|
7
8
|
// collects dist/__tests__/*.test.js, which `tsc -p` emits because this
|
|
@@ -138,6 +138,41 @@ 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
|
|
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.
|
|
145
|
+
|
|
146
|
+
The reason is worth understanding, because the obvious approach quietly fails. Every conversation is
|
|
147
|
+
its own separate agent with its own memory. If you send the visitor a correction from your chat, they
|
|
148
|
+
receive it, but the agent that has been talking to them never sees it: it is a different
|
|
149
|
+
conversation, and nothing carries a message from yours into theirs. It carries on from what it
|
|
150
|
+
believes, and repeats the mistake on the next question. That is exactly what happened on a live
|
|
151
|
+
conversation where a corrected price was quoted wrong again ninety-seven seconds later.
|
|
152
|
+
|
|
153
|
+
So tell {{productName}} what the visitor should be told, and name the bot and the chat: "Tell the
|
|
154
|
+
visitor on chat 1234567890 that the price is 75, not 65." The instruction goes into that visitor's
|
|
155
|
+
own conversation. The agent writes the message itself, in the same voice it has been using, and its
|
|
156
|
+
own memory now holds what it said, so it will not contradict it a moment later. The visitor sees a
|
|
157
|
+
normal message from the assistant they have been talking to, with no sign that anybody stepped in.
|
|
158
|
+
|
|
159
|
+
Write the intent rather than the exact sentence. This is an instruction to the agent, not text
|
|
160
|
+
delivered word for word, so "tell them we can do Thursday morning but not the afternoon" works better
|
|
161
|
+
than a script.
|
|
162
|
+
|
|
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.
|
|
169
|
+
- The chat belongs to a connected business account. Those conversations are held separately and this
|
|
170
|
+
route cannot reach them.
|
|
171
|
+
- The chat is a broadcast channel the bot does not allow. A channel post reaches every subscriber and
|
|
172
|
+
cannot be unsent.
|
|
173
|
+
|
|
174
|
+
If you need the chat ID, ask "who can you reach on Telegram?" first.
|
|
175
|
+
|
|
141
176
|
## Getting a Chat ID
|
|
142
177
|
|
|
143
178
|
To message a specific person or group, {{productName}} needs their chat ID. The easiest way:
|
|
@@ -224,7 +259,9 @@ it puts the answer in the card itself and does not add a sentence beside it. On
|
|
|
224
259
|
public bot, that following sentence is held back on purpose, so the visitor sees
|
|
225
260
|
the card once and not the same thing twice. And when someone presses a button,
|
|
226
261
|
your conversation view shows the button's own wording — "1 passenger", "One way"
|
|
227
|
-
— rather than the code behind it.
|
|
262
|
+
— rather than the code behind it. A card {{productName}} sends into a different
|
|
263
|
+
chat appears in that chat's conversation, where the person who received it is,
|
|
264
|
+
and not in the conversation you asked for it from.
|
|
228
265
|
|
|
229
266
|
The same is now true of most of what Telegram sends. Reply to one of
|
|
230
267
|
{{productName}}'s messages and it sees the message you replied to, so "yes, do
|
|
@@ -2,6 +2,7 @@ import { defineConfig } from "vitest/config";
|
|
|
2
2
|
|
|
3
3
|
export default defineConfig({
|
|
4
4
|
test: {
|
|
5
|
+
setupFiles: ["../../../test/tmpdir-setup.ts"],
|
|
5
6
|
environment: "node",
|
|
6
7
|
// narrow to `src/tools/__tests__/` so vitest does not pick up
|
|
7
8
|
// pre-existing `src/lib/__tests__/` files that use Node's built-in
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import { defineConfig } from "vitest/config";
|
|
2
2
|
export default defineConfig({
|
|
3
|
-
test: {
|
|
3
|
+
test: {
|
|
4
|
+
setupFiles: ["../../../test/tmpdir-setup.ts"],
|
|
5
|
+
environment: "node",
|
|
6
|
+
include: ["src/**/__tests__/**/*.test.ts"],
|
|
7
|
+
testTimeout: 10_000,
|
|
8
|
+
},
|
|
4
9
|
});
|
|
@@ -7,6 +7,7 @@ import { defineConfig } from "vitest/config";
|
|
|
7
7
|
// and this flag becomes a no-op.
|
|
8
8
|
export default defineConfig({
|
|
9
9
|
test: {
|
|
10
|
+
setupFiles: ["../../../test/tmpdir-setup.ts"],
|
|
10
11
|
environment: "node",
|
|
11
12
|
include: ["src/**/__tests__/**/*.test.ts"],
|
|
12
13
|
passWithNoTests: true,
|