@rubytech/create-maxy-code 0.1.434 → 0.1.435

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 (35) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/lib/embed-client/dist/index.d.ts +1 -1
  3. package/payload/platform/lib/embed-client/dist/index.d.ts.map +1 -1
  4. package/payload/platform/lib/embed-client/dist/index.js +73 -25
  5. package/payload/platform/lib/embed-client/dist/index.js.map +1 -1
  6. package/payload/platform/lib/embed-client/src/index.ts +77 -25
  7. package/payload/platform/plugins/admin/PLUGIN.md +1 -0
  8. package/payload/platform/plugins/admin/hooks/__tests__/askuserquestion-channel-carrier-gate.test.sh +175 -0
  9. package/payload/platform/plugins/admin/hooks/askuserquestion-channel-carrier-gate.sh +137 -0
  10. package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +2 -2
  11. package/payload/platform/plugins/docs/references/internals.md +1 -1
  12. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/embed-throughput.test.js +161 -19
  13. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/embed-throughput.test.js.map +1 -1
  14. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/embed-timeout.test.js +11 -9
  15. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/embed-timeout.test.js.map +1 -1
  16. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/embeddings-cap.test.js +9 -5
  17. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/embeddings-cap.test.js.map +1 -1
  18. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-update-own-preference-selfheal.test.d.ts +2 -0
  19. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-update-own-preference-selfheal.test.d.ts.map +1 -0
  20. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-update-own-preference-selfheal.test.js +113 -0
  21. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-update-own-preference-selfheal.test.js.map +1 -0
  22. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-update-reconcile.test.js +6 -0
  23. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-update-reconcile.test.js.map +1 -1
  24. package/payload/platform/plugins/memory/mcp/dist/tools/profile-update.js +47 -4
  25. package/payload/platform/plugins/memory/mcp/dist/tools/profile-update.js.map +1 -1
  26. package/payload/platform/scripts/lib/provision-account-dir.sh +2 -1
  27. package/payload/platform/services/claude-session-manager/dist/index.js +20 -0
  28. package/payload/platform/services/claude-session-manager/dist/index.js.map +1 -1
  29. package/payload/platform/services/claude-session-manager/dist/interactive-wedge.d.ts +42 -0
  30. package/payload/platform/services/claude-session-manager/dist/interactive-wedge.d.ts.map +1 -0
  31. package/payload/platform/services/claude-session-manager/dist/interactive-wedge.js +149 -0
  32. package/payload/platform/services/claude-session-manager/dist/interactive-wedge.js.map +1 -0
  33. package/payload/server/{chunk-UUG6ZSO5.js → chunk-DAYMXQG2.js} +28 -0
  34. package/payload/server/maxy-edge.js +1 -1
  35. package/payload/server/server.js +6 -5
@@ -0,0 +1,137 @@
1
+ #!/usr/bin/env bash
2
+ # AskUserQuestion native-channel carrier gate.
3
+ #
4
+ # Blocks `AskUserQuestion` when the session has a native channel attached. The
5
+ # Claude Code channel protocol carries exactly two interactive methods
6
+ # (permission_request / permission); there is NO carrier for the AskUserQuestion
7
+ # elicitation. On a native-channel (rc-spawn) webchat/WhatsApp/Telegram session
8
+ # the harness blocks the turn awaiting a selection that can never arrive: the
9
+ # reader renders only delivered replies, never an elicitation card, so the turn
10
+ # wedges — the operator sees the last delivered reply and a live-looking but
11
+ # dead composer (see .tasks/1552, live SiteDesk incident session 1a085718
12
+ # 2026-07-11). This hook removes that wedge deterministically by steering the
13
+ # agent to ask the same question as prose via its channel reply tool, which
14
+ # rides the ordinary delivered-reply path that works on every surface.
15
+ #
16
+ # This is a SEPARATE concern from askuserquestion-investigate-gate.sh (which
17
+ # blocks a fabricated menu raised before any investigation). Both are registered
18
+ # as commands on the same PreToolUse AskUserQuestion matcher; either exit 2
19
+ # blocks. This hook guards the "surface can't render this" condition; the other
20
+ # guards the "no evidence yet" condition.
21
+ #
22
+ # Signal: the rc-spawn writes the channel MCP registration as a config file in
23
+ # os.tmpdir() keyed by session id (channel-mcp.ts / webchat-channel-mcp.ts /
24
+ # wa-channel-mcp.ts / telegram-channel-mcp.ts). Its presence at tool-call time
25
+ # is the authoritative "channel attached to this session" marker: a Pi channel
26
+ # process sees the file (block); a claude.ai/code process on another host never
27
+ # sees the Pi tmpfile (fail-open, allow — that surface can answer the card).
28
+ #
29
+ # Contract:
30
+ # Input: PreToolUse stdin JSON envelope from Claude Code
31
+ # Output: exit 0 (allow) or exit 2 (block) per hook protocol
32
+ # Logs: one stderr line per decisive call, format
33
+ # [ask-channel] decision=<allow|block> sessionId=<id8>
34
+ # channel=<attached|none>
35
+ # reason=<channel-attached|no-channel|fail-open-no-envelope|fail-open-no-session>
36
+ #
37
+ # Fail-open philosophy: any missing/blank marker (no channel file, no session
38
+ # id, no envelope) nudges the agent through, never bricks the UI. Block is
39
+ # reserved for the deterministic case "AskUserQuestion fired while a channel
40
+ # config file for this session exists in tmpdir".
41
+
42
+ set -uo pipefail
43
+
44
+ # ----- Read stdin, identify event ------------------------------------------
45
+ if [ -t 0 ]; then
46
+ # No envelope — cannot enforce. Fail open per nudge-not-brick rule.
47
+ echo "[ask-channel] decision=allow sessionId=- channel=none reason=fail-open-no-envelope" >&2
48
+ exit 0
49
+ fi
50
+ INPUT=$(cat)
51
+
52
+ if [ -z "$INPUT" ]; then
53
+ echo "[ask-channel] decision=allow sessionId=- channel=none reason=fail-open-no-envelope" >&2
54
+ exit 0
55
+ fi
56
+
57
+ HOOK_EVENT=$(printf '%s' "$INPUT" | python3 -c '
58
+ import sys, json
59
+ try:
60
+ d = json.load(sys.stdin)
61
+ print(d.get("hook_event_name", "") or "")
62
+ except Exception:
63
+ print("")
64
+ ' 2>/dev/null)
65
+
66
+ TOOL_NAME=$(printf '%s' "$INPUT" | python3 -c '
67
+ import sys, json
68
+ try:
69
+ d = json.load(sys.stdin)
70
+ print(d.get("tool_name", "") or "")
71
+ except Exception:
72
+ print("")
73
+ ' 2>/dev/null)
74
+
75
+ # Only applies to PreToolUse on AskUserQuestion. Anything else: silent exit.
76
+ if [ "$HOOK_EVENT" != "PreToolUse" ] || [ "$TOOL_NAME" != "AskUserQuestion" ]; then
77
+ exit 0
78
+ fi
79
+
80
+ SESSION_ID=$(printf '%s' "$INPUT" | python3 -c '
81
+ import sys, json
82
+ try:
83
+ d = json.load(sys.stdin)
84
+ print(d.get("session_id", "") or "")
85
+ except Exception:
86
+ print("")
87
+ ' 2>/dev/null)
88
+ SESSION_ID8="${SESSION_ID:0:8}"
89
+ if [ -z "$SESSION_ID8" ]; then SESSION_ID8="-"; fi
90
+
91
+ if [ -z "$SESSION_ID" ]; then
92
+ echo "[ask-channel] decision=allow sessionId=- channel=none reason=fail-open-no-session" >&2
93
+ exit 0
94
+ fi
95
+
96
+ # ----- Resolve the tmpdir the writers used ---------------------------------
97
+ # The channel MCP config path is join(os.tmpdir(), ...). Node's os.tmpdir() on
98
+ # POSIX is `process.env.TMPDIR` with a trailing separator stripped, else '/tmp'.
99
+ # Reproduce that exactly so the lookup lands on the same directory the rc-spawn
100
+ # wrote to. `ASK_CHANNEL_TMPDIR` overrides it for tests only — never set in
101
+ # production; the SDK-spawned child inherits the manager's TMPDIR.
102
+ if [ -n "${ASK_CHANNEL_TMPDIR:-}" ]; then
103
+ TMP_DIR="$ASK_CHANNEL_TMPDIR"
104
+ else
105
+ # Mirror Node's os.tmpdir() (libuv uv_os_tmpdir): TMPDIR, then TMP, then TEMP,
106
+ # then /tmp; a trailing slash is stripped. The lookup must land on the exact
107
+ # directory the rc-spawn writer used, so this resolution order matches the
108
+ # writer's byte for byte. On the Pi (systemd user service) and macOS (launchd)
109
+ # only TMPDIR is ever set, but honouring the full order removes a latent
110
+ # false-allow if TMP/TEMP alone are present.
111
+ TMP_DIR="${TMPDIR:-${TMP:-${TEMP:-/tmp}}}"
112
+ TMP_DIR="${TMP_DIR%/}"
113
+ fi
114
+
115
+ # Sanitize the session id the same way the writers do:
116
+ # `sessionId.replace(/[^A-Za-z0-9_-]/g, '_')`.
117
+ SID_SAN=$(printf '%s' "$SESSION_ID" | sed 's/[^A-Za-z0-9_-]/_/g')
118
+
119
+ # ----- Channel attached? ---------------------------------------------------
120
+ # Any of the four channel MCP config filename shapes present in tmpdir for this
121
+ # session means a channel is bound (unified, webchat, whatsapp, or telegram).
122
+ CHANNEL_ATTACHED=0
123
+ for kind in channel webchat-channel wa-channel telegram-channel; do
124
+ if [ -e "$TMP_DIR/maxy-${kind}-${SID_SAN}.json" ]; then
125
+ CHANNEL_ATTACHED=1
126
+ break
127
+ fi
128
+ done
129
+
130
+ if [ "$CHANNEL_ATTACHED" -eq 1 ]; then
131
+ echo "[ask-channel] decision=block sessionId=${SESSION_ID8} channel=attached reason=channel-attached" >&2
132
+ echo "Blocked: this is a native-channel session and AskUserQuestion cannot be delivered over a channel (the channel protocol carries no elicitation card, so the turn would wedge). Ask the same question as prose in your channel reply tool and wait for the operator's next message." >&2
133
+ exit 2
134
+ fi
135
+
136
+ echo "[ask-channel] decision=allow sessionId=${SESSION_ID8} channel=none reason=no-channel" >&2
137
+ exit 0
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: platform-architecture
3
3
  description: Use when grounding any documented-surface claim about what Maxy 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:ceaeee9505453efdd80ee573d7574cb56a8301beca2152b8f70699d3688b2eba
4
+ content-hash: sha256:24ba1d10bf495eb27e7240cdabc0673af4b55a29fad384209f682f3fc0c2689e
5
5
  brand: maxy-code
6
6
  product-name: Maxy
7
7
  ---
@@ -3566,7 +3566,7 @@ If Ollama is unavailable at write time, the node is stored without an embedding
3566
3566
 
3567
3567
  The `memory-reindex` tool backfills missing embeddings by iterating nodes where `embedding IS NULL`. It uses the bounded representation (the `summary` for document/archive labels, never the raw body), embeds in batches with a per-node fallback on batch error, and **skips and continues** past a failing node — keeping skipped nodes out of the re-fetch via an exclude set — instead of aborting the whole run. `embed()`/`embedBatch()` cap oversized input (`EMBED_INPUT_MAX_CHARS`) before the Ollama POST, so a large body embeds truncated rather than throwing. Per-node `[reindex] op=embedded|skip-error` lines and a terminal `[reindex] op=done processed=N skipped=M`.
3568
3568
 
3569
- `embedBatch()` also paces large batches. A document's summary plus every section body in one `/api/embed` POST pins ollama's `llama-server` across all cores for the whole batch with no idle gaps; on a passively-cooled Pi the SoC climbs past its soft-temp limit and the board thermally hard-resets. `embedBatch` splits an input array longer than the effective sub-batch size into sub-batches, waiting `EMBED_SUBBATCH_COOLDOWN_MS` (default 1000) between them so the SoC gets cooling gaps; vectors are concatenated in input order. The effective sub-batch size is the smaller of two ceilings: the thermal count ceiling `EMBED_SUBBATCH_SIZE` (default 32) and a throughput ceiling `floor(EMBED_REQUEST_TIMEOUT_MS * 0.8 / EMBED_MS_PER_INPUT)`. The throughput ceiling exists because on a CPU-only embedder a fixed 32-input POST can exceed `EMBED_REQUEST_TIMEOUT_MS` and abort the atomic ingest write, so `EMBED_MS_PER_INPUT` (the budgeted worst-case wall-time for one capped input, default 6000 ms, env-tunable) bounds each POST to 80 % of the request timeout. Every `/api/embed` POST also carries `keep_alive` (`EMBED_KEEP_ALIVE`, default `-1` = keep the model resident forever) so an interactive graph query-embed never cold-loads and blows its 5 s timeout. All knobs are env-overridable for on-device tuning. The load-bearing thermal protection is the installer's `CPUQuota` cap on `ollama.service` (every embed caller is bounded there regardless of batch shape); this pacing is defence-in-depth. The UI's file-index path uses its own single-input embed client in `platform/ui/app/lib/neo4j-store.ts` (one embed per file, not a batch), so it is covered by the CPU cap, not by `embedBatch` pacing.
3569
+ `embedBatch()` also paces large batches. A document's summary plus every section body in one `/api/embed` POST pins ollama's `llama-server` across all cores for the whole batch with no idle gaps; on a passively-cooled Pi the SoC climbs past its soft-temp limit and the board thermally hard-resets. `embedBatch` splits a multi-input array into sub-batches, waiting `EMBED_SUBBATCH_COOLDOWN_MS` (default 1000) between them so the SoC gets cooling gaps; vectors are concatenated in input order. Each POST is sized from the device's *measured* throughput, not a fixed constant: the first POST of a multi-input batch is a single-input probe (the only size provably safe without a measurement), and every POST's observed per-character wall-time folds into a running maximum. Subsequent POSTs are packed with as many inputs as fit a character budget `floor(EMBED_REQUEST_TIMEOUT_MS * 0.8 / observedMsPerChar)`, capped by the `EMBED_SUBBATCH_SIZE` count ceiling. Sizing by characters rather than input count matters because an embed's wall-time scales with its characters — a POST sized by count from a short probe (a document summary) would over-provision when the later inputs are near-cap sections and abort. So a CPU-only device slower than the old budget gets character-bounded POSTs that complete inside `EMBED_REQUEST_TIMEOUT_MS`, instead of a fixed 16/32-input POST that exceeds it and aborts the atomic ingest write; the running maximum is monotonic, so a mid-batch slowdown shrinks the remainder and never re-expands into a timeout. `EMBED_SUBBATCH_SIZE` (default 32) is the thermal count ceiling and the hard cap on any POST. `EMBED_MS_PER_INPUT` (default 6000 ms, env-tunable) no longer sizes the POST; it is the reconciliation baseline — after each POST an `[embed] op=drift` line warns when the observed per-input time exceeds the budget by more than 1.5×, so a device slower than budget is surfaced by a standing check rather than by a later ingest failure. Every `/api/embed` POST also carries `keep_alive` (`EMBED_KEEP_ALIVE`, default `-1` = keep the model resident forever) so an interactive graph query-embed never cold-loads and blows its 5 s timeout. All knobs are env-overridable for on-device tuning. The load-bearing thermal protection is the installer's `CPUQuota` cap on `ollama.service` (every embed caller is bounded there regardless of batch shape); this pacing is defence-in-depth. The UI's file-index path uses its own single-input embed client in `platform/ui/app/lib/neo4j-store.ts` (one embed per file, not a batch), so it is covered by the CPU cap, not by `embedBatch` pacing.
3570
3570
 
3571
3571
  ---
3572
3572
 
@@ -95,7 +95,7 @@ If Ollama is unavailable at write time, the node is stored without an embedding
95
95
 
96
96
  The `memory-reindex` tool backfills missing embeddings by iterating nodes where `embedding IS NULL`. It uses the bounded representation (the `summary` for document/archive labels, never the raw body), embeds in batches with a per-node fallback on batch error, and **skips and continues** past a failing node — keeping skipped nodes out of the re-fetch via an exclude set — instead of aborting the whole run. `embed()`/`embedBatch()` cap oversized input (`EMBED_INPUT_MAX_CHARS`) before the Ollama POST, so a large body embeds truncated rather than throwing. Per-node `[reindex] op=embedded|skip-error` lines and a terminal `[reindex] op=done processed=N skipped=M`.
97
97
 
98
- `embedBatch()` also paces large batches. A document's summary plus every section body in one `/api/embed` POST pins ollama's `llama-server` across all cores for the whole batch with no idle gaps; on a passively-cooled Pi the SoC climbs past its soft-temp limit and the board thermally hard-resets. `embedBatch` splits an input array longer than the effective sub-batch size into sub-batches, waiting `EMBED_SUBBATCH_COOLDOWN_MS` (default 1000) between them so the SoC gets cooling gaps; vectors are concatenated in input order. The effective sub-batch size is the smaller of two ceilings: the thermal count ceiling `EMBED_SUBBATCH_SIZE` (default 32) and a throughput ceiling `floor(EMBED_REQUEST_TIMEOUT_MS * 0.8 / EMBED_MS_PER_INPUT)`. The throughput ceiling exists because on a CPU-only embedder a fixed 32-input POST can exceed `EMBED_REQUEST_TIMEOUT_MS` and abort the atomic ingest write, so `EMBED_MS_PER_INPUT` (the budgeted worst-case wall-time for one capped input, default 6000 ms, env-tunable) bounds each POST to 80 % of the request timeout. Every `/api/embed` POST also carries `keep_alive` (`EMBED_KEEP_ALIVE`, default `-1` = keep the model resident forever) so an interactive graph query-embed never cold-loads and blows its 5 s timeout. All knobs are env-overridable for on-device tuning. The load-bearing thermal protection is the installer's `CPUQuota` cap on `ollama.service` (every embed caller is bounded there regardless of batch shape); this pacing is defence-in-depth. The UI's file-index path uses its own single-input embed client in `platform/ui/app/lib/neo4j-store.ts` (one embed per file, not a batch), so it is covered by the CPU cap, not by `embedBatch` pacing.
98
+ `embedBatch()` also paces large batches. A document's summary plus every section body in one `/api/embed` POST pins ollama's `llama-server` across all cores for the whole batch with no idle gaps; on a passively-cooled Pi the SoC climbs past its soft-temp limit and the board thermally hard-resets. `embedBatch` splits a multi-input array into sub-batches, waiting `EMBED_SUBBATCH_COOLDOWN_MS` (default 1000) between them so the SoC gets cooling gaps; vectors are concatenated in input order. Each POST is sized from the device's *measured* throughput, not a fixed constant: the first POST of a multi-input batch is a single-input probe (the only size provably safe without a measurement), and every POST's observed per-character wall-time folds into a running maximum. Subsequent POSTs are packed with as many inputs as fit a character budget `floor(EMBED_REQUEST_TIMEOUT_MS * 0.8 / observedMsPerChar)`, capped by the `EMBED_SUBBATCH_SIZE` count ceiling. Sizing by characters rather than input count matters because an embed's wall-time scales with its characters — a POST sized by count from a short probe (a document summary) would over-provision when the later inputs are near-cap sections and abort. So a CPU-only device slower than the old budget gets character-bounded POSTs that complete inside `EMBED_REQUEST_TIMEOUT_MS`, instead of a fixed 16/32-input POST that exceeds it and aborts the atomic ingest write; the running maximum is monotonic, so a mid-batch slowdown shrinks the remainder and never re-expands into a timeout. `EMBED_SUBBATCH_SIZE` (default 32) is the thermal count ceiling and the hard cap on any POST. `EMBED_MS_PER_INPUT` (default 6000 ms, env-tunable) no longer sizes the POST; it is the reconciliation baseline — after each POST an `[embed] op=drift` line warns when the observed per-input time exceeds the budget by more than 1.5×, so a device slower than budget is surfaced by a standing check rather than by a later ingest failure. Every `/api/embed` POST also carries `keep_alive` (`EMBED_KEEP_ALIVE`, default `-1` = keep the model resident forever) so an interactive graph query-embed never cold-loads and blows its 5 s timeout. All knobs are env-overridable for on-device tuning. The load-bearing thermal protection is the installer's `CPUQuota` cap on `ollama.service` (every embed caller is bounded there regardless of batch shape); this pacing is defence-in-depth. The UI's file-index path uses its own single-input embed client in `platform/ui/app/lib/neo4j-store.ts` (one embed per file, not a batch), so it is covered by the CPU cap, not by `embedBatch` pacing.
99
99
 
100
100
  ---
101
101
 
@@ -1,18 +1,63 @@
1
1
  import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
2
- // Record the size of every /api/embed POST's input array, and return one
3
- // zero-vector per input so the index-aligned contract can be checked.
4
- function stubFetchRecordingBatchSizes(sizes) {
2
+ // Record every /api/embed POST's input array, and return one zero-vector per
3
+ // input so the index-aligned contract can be checked. Resolves instantly.
4
+ function stubFetchRecordingPosts(posts) {
5
5
  vi.stubGlobal("fetch", vi.fn(async (_url, init) => {
6
6
  const body = JSON.parse(init.body);
7
7
  const inputs = Array.isArray(body.input) ? body.input : [body.input];
8
- sizes.push(inputs.length);
8
+ posts.push(inputs);
9
9
  return {
10
10
  ok: true,
11
11
  json: async () => ({ embeddings: inputs.map(() => [0]) }),
12
12
  };
13
13
  }));
14
14
  }
15
- describe("throughput-aware embed sub-batch sizing", () => {
15
+ // Fake-clock stub: each POST "takes" (fixed overhead + total chars * msPerChar)
16
+ // of simulated wall-time, advanced synchronously so there is no real sleeping
17
+ // and no flakiness. The stub ignores the abort signal and always resolves, so a
18
+ // simulated-slow POST completes and its measured elapsed feeds the next size.
19
+ function stubFetchCharLatency(posts, msPerCharFor, overheadMs = 0) {
20
+ vi.setSystemTime(0);
21
+ let clock = 0;
22
+ let n = 0;
23
+ vi.stubGlobal("fetch", vi.fn(async (_url, init) => {
24
+ const body = JSON.parse(init.body);
25
+ const inputs = Array.isArray(body.input) ? body.input : [body.input];
26
+ posts.push(inputs);
27
+ const chars = inputs.reduce((s, t) => s + t.length, 0);
28
+ clock += overheadMs + chars * msPerCharFor(n);
29
+ n += 1;
30
+ vi.setSystemTime(clock);
31
+ return {
32
+ ok: true,
33
+ json: async () => ({ embeddings: inputs.map(() => [0]) }),
34
+ };
35
+ }));
36
+ }
37
+ const charsOf = (post) => post.reduce((s, t) => s + t.length, 0);
38
+ describe("subBatchCharBudget — pure char-budget sizing", () => {
39
+ beforeEach(() => {
40
+ vi.resetModules();
41
+ process.env.EMBED_REQUEST_TIMEOUT_MS = "120000";
42
+ });
43
+ afterEach(() => {
44
+ delete process.env.EMBED_REQUEST_TIMEOUT_MS;
45
+ });
46
+ it("returns floor(timeout * 0.8 / msPerChar) chars", async () => {
47
+ const { subBatchCharBudget } = await import("../../../../../../lib/embed-client/dist/index.js");
48
+ // 120000 * 0.8 / 4 = 24000 chars.
49
+ expect(subBatchCharBudget(4)).toBe(24000);
50
+ });
51
+ it("floors at 1 char when a single char would already blow the timeout", async () => {
52
+ const { subBatchCharBudget } = await import("../../../../../../lib/embed-client/dist/index.js");
53
+ expect(subBatchCharBudget(1e12)).toBe(1);
54
+ });
55
+ it("is unbounded (Infinity) when the device is effectively instant", async () => {
56
+ const { subBatchCharBudget } = await import("../../../../../../lib/embed-client/dist/index.js");
57
+ expect(subBatchCharBudget(0)).toBe(Infinity); // count ceiling governs instead
58
+ });
59
+ });
60
+ describe("embedBatch — adaptive char-based sub-batch sizing", () => {
16
61
  beforeEach(() => {
17
62
  vi.restoreAllMocks();
18
63
  vi.resetModules();
@@ -21,29 +66,126 @@ describe("throughput-aware embed sub-batch sizing", () => {
21
66
  process.env.EMBED_SUBBATCH_COOLDOWN_MS = "0"; // no real sleeps in test
22
67
  });
23
68
  afterEach(() => {
69
+ vi.useRealTimers();
24
70
  delete process.env.EMBED_REQUEST_TIMEOUT_MS;
25
71
  delete process.env.EMBED_SUBBATCH_SIZE;
26
72
  delete process.env.EMBED_SUBBATCH_COOLDOWN_MS;
27
73
  delete process.env.EMBED_MS_PER_INPUT;
28
74
  });
29
- it("caps each POST at min(count, duration) and keeps vectors index-aligned", async () => {
30
- process.env.EMBED_MS_PER_INPUT = "6000"; // durationCap = floor(120000*0.8/6000) = 16
31
- const sizes = [];
32
- stubFetchRecordingBatchSizes(sizes);
75
+ it("probes with a single input first, respects the count ceiling, and keeps vectors index-aligned", async () => {
76
+ const posts = [];
77
+ stubFetchRecordingPosts(posts); // instant -> msPerChar ~0 -> count ceiling after probe
33
78
  const { embedBatch } = await import("../../lib/embeddings.js");
34
79
  const texts = Array.from({ length: 35 }, (_, i) => `section ${i}`);
35
80
  const out = await embedBatch(texts);
36
- expect(out).toHaveLength(35);
37
- expect(sizes.every((n) => n <= 16)).toBe(true); // duration cap wins over 32
38
- expect(sizes.reduce((a, b) => a + b, 0)).toBe(35); // every input embedded once
39
- });
40
- it("lets the count cap win when per-input duration is small", async () => {
41
- process.env.EMBED_MS_PER_INPUT = "1000"; // durationCap = floor(120000*0.8/1000) = 96 -> count cap 32 wins
42
- const sizes = [];
43
- stubFetchRecordingBatchSizes(sizes);
81
+ expect(posts[0]).toHaveLength(1); // first POST is always the size-1 probe
82
+ expect(posts.every((p) => p.length <= 32)).toBe(true); // count ceiling is the hard cap
83
+ expect(posts.reduce((a, p) => a + p.length, 0)).toBe(35); // every input embedded once
84
+ expect(out).toHaveLength(35); // index-aligned: one vector per input
85
+ });
86
+ it("keeps a single-input batch (the warm interactive query) as exactly one POST", async () => {
87
+ const posts = [];
88
+ stubFetchRecordingPosts(posts);
89
+ const { embedBatch } = await import("../../lib/embeddings.js");
90
+ await embedBatch(["just one"]);
91
+ expect(posts.map((p) => p.length)).toEqual([1]);
92
+ });
93
+ it("does NOT over-size the next POST when a short first input under-represents later big inputs", async () => {
94
+ // The exitchatcontrol regression: a short document summary followed by
95
+ // near-cap section bodies. Sizing by input count from the fast summary
96
+ // probe would bundle every big input into one POST and time out; sizing by
97
+ // observed characters bounds each POST's total chars so every POST completes.
98
+ // Device-like numbers: 100 ms fixed request overhead + 3 ms/char.
99
+ vi.useFakeTimers();
100
+ const posts = [];
101
+ const MS_PER_CHAR = 3;
102
+ const OVERHEAD = 100;
103
+ stubFetchCharLatency(posts, () => MS_PER_CHAR, OVERHEAD);
104
+ const { embedBatch } = await import("../../lib/embeddings.js");
105
+ const texts = ["s".repeat(300), ...Array.from({ length: 10 }, () => "x".repeat(6000))];
106
+ const out = await embedBatch(texts);
107
+ expect(posts[0]).toHaveLength(1); // probe is the short summary
108
+ // Every POST — probe and each big-input POST — completes inside the 120 s
109
+ // timeout. The old per-input sizing would bundle all 10 big inputs into the
110
+ // POST after the probe (~180 s) and abort.
111
+ for (const p of posts) {
112
+ expect(OVERHEAD + charsOf(p) * MS_PER_CHAR).toBeLessThan(120000);
113
+ }
114
+ // Char-bounded: at most four 6000-char inputs per POST (24000 chars fit the
115
+ // 96000-char budget), never the count ceiling of 32.
116
+ expect(posts.slice(1).every((p) => p.length <= 4)).toBe(true);
117
+ expect(out).toHaveLength(11);
118
+ });
119
+ it("shrinks the remaining POSTs after a mid-batch slowdown", async () => {
120
+ // 100 inputs of 200 chars. First two POSTs fast (3 ms/char), then a 10x
121
+ // slowdown (30 ms/char). The running max shrinks every POST after it.
122
+ vi.useFakeTimers();
123
+ const posts = [];
124
+ stubFetchCharLatency(posts, (i) => (i < 2 ? 3 : 30), 100);
125
+ const { embedBatch } = await import("../../lib/embeddings.js");
126
+ const out = await embedBatch(Array.from({ length: 100 }, () => "y".repeat(200)));
127
+ expect(posts[0]).toHaveLength(1); // probe
128
+ expect(posts[1]).toHaveLength(32); // fast observation -> count ceiling
129
+ expect(posts[3].length).toBeLessThan(32); // shrinks after the slowdown
130
+ expect(posts[3].length).toBeGreaterThan(0);
131
+ expect(out).toHaveLength(100);
132
+ });
133
+ it("emits no malformed op=drift line for an empty batch", async () => {
134
+ const posts = [];
135
+ stubFetchRecordingPosts(posts);
136
+ const writes = [];
137
+ vi.spyOn(process.stderr, "write").mockImplementation((s) => {
138
+ writes.push(String(s));
139
+ return true;
140
+ });
44
141
  const { embedBatch } = await import("../../lib/embeddings.js");
45
- await embedBatch(Array.from({ length: 40 }, (_, i) => `s${i}`));
46
- expect(Math.max(...sizes)).toBe(32);
142
+ await embedBatch([]);
143
+ expect(writes.some((w) => /op=drift/.test(w))).toBe(false);
144
+ });
145
+ });
146
+ describe("embed drift reconciliation (op=drift)", () => {
147
+ beforeEach(() => {
148
+ vi.restoreAllMocks();
149
+ vi.resetModules();
150
+ process.env.EMBED_SUBBATCH_COOLDOWN_MS = "0";
151
+ });
152
+ afterEach(() => {
153
+ vi.useRealTimers();
154
+ delete process.env.EMBED_SUBBATCH_COOLDOWN_MS;
155
+ delete process.env.EMBED_MS_PER_INPUT;
156
+ delete process.env.EMBED_REQUEST_TIMEOUT_MS;
157
+ });
158
+ it("warns when a POST's observed per-input time drifts above the budget", async () => {
159
+ process.env.EMBED_MS_PER_INPUT = "5"; // budget baseline; 5 * 1.5 = 7.5 ms warn threshold
160
+ process.env.EMBED_REQUEST_TIMEOUT_MS = "120000";
161
+ vi.useFakeTimers();
162
+ vi.setSystemTime(0);
163
+ let clock = 0;
164
+ vi.stubGlobal("fetch", vi.fn(async () => {
165
+ clock += 200; // 200 ms for the single input -> far above budget
166
+ vi.setSystemTime(clock);
167
+ return { ok: true, json: async () => ({ embeddings: [[0]] }) };
168
+ }));
169
+ const writes = [];
170
+ vi.spyOn(process.stderr, "write").mockImplementation((s) => {
171
+ writes.push(String(s));
172
+ return true;
173
+ });
174
+ const { embed } = await import("../../lib/embeddings.js");
175
+ await embed("hello");
176
+ expect(writes.some((w) => /\[embed\] op=drift observedMsPerInput=200 budgetMsPerInput=5 ratio=40\.0/.test(w))).toBe(true);
177
+ });
178
+ it("stays silent when observed per-input time is within budget", async () => {
179
+ // default EMBED_MS_PER_INPUT = 6000; an instant POST is ~0 ms/input
180
+ vi.stubGlobal("fetch", vi.fn(async () => ({ ok: true, json: async () => ({ embeddings: [[0]] }) })));
181
+ const writes = [];
182
+ vi.spyOn(process.stderr, "write").mockImplementation((s) => {
183
+ writes.push(String(s));
184
+ return true;
185
+ });
186
+ const { embed } = await import("../../lib/embeddings.js");
187
+ await embed("hello");
188
+ expect(writes.some((w) => /op=drift/.test(w))).toBe(false);
47
189
  });
48
190
  });
49
191
  describe("embed keep_alive + per-POST breadcrumb", () => {
@@ -1 +1 @@
1
- {"version":3,"file":"embed-throughput.test.js","sourceRoot":"","sources":["../../../src/tools/__tests__/embed-throughput.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"embed-throughput.test.js","sourceRoot":"","sources":["../../../src/tools/__tests__/embed-throughput.test.ts"],"names":[],"mappings":"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"}
@@ -3,17 +3,15 @@ describe("embed request timeout + enriched errors", () => {
3
3
  beforeEach(() => {
4
4
  vi.restoreAllMocks();
5
5
  process.env.EMBED_REQUEST_TIMEOUT_MS = "50";
6
- // These tests assert enriched errors for a whole POST (inputs=2), not
7
- // sub-batch sizing. Throughput-aware sizing (Task 1533) derives the POST
8
- // size from the timeout, and a 50 ms timeout would otherwise floor the
9
- // batch to one input per POST. Pin a 1 ms per-input estimate so the
10
- // 2-input batch stays a single POST and the error still names inputs=2.
11
- process.env.EMBED_MS_PER_INPUT = "1";
6
+ // These tests assert the enriched error for the POST that failed. Adaptive
7
+ // sizing (Task 1553) makes the first POST of a multi-input batch a
8
+ // single-input probe, so the batch cases below put the largest input first
9
+ // and assert inputs=1 with that input's char count proving the error
10
+ // reports the count and largest input of the actual POST array.
12
11
  vi.resetModules();
13
12
  });
14
13
  afterEach(() => {
15
14
  delete process.env.EMBED_REQUEST_TIMEOUT_MS;
16
- delete process.env.EMBED_MS_PER_INPUT;
17
15
  });
18
16
  it("rejects promptly with an enriched timeout error, not a bare fetch failed", async () => {
19
17
  // Honour the abort signal: never resolve, reject when the timeout fires.
@@ -31,7 +29,9 @@ describe("embed request timeout + enriched errors", () => {
31
29
  init.signal.addEventListener("abort", () => rej(init.signal.reason ?? new Error("aborted")));
32
30
  })));
33
31
  const { embedBatch } = await import("../../lib/embeddings.js");
34
- await expect(embedBatch(["a", "bbbb"])).rejects.toThrow(/timed out.*inputs=2.*largestInputChars=4/s);
32
+ // Largest input first: the size-1 probe carries "bbbb", so the timed-out
33
+ // POST reports inputs=1 and largestInputChars=4.
34
+ await expect(embedBatch(["bbbb", "a"])).rejects.toThrow(/timed out.*inputs=1.*largestInputChars=4/s);
35
35
  });
36
36
  it("names the underlying cause on a connection failure, not a bare fetch failed", async () => {
37
37
  // Mirrors undici on a refused connection: TypeError("fetch failed", { cause }).
@@ -50,7 +50,9 @@ describe("embed request timeout + enriched errors", () => {
50
50
  text: async () => '{"error":"the input length exceeds the context length"}',
51
51
  })));
52
52
  const { embedBatch } = await import("../../lib/embeddings.js");
53
- await expect(embedBatch(["a", "bbbb"])).rejects.toThrow(/400.*inputs=2.*largestInputChars=4/s);
53
+ // Largest input first: the size-1 probe carries "bbbb", so the HTTP error
54
+ // reports inputs=1 and largestInputChars=4.
55
+ await expect(embedBatch(["bbbb", "a"])).rejects.toThrow(/400.*inputs=1.*largestInputChars=4/s);
54
56
  });
55
57
  });
56
58
  //# sourceMappingURL=embed-timeout.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"embed-timeout.test.js","sourceRoot":"","sources":["../../../src/tools/__tests__/embed-timeout.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"embed-timeout.test.js","sourceRoot":"","sources":["../../../src/tools/__tests__/embed-timeout.test.ts"],"names":[],"mappings":"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"}
@@ -17,18 +17,22 @@ describe("embed input capping", () => {
17
17
  expect(sentInput.length).toBe(EMBED_INPUT_MAX_CHARS);
18
18
  });
19
19
  it("embedBatch caps each oversized element, leaves short ones intact", async () => {
20
- let sent = [];
20
+ // Adaptive sizing (Task 1553) may split a batch across POSTs (a size-1
21
+ // probe first), so collect every posted input and check capping applied to
22
+ // each element wherever it landed, preserving input order.
23
+ const posted = [];
21
24
  vi.stubGlobal("fetch", vi.fn(async (_u, init) => {
22
- sent = JSON.parse(init.body).input;
25
+ const inp = JSON.parse(init.body).input;
26
+ posted.push(...inp);
23
27
  return {
24
28
  ok: true,
25
- json: async () => ({ embeddings: sent.map(() => [0.1]) }),
29
+ json: async () => ({ embeddings: inp.map(() => [0.1]) }),
26
30
  };
27
31
  }));
28
32
  const { embedBatch, EMBED_INPUT_MAX_CHARS } = await import("../../lib/embeddings.js");
29
33
  await embedBatch(["short", "y".repeat(50_000)]);
30
- expect(sent[0]).toBe("short");
31
- expect(sent[1].length).toBe(EMBED_INPUT_MAX_CHARS);
34
+ expect(posted[0]).toBe("short");
35
+ expect(posted[1].length).toBe(EMBED_INPUT_MAX_CHARS);
32
36
  });
33
37
  });
34
38
  describe("token-safe cap default", () => {
@@ -1 +1 @@
1
- {"version":3,"file":"embeddings-cap.test.js","sourceRoot":"","sources":["../../../src/tools/__tests__/embeddings-cap.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"embeddings-cap.test.js","sourceRoot":"","sources":["../../../src/tools/__tests__/embeddings-cap.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=profile-update-own-preference-selfheal.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profile-update-own-preference-selfheal.test.d.ts","sourceRoot":"","sources":["../../../src/tools/__tests__/profile-update-own-preference-selfheal.test.ts"],"names":[],"mappings":""}