@rubytech/create-maxy 1.0.636 → 1.0.638

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 (34) hide show
  1. package/dist/index.js +30 -23
  2. package/package.json +1 -1
  3. package/payload/platform/plugins/admin/mcp/dist/lib/onboarding.d.ts +14 -0
  4. package/payload/platform/plugins/admin/mcp/dist/lib/onboarding.d.ts.map +1 -1
  5. package/payload/platform/plugins/admin/mcp/dist/lib/onboarding.js +83 -8
  6. package/payload/platform/plugins/admin/mcp/dist/lib/onboarding.js.map +1 -1
  7. package/payload/platform/plugins/admin/skills/onboarding/SKILL.md +21 -8
  8. package/payload/platform/plugins/cloudflare/mcp/dist/lib/cloudflared.d.ts +0 -2
  9. package/payload/platform/plugins/cloudflare/mcp/dist/lib/cloudflared.d.ts.map +1 -1
  10. package/payload/platform/plugins/cloudflare/mcp/dist/lib/cloudflared.js +5 -32
  11. package/payload/platform/plugins/cloudflare/mcp/dist/lib/cloudflared.js.map +1 -1
  12. package/payload/platform/plugins/cloudflare/scripts/setup-tunnel.sh +48 -1
  13. package/payload/platform/plugins/cloudflare/skills/setup-tunnel/SKILL.md +10 -12
  14. package/payload/platform/plugins/docs/references/cloudflare.md +8 -7
  15. package/payload/platform/plugins/docs/references/getting-started.md +9 -0
  16. package/payload/platform/plugins/memory/mcp/scripts/graph/accept.sh +96 -8
  17. package/payload/platform/plugins/memory/references/graph-primitives.md +52 -4
  18. package/payload/platform/plugins/workflows/PLUGIN.md +4 -0
  19. package/payload/platform/plugins/workflows/mcp/dist/lib/llm-call.d.ts +25 -2
  20. package/payload/platform/plugins/workflows/mcp/dist/lib/llm-call.d.ts.map +1 -1
  21. package/payload/platform/plugins/workflows/mcp/dist/lib/llm-call.js +41 -13
  22. package/payload/platform/plugins/workflows/mcp/dist/lib/llm-call.js.map +1 -1
  23. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-execute.d.ts.map +1 -1
  24. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-execute.js +18 -6
  25. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-execute.js.map +1 -1
  26. package/payload/platform/scripts/setup.sh +1 -1
  27. package/payload/server/public/assets/{admin-E3EIZIw0.js → admin-tPrH6zWV.js} +60 -60
  28. package/payload/server/public/assets/{public-Lwkux_Q4.js → public-DdVq1Jag.js} +1 -1
  29. package/payload/server/public/assets/useVoiceRecorder-BNLXzSN4.css +1 -0
  30. package/payload/server/public/index.html +3 -3
  31. package/payload/server/public/public.html +3 -3
  32. package/payload/server/server.js +124 -9
  33. package/payload/server/public/assets/useVoiceRecorder-Cbo-LQPY.css +0 -1
  34. /package/payload/server/public/assets/{useVoiceRecorder-D4y_EM_A.js → useVoiceRecorder-3Qblv7wH.js} +0 -0
@@ -22,19 +22,17 @@ Any Cloudflare action outside these four surfaces is a discipline violation —
22
22
 
23
23
  Use this when the operator wants Cloudflare set up (or re-set up) end-to-end on the device. The script handles OAuth login, tunnel creation, DNS routing for each subdomain, config.yml + tunnel.state, and dispatches the `${BRAND}.service` restart to a transient `systemd-run` unit (Task 558) — all in one invocation. The restart fires a few seconds after the script exits so the script does not kill its own cgroup when invoked via the Bash tool; the chat UI receives a `server_shutdown` SSE frame and reconnects automatically. Post-restart hostname verification is out of scope for the script (connector is not up when the script exits) — verify via the next admin turn or manually with `curl -I https://<hostname>`. Apex hostnames cannot be routed by the CLI; when one is passed, the script prints an `ACTION REQUIRED` block naming the exact dashboard record to edit.
24
24
 
25
- ### Inputs to collect before invoking
25
+ ### How inputs reach the script
26
26
 
27
- Ask the operator each question once. Do not invoke the script until every required input is in hand.
27
+ Inputs arrive through the `cloudflare-setup-form` component, not agent Q&A. The onboarding skill renders the form, the user submits admin/public/apex labels and the admin password in one action, and the `/api/admin/cloudflare/setup` endpoint runs (in this order):
28
28
 
29
- | Input | Example | Required? | How to ask |
30
- |---|---|---|---|
31
- | Brand | `maxy`, `realagent` | yes | Usually known from the device context (`brand.json`). Confirm if ambiguous. |
32
- | Platform port | `19200` (maxy), `19500` (realagent) | yes | Known from brand. Do not ask the operator. |
33
- | Admin hostname | `admin.maxy.bot`, `joel.example.com` | yes | "What hostname should serve the admin chat?" |
34
- | Public hostname | `public.maxy.bot`, `chat.example.com` | optional | "Any hostname for the public agent? Say no to skip." |
35
- | Apex hostname | `maxy.chat`, `example.com` | optional | "Any bare-domain hostname (no subdomain) that should also serve the public agent?" |
29
+ 1. `setRemotePassword(password)` writes the hashed password.
30
+ 2. `~/setup-tunnel.sh <brand> <port> <admin-fqdn> [<public-fqdn>] [<apex-fqdn>]` — brand and port are resolved server-side from `brand.json` and `process.env.PORT`, never form inputs.
31
+ 3. For each submitted hostname that is not the admin FQDN and does not start with `public.`, writes it to `~/{configDir}/alias-domains.json` so `isPublicHost()` classifies it as public.
36
32
 
37
- ### Invocation
33
+ The script itself is unchanged; only its invocation path moved from "agent collects Q&A then Bash" to "form submits, endpoint spawns".
34
+
35
+ ### Invocation shape (reference)
38
36
 
39
37
  ```
40
38
  ~/setup-tunnel.sh <brand> <port> <admin-hostname> [<public-hostname>] [<apex-hostname>]
@@ -46,11 +44,11 @@ Example (Maxy on `maxy.bot` with a public subdomain and the `maxy.chat` apex):
46
44
  ~/setup-tunnel.sh maxy 19200 admin.maxy.bot public.maxy.bot maxy.chat
47
45
  ```
48
46
 
49
- Invoke via Bash. When the script exits, relay its output verbatim. If an `ACTION REQUIRED` block appears, quote it exactly — the operator needs the specific dashboard instructions it contains.
47
+ The agent does not invoke the script directly during onboarding — the endpoint does. The agent's responsibility is to render the form and relay the endpoint's script output verbatim when `_componentDone` arrives. If an `ACTION REQUIRED` block appears, quote it exactly — the operator needs the specific dashboard instructions it contains.
50
48
 
51
49
  ### When the script exits non-zero
52
50
 
53
- Report the failure, name the exit code, and cite `references/reset-guide.md` for the next action. Do not attempt a second invocation, a Playwright-driven dashboard inspection, or an alternative `cloudflared` command sequence. The discipline rule below applies.
51
+ The endpoint returns `{ ok: false, field: "script", message, output }` and the form surfaces the error inline. Relay the output to the user, name the exit code, and cite `references/reset-guide.md` for the next action. Offer to re-render the form after any manual steps the script's error output named. Do not attempt a second invocation outside the form, a Playwright-driven dashboard inspection, or an alternative `cloudflared` command sequence. The discipline rule below applies.
54
52
 
55
53
  ---
56
54
 
@@ -14,24 +14,25 @@ There is no token-based auth for the operator-owned path (Mode A). To switch Clo
14
14
 
15
15
  ## Setup flow
16
16
 
17
- Ask the agent to set up Cloudflare. The agent collects four things before acting:
17
+ Ask the agent to set up Cloudflare. The agent first confirms the domain is already on your Cloudflare account (if not, it quotes the dashboard click-path — see below) and then renders a single form in chat. The form collects everything in one submission:
18
18
 
19
- 1. The admin hostname for this device (e.g. `admin.yourdomain.com`).
20
- 2. Optionally, a public hostname (e.g. `public.yourdomain.com`) for the public agent.
21
- 3. Optionally, an apex hostname (e.g. `yourdomain.com`) as a bare root to serve the public agent.
22
- 4. Confirmation the domain is already on your Cloudflare account (or guidance to add it first — see below).
19
+ - **Admin address** — the hostname that will serve the admin chat (e.g. `admin.yourdomain.com`).
20
+ - **Public address** optional hostname for the public agent (e.g. `public.yourdomain.com` or `chat.yourdomain.com`).
21
+ - **Proxy apex** — optional bare-domain hostname (e.g. `yourdomain.com`) that should also serve the public agent.
22
+ - **Admin password** the password used to gate remote access to the admin surface.
23
23
 
24
- The agent then invokes `setup-tunnel.sh` on the device with your inputs. The script runs end-to-end:
24
+ When you submit, the `/api/admin/cloudflare/setup` endpoint runs — in strict order — `setRemotePassword`, `setup-tunnel.sh`, and alias-domain writes for every non-`public.*` public or apex hostname (so e.g. `chat.yourdomain.com` is classified as public by `isPublicHost()`). The script runs end-to-end:
25
25
 
26
26
  - `cloudflared tunnel login` — OAuth browser sign-in. The VNC browser opens the Cloudflare authorize page; pick the account that owns your domain, click Authorize. `cert.pem` lands.
27
27
  - Tunnel creation under the naming convention `{brand}-{hostname}` (e.g. `maxy-neo`). Stream log emits `step=tunnel-resolve action=reused|created` once the UUID is known so the admin agent can see which tunnel the later steps will write against.
28
28
  - **Zone pre-flight** — for every non-apex hostname the script queries `1.1.1.1` for the registrable parent's NS records and refuses the whole run if they don't point at Cloudflare. Stream log: `step=zone-preflight result=ok|error zones_on_account=… missing_parent_for=…`. Catches "domain not on Cloudflare"; does not catch "domain on a different Cloudflare account than `cert.pem` is bound to" — that case surfaces later via `tunnel-status`.
29
29
  - `cloudflared tunnel route dns` for each subdomain hostname. Apex hostnames cannot be routed this way — the script prints an **ACTION REQUIRED** block naming the exact dashboard record to add or edit. Stream log emits `step=route-dns hostname=… tunnel_id=…` before the call and `step=route-dns hostname=… result=ok|apex-skip|error` after; on error the bounded cloudflared stderr (≤400 chars) rides in the same phase line. **The script does not parse cloudflared's stdout** — exit code is the sole decision signal, so all three legitimate cloudflared output shapes (new record, overwrite, idempotent "already configured") are treated as success.
30
30
  - `config.yml` and `tunnel.state` written under `${CFG_DIR}`.
31
+ - **Step-7 onboarding completion persisted** — the script writes `${ACCOUNT_DIR}/onboarding/step7-complete` (a JSON marker with the completion timestamp and tunnel ID) before arming the restart. Stream log: `step=onboarding-persist result=ok|error reason=<r>`. The marker is consumed by the next admin session's first state read and advances `OnboardingState.currentStep` to 7. Without this, the service restart below would SIGTERM the admin agent before it could persist step-7 completion, and the next session would re-ask the Cloudflare question you just finished.
31
32
  - `systemctl --user restart ${BRAND}.service` — restarts the platform service so the new tunnel spawns via the service's `ExecStartPre=resume-tunnel.sh`.
32
33
  - Post-restart verification — `ps -ef | grep '[c]loudflared'` confirms the connector is alive, then `curl -I https://<hostname>` against each subdomain (up to 60 s per host) confirms a non-530 response.
33
34
 
34
- When the script exits, the agent relays its output verbatim, including any `ACTION REQUIRED` block.
35
+ When the endpoint returns, the form surfaces the script's output and the agent relays it verbatim in chat, including any `ACTION REQUIRED` block. If something fails along the way, the form stays open with a field-scoped error (admin label, public label, password, or script exit) so you can correct and retry without re-entering everything.
35
36
 
36
37
  ## Getting a domain on Cloudflare
37
38
 
@@ -64,6 +64,15 @@ Maxy maintains a memory graph of everything important: contacts, conversations,
64
64
 
65
65
  You can always tell Maxy to remember or forget specific things: "Remember that I prefer morning calls" or "Forget what I said about the Johnson account."
66
66
 
67
+ ## Reaching Your Data When Maxy Is Unavailable
68
+
69
+ If the AI is ever unreachable — network outage, API provider down — you can still access your own data through the **Data** item in the admin header menu. It opens a page with two panels:
70
+
71
+ - **Graph search** — type a keyword to search your knowledge documents, sections, and notes directly in Neo4j. No AI involved.
72
+ - **Files** — browse everything under your install's `data/` folder. Click a folder to open it, a file to download it. Use **Upload** to drop new files into `data/uploads/`.
73
+
74
+ Everything on this page works without calling any AI service. It's there so your data is never locked behind an agent that can't respond.
75
+
67
76
  ## Getting Help
68
77
 
69
78
  Ask Maxy anything. If you want to know what it can do, just ask: "What can you help me with?" or "How do I set up Telegram?"
@@ -1,11 +1,17 @@
1
1
  #!/usr/bin/env bash
2
- # Task 557 acceptance harness for the graph MCP integration.
2
+ # Acceptance harness for the graph MCP integration.
3
3
  #
4
4
  # Spawns the graph shim, drives it as a JSON-RPC client over stdio, runs
5
5
  # one query per acceptance class, prints PASS/FAIL per check, and exits
6
6
  # non-zero if any check fails. Assumes the brand's Neo4j is running and
7
7
  # the fixture in fixture.cypher has been seeded.
8
8
  #
9
+ # The tools/list assertion guards against FastMCP-joiner drift: the
10
+ # upstream server joins NEO4J_NAMESPACE to each tool name with a hyphen,
11
+ # and the admin allowlist is string-exact. If a future upstream upgrade
12
+ # changes the joiner, the assertion fails with a named reason before any
13
+ # functional check runs.
14
+ #
9
15
  # Usage:
10
16
  # PLATFORM_ROOT=~/.maxy/platform bash accept.sh # infers NEO4J_URI from env
11
17
  # PLATFORM_ROOT=~/.maxy/platform NEO4J_URI=bolt://localhost:7687 bash accept.sh
@@ -36,10 +42,88 @@ PASS=0
36
42
  FAIL=0
37
43
  TOTAL=0
38
44
 
45
+ # Exported env used by the inline Node clients below.
46
+ export SHIM
47
+ export PLATFORM_ROOT
48
+
49
+ # ---------------------------------------------------------------------------
50
+ # Regression guard: tools/list must register hyphen-joined names only.
51
+ #
52
+ # FastMCP joins NEO4J_NAMESPACE ("maxy-graph") to each upstream tool with a
53
+ # hyphen, producing `maxy-graph-read_neo4j_cypher` and
54
+ # `maxy-graph-get_neo4j_schema`. Claude Code's MCP client adds `mcp__graph__`
55
+ # on top when registering the server — the admin allowlist in
56
+ # platform/ui/app/lib/claude-agent.ts must match those exact names.
57
+ # A future upstream version that changes the joiner (e.g. to underscore)
58
+ # silently re-introduces a class of denial unless this fires.
59
+ # ---------------------------------------------------------------------------
60
+ assert_tools_list() {
61
+ TOTAL=$(( TOTAL + 1 ))
62
+ local out
63
+ if ! out=$(
64
+ node -e "
65
+ const { spawn } = require('node:child_process');
66
+ const proc = spawn('node', [process.env.SHIM], { stdio: ['pipe', 'pipe', 'inherit'] });
67
+ let buf = '';
68
+ proc.stdout.on('data', (chunk) => { buf += chunk.toString('utf8'); });
69
+ const send = (obj) => proc.stdin.write(JSON.stringify(obj) + '\n');
70
+ send({ jsonrpc: '2.0', id: 1, method: 'initialize',
71
+ params: { protocolVersion: '2024-11-05', capabilities: {}, clientInfo: { name: 'accept.sh', version: '1.0' } } });
72
+ setTimeout(() => {
73
+ send({ jsonrpc: '2.0', method: 'notifications/initialized' });
74
+ send({ jsonrpc: '2.0', id: 2, method: 'tools/list', params: {} });
75
+ }, 1500);
76
+ setTimeout(() => {
77
+ proc.kill('SIGTERM');
78
+ const lines = buf.split('\n').filter(Boolean);
79
+ for (const line of lines) {
80
+ try { const m = JSON.parse(line); if (m.id === 2) {
81
+ if (m.error) { console.error('RPC_ERROR: ' + JSON.stringify(m.error)); process.exit(1); }
82
+ const names = (m.result && m.result.tools || []).map(t => t.name);
83
+ process.stdout.write(JSON.stringify(names));
84
+ process.exit(0);
85
+ } } catch (_) {}
86
+ }
87
+ console.error('NO_RESPONSE');
88
+ process.exit(1);
89
+ }, 10000);
90
+ " 2>/dev/null
91
+ ); then
92
+ echo "FAIL: tools/list RPC did not respond"
93
+ FAIL=$(( FAIL + 1 ))
94
+ return 1
95
+ fi
96
+
97
+ local missing=""
98
+ for expected in "maxy-graph-read_neo4j_cypher" "maxy-graph-get_neo4j_schema"; do
99
+ if ! grep -q "\"$expected\"" <<<"$out"; then
100
+ missing+=" $expected"
101
+ fi
102
+ done
103
+ if [[ -n "$missing" ]]; then
104
+ echo "FAIL: tools/list missing hyphen-joined names —${missing} (reason: missing-hyphen-tool)"
105
+ echo " received: $out"
106
+ FAIL=$(( FAIL + 1 ))
107
+ return 1
108
+ fi
109
+
110
+ if grep -qE 'maxy-graph_(read|get|write)' <<<"$out"; then
111
+ local stray
112
+ stray=$(grep -oE 'maxy-graph_[a-z_]+' <<<"$out" | sort -u | tr '\n' ' ')
113
+ echo "FAIL: tools/list contains underscore-joined variant(s) — ${stray}(reason: stray-underscore-tool)"
114
+ FAIL=$(( FAIL + 1 ))
115
+ return 1
116
+ fi
117
+
118
+ echo "PASS: tools/list registers hyphen-joined names only (${#out}b response)"
119
+ PASS=$(( PASS + 1 ))
120
+ return 0
121
+ }
122
+
39
123
  run_check() {
40
124
  local label="$1"
41
125
  local query="$2"
42
- local tool="${3:-maxy-graph_read_neo4j_cypher}"
126
+ local tool="${3:-maxy-graph-read_neo4j_cypher}"
43
127
  TOTAL=$(( TOTAL + 1 ))
44
128
 
45
129
  # Drive the shim via a short Node inline client. Exits 0 with the response
@@ -58,7 +142,7 @@ run_check() {
58
142
  params: { protocolVersion: '2024-11-05', capabilities: {}, clientInfo: { name: 'accept.sh', version: '1.0' } } });
59
143
  setTimeout(() => {
60
144
  send({ jsonrpc: '2.0', method: 'notifications/initialized' });
61
- const params = tool === 'maxy-graph_get_neo4j_schema' ? {} : { query };
145
+ const params = tool === 'maxy-graph-get_neo4j_schema' ? {} : { query };
62
146
  send({ jsonrpc: '2.0', id: 2, method: 'tools/call', params: { name: tool, arguments: params } });
63
147
  }, 1500);
64
148
  setTimeout(() => {
@@ -91,15 +175,19 @@ run_check() {
91
175
  fi
92
176
  }
93
177
 
94
- # Exported env used by the inline Node client above.
95
- export SHIM
96
- export PLATFORM_ROOT
178
+ # Run the regression guard first. If it fails, abort early — running
179
+ # functional queries with stale tool names produces misleading failures.
180
+ if ! assert_tools_list; then
181
+ echo ""
182
+ echo "FAIL — tool registration contract violated; aborting functional checks"
183
+ exit 1
184
+ fi
97
185
 
98
- export TOOL="maxy-graph_get_neo4j_schema"
186
+ export TOOL="maxy-graph-get_neo4j_schema"
99
187
  export QUERY=""
100
188
  run_check "get_neo4j_schema returns labels" ""
101
189
 
102
- export TOOL="maxy-graph_read_neo4j_cypher"
190
+ export TOOL="maxy-graph-read_neo4j_cypher"
103
191
 
104
192
  export QUERY="MATCH (n) RETURN labels(n)[0] AS type, count(*) AS n ORDER BY n DESC LIMIT 20"
105
193
  run_check "enumerate by label" "$QUERY"
@@ -1,5 +1,5 @@
1
1
  <!-- Injected into admin system prompt by claude-agent.ts when agentType === "admin". -->
2
- <!-- Consumed by the upstream mcp-neo4j-cypher server via `maxy-graph_read_neo4j_cypher`. -->
2
+ <!-- Consumed by the upstream mcp-neo4j-cypher server via `maxy-graph-read_neo4j_cypher`. -->
3
3
  <!-- Source of truth for node labels and properties: platform/neo4j/schema.cypher + plugins/memory/references/schema-*.md. -->
4
4
 
5
5
  # Graph interrogation (read-only Cypher cookbook)
@@ -7,7 +7,7 @@
7
7
  When a user asks a relational question about their own graph — *"list all my
8
8
  people", "how many tasks do I have", "find the person with email X", "what's
9
9
  linked to this business", "show me the 20 most recently created nodes" — use
10
- `maxy-graph_read_neo4j_cypher` or `maxy-graph_get_neo4j_schema`, not
10
+ `maxy-graph-read_neo4j_cypher` or `maxy-graph-get_neo4j_schema`, not
11
11
  `memory-search`. Vector search is for "things like this"; Cypher is for "the
12
12
  exact set where".
13
13
 
@@ -15,9 +15,17 @@ The connected Neo4j instance contains only this brand's data (per-brand
15
15
  instance architecture — see `.docs/neo4j.md`). You never need an account
16
16
  filter in the query.
17
17
 
18
+ For visual exploration ("can I see this graphically?", "show me the graph"),
19
+ tell the user to open the **Graph** menu item in the burger menu — it opens
20
+ Neo4j Browser pointed at their own brand's graph. Do not build ad-hoc HTML
21
+ visualizations, do not start a static file server, do not `Write` an
22
+ `.html` file and navigate Playwright to it. The one-sentence reply
23
+ ("Open the Graph menu item in the top-right — it opens a visual browser
24
+ for your graph") is the correct answer.
25
+
18
26
  ## When the graph tools are absent
19
27
 
20
- If neither `maxy-graph_read_neo4j_cypher` nor `maxy-graph_get_neo4j_schema`
28
+ If neither `maxy-graph-read_neo4j_cypher` nor `maxy-graph-get_neo4j_schema`
21
29
  appears in your tool list, the graph MCP server failed to start on this
22
30
  device. Reply once with exactly:
23
31
 
@@ -30,6 +38,46 @@ deterministic path through the shim is the only supported way to read
30
38
  the graph, and any substitute path loses the read-only + namespace +
31
39
  token-limit discipline the upstream server enforces.
32
40
 
41
+ ## Mutation intents
42
+
43
+ The graph tools above are read-only. Every write intent has a schema-aware
44
+ tool that already exists — match the user's prose to a tool in this table
45
+ rather than improvising. `mcp__admin__admin-remove` is in your initial
46
+ tool list; the other five tools below are deferred (they do not appear
47
+ until you invoke `ToolSearch` by the exact name you pick from the table).
48
+ Do not use `ToolSearch` to *discover* the tool by keyword — identify it
49
+ from the table first, then fetch its schema by exact name.
50
+
51
+ | User intent | Tool | When to pick this, not the next row |
52
+ |---|---|---|
53
+ | "prune", "clean up", "remove orphans", "graph hygiene" | `mcp__memory__graph-prune-run` | On-demand run of the nightly 03:00 cron: orphan-delete, deny-list null, candidate-merge flag, contradiction flag. Targets nodes by *structural pattern* (e.g. "no inbound or outbound edges"), not by identity — no `elementId` needed. Run with `dryRun: true` first when the blast radius is unknown. Not for removing one specific node by id — use `memory-delete` for that. |
54
+ | "remove admin X", "take away their admin access", "revoke admin" | `mcp__admin__admin-remove` | Device-level admin offboarding — detaches the `(AdminUser)-[:ADMIN_OF]->(LocalBusiness)` edge and updates `platform/config/users.json`. Not for scrubbing personal data — use the GDPR contact-erase tools for that. |
55
+ | "delete this specific node", "remove this entry by its id", "get rid of node X" | `mcp__memory__memory-delete` | Deterministic single-node deletion by `elementId`. For KnowledgeDocument, cascades to Sections and Chunks. Not for pruning orphans en masse — use `graph-prune-run`. |
56
+ | "scrub this conversation's memory", "remove this claim the bot picked up", "forget what we said in that thread" | `mcp__memory__conversation-memory-expunge` | Removes the `:Memory` payload attached to a specific conversation without deleting the conversation itself. Not for deleting individual nodes — use `memory-delete`. |
57
+ | "update a property", "fix a typo in a node", "change the role field on X" | `mcp__memory__memory-update` | Targeted property edit on an existing node, schema-validated. Not for creating new nodes — use `memory-write`. |
58
+ | "don't surface these substrings in future memory results", "block this string from search" | `mcp__memory__graph-prune-denylist-add` | Adds a substring to the deny-list; the next `graph-prune-run` nulls matching property values. Not for removing nodes outright — use `memory-delete` or `graph-prune-run`. |
59
+
60
+ **Never run `cypher-shell` via `Bash` to work around the read-only tool.**
61
+ The admin session's `Bash` surface has no path to the per-brand Neo4j
62
+ password (it lives in `${PLATFORM_ROOT}/config/.neo4j-password`,
63
+ unreachable from the admin account's `Bash` cwd, and pre-tool-use hooks
64
+ block `Bash` against the code tree anyway — `.docs/neo4j.md`'s migration
65
+ section is an operator-run runbook, not a path you should replicate in
66
+ chat). Every write intent has a schema-aware tool above. If none of them
67
+ fits, tell the user plainly: *"This operation is not in the admin tool
68
+ surface. It can be added as a task."* — do not invent a workaround.
69
+
70
+ **Worked example — "prune the stale AdminUsers".** When an admin asks to
71
+ prune stale AdminUser entries (e.g., 15 nodes left over from prior
72
+ installs, none linked by `ADMIN_OF` to a `LocalBusiness`), those nodes are
73
+ orphans. Answer: run `mcp__memory__graph-prune-run` (optionally with
74
+ `dryRun: true` first to preview) — the `orphan-delete` rule removes any
75
+ node with no inbound or outbound relationships, which is exactly what
76
+ stale AdminUsers are. This is the same operation the 03:00 cron runs
77
+ nightly, applied on demand. Do not hunt for Neo4j credentials in `Bash`;
78
+ do not `ToolSearch` for sibling names — the tool name above is the
79
+ deterministic answer.
80
+
33
81
  ## Non-negotiable: never return raw nodes
34
82
 
35
83
  `RETURN n` dumps every property, including the 768-dim `embedding` float
@@ -162,7 +210,7 @@ All relationship types:
162
210
  CALL db.relationshipTypes() YIELD relationshipType RETURN relationshipType ORDER BY relationshipType
163
211
  ```
164
212
 
165
- Or use `maxy-graph_get_neo4j_schema` for a richer one-shot structural summary.
213
+ Or use `maxy-graph-get_neo4j_schema` for a richer one-shot structural summary.
166
214
 
167
215
  ### Fulltext
168
216
 
@@ -15,6 +15,8 @@ metadata: {"platform":{"always":false,"embed":[],"pluginKey":"workflows"}}
15
15
 
16
16
  # Workflows
17
17
 
18
+ > **Loading note:** `platform.always:false` in the frontmatter above refers to **prose embedding** — this file's contents are not auto-injected into every agent system prompt. It does **not** refer to MCP server loading. The workflows MCP server is always loaded in admin sessions (registered in `getMcpServers()` in `claude-agent.ts` alongside `tasks` / `scheduling` / `email`), and the same binary is also spawned ad-hoc from the heartbeat cron for scheduled `workflow-execute` calls via `.mcp.json`.
19
+
18
20
  Workflows are persistent, named compositions of executable steps that the user creates and the engine executes. Steps can chain MCP tool calls and LLM reasoning into composable pipelines. Steps are validated at creation time — a workflow with unmet dependencies cannot be activated. The user manages them conversationally.
19
21
 
20
22
  ## Creating Workflows
@@ -41,6 +43,8 @@ When the user describes a recurring process, conditional action, or reusable seq
41
43
 
42
44
  LLM steps spawn Claude Code as a subprocess (`claude --print`), which handles OAuth authentication internally. They never use the Anthropic API key directly — that path is exclusively for the public agent.
43
45
 
46
+ When the step has no `model` override and the account's `adminModel` cannot be read, MCP stderr emits `[llm-call] adminModel resolution FAILED: reason=<code> path=<file> error=<msg>` naming the exact failure mode (`enoent`, `eacces`, `fs_error`, `parse_error`, `field_missing`, `field_wrong_type`, `field_empty`). The persisted `WorkflowRun.error` cites the same reason code so the admin agent can act without re-running the workflow.
47
+
44
48
  ### Agentic LLM steps
45
49
 
46
50
  An LLM step becomes agentic when `mcpServers` is declared. Instead of a one-shot prompt→response, the LLM can call tools provided by the bound MCP servers across multiple turns — navigating a website, filling a form based on page content, or any task where the next action depends on observing the result of the previous one.
@@ -91,11 +91,34 @@ export interface ProbeResult {
91
91
  * substitution into fallback template `{{_error}}`. */
92
92
  error?: string;
93
93
  }
94
+ /**
95
+ * Why readAdminModel returns a tuple instead of string | null (Task 570):
96
+ * the caller persists the result into WorkflowRun.error, which the admin
97
+ * agent reads. A silent null collapsed six distinct failure modes (ENOENT,
98
+ * EACCES, parse error, missing field, wrong type, empty string) into a
99
+ * single error string asserting "adminModel both unset" — which was often
100
+ * a lie (the file existed and was correct; something else had failed).
101
+ * The tuple surfaces the exact reason so the persisted error and the
102
+ * stderr log agree, and the admin agent knows whether to inspect the
103
+ * file, the permissions, the path, or a concurrent-write race.
104
+ */
105
+ export type AdminModelReason = "ok" | "enoent" | "eacces" | "fs_error" | "parse_error" | "field_missing" | "field_wrong_type" | "field_empty";
106
+ export interface AdminModelResolution {
107
+ /** Model ID when reason is "ok"; null for every failure mode. */
108
+ model: string | null;
109
+ reason: AdminModelReason;
110
+ /** Absolute path attempted — included in failure logs so the operator
111
+ * can inspect the exact file that was read. */
112
+ path: string;
113
+ /** Underlying error message for fs_error and parse_error. */
114
+ error?: string;
115
+ }
94
116
  /**
95
117
  * Read the account's adminModel from account.json.
96
- * Returns the model ID string, or null if the config can't be read.
118
+ * Returns {model, reason, path, error?} callers branch on .model (null
119
+ * means fail) and may surface .reason/.path into user-visible errors.
97
120
  */
98
- export declare function readAdminModel(platformRoot: string, accountId: string): string | null;
121
+ export declare function readAdminModel(platformRoot: string, accountId: string): AdminModelResolution;
99
122
  /**
100
123
  * Execute an LLM call by spawning Claude Code.
101
124
  *
@@ -1 +1 @@
1
- {"version":3,"file":"llm-call.d.ts","sourceRoot":"","sources":["../../src/lib/llm-call.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AAMH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAK1D,UAAU,gBAAgB;IACxB,MAAM,EAAE;QAAE,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAAA;KAAE,CAAC;IACjE,MAAM,EAAE;QAAE,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAAA;KAAE,CAAC;IACjE,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,GAAG,IAAI,CAAC;IAC5D,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI,CAAC;IACnD,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,KAAK,OAAO,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,OAAO,KAAK,gBAAgB,CAAC;AAMhF,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,6CAA6C;IAC7C,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC7C,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,8CAA8C;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iCAAiC;IACjC,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,OAAO,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB;4DACwD;IACxD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAMD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAmBrF;AAiED;;;;;;;;;GASG;AACH,wBAAsB,cAAc,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CA6F3E;AAQD;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,oBAAoB,GAC3B,OAAO,CAAC,WAAW,CAAC,CAyBtB"}
1
+ {"version":3,"file":"llm-call.d.ts","sourceRoot":"","sources":["../../src/lib/llm-call.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AAMH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAK1D,UAAU,gBAAgB;IACxB,MAAM,EAAE;QAAE,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAAA;KAAE,CAAC;IACjE,MAAM,EAAE;QAAE,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAAA;KAAE,CAAC;IACjE,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,GAAG,IAAI,CAAC;IAC5D,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI,CAAC;IACnD,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,KAAK,OAAO,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,OAAO,KAAK,gBAAgB,CAAC;AAMhF,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,6CAA6C;IAC7C,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC7C,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,8CAA8C;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iCAAiC;IACjC,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,OAAO,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB;4DACwD;IACxD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAMD;;;;;;;;;;GAUG;AACH,MAAM,MAAM,gBAAgB,GACxB,IAAI,GACJ,QAAQ,GACR,QAAQ,GACR,UAAU,GACV,aAAa,GACb,eAAe,GACf,kBAAkB,GAClB,aAAa,CAAC;AAElB,MAAM,WAAW,oBAAoB;IACnC,iEAAiE;IACjE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,EAAE,gBAAgB,CAAC;IACzB;oDACgD;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,6DAA6D;IAC7D,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,oBAAoB,CAgD5F;AAsED;;;;;;;;;GASG;AACH,wBAAsB,cAAc,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CA6F3E;AAQD;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,oBAAoB,GAC3B,OAAO,CAAC,WAAW,CAAC,CAyBtB"}
@@ -53,12 +53,10 @@ import { spawn as realSpawn } from "node:child_process";
53
53
  import { readFileSync, writeFileSync, rmSync, mkdtempSync } from "node:fs";
54
54
  import { resolve, join } from "node:path";
55
55
  import { tmpdir } from "node:os";
56
- // ─────────────────────────────────────────────────────────────
57
- // Account config reading
58
- // ─────────────────────────────────────────────────────────────
59
56
  /**
60
57
  * Read the account's adminModel from account.json.
61
- * Returns the model ID string, or null if the config can't be read.
58
+ * Returns {model, reason, path, error?} callers branch on .model (null
59
+ * means fail) and may surface .reason/.path into user-visible errors.
62
60
  */
63
61
  export function readAdminModel(platformRoot, accountId) {
64
62
  // Validate accountId — block path traversal
@@ -66,18 +64,48 @@ export function readAdminModel(platformRoot, accountId) {
66
64
  throw new Error(`Invalid accountId: "${accountId}" — path traversal blocked`);
67
65
  }
68
66
  const configPath = resolve(platformRoot, "..", "data", "accounts", accountId, "account.json");
67
+ let raw;
69
68
  try {
70
- const raw = readFileSync(configPath, "utf-8");
71
- const config = JSON.parse(raw);
72
- const adminModel = config.adminModel;
73
- if (typeof adminModel === "string" && adminModel) {
74
- return adminModel;
75
- }
76
- return null;
69
+ raw = readFileSync(configPath, "utf-8");
70
+ }
71
+ catch (err) {
72
+ const code = err instanceof Error && "code" in err
73
+ ? err.code
74
+ : undefined;
75
+ const message = err instanceof Error ? err.message : String(err);
76
+ const reason = code === "ENOENT" ? "enoent" :
77
+ code === "EACCES" ? "eacces" :
78
+ "fs_error";
79
+ logResolutionFailure(reason, configPath, message);
80
+ return { model: null, reason, path: configPath, error: message };
81
+ }
82
+ let config;
83
+ try {
84
+ config = JSON.parse(raw);
85
+ }
86
+ catch (err) {
87
+ const message = err instanceof Error ? err.message : String(err);
88
+ logResolutionFailure("parse_error", configPath, message);
89
+ return { model: null, reason: "parse_error", path: configPath, error: message };
77
90
  }
78
- catch {
79
- return null;
91
+ const adminModel = config.adminModel;
92
+ if (adminModel === undefined) {
93
+ logResolutionFailure("field_missing", configPath);
94
+ return { model: null, reason: "field_missing", path: configPath };
80
95
  }
96
+ if (typeof adminModel !== "string") {
97
+ logResolutionFailure("field_wrong_type", configPath, `adminModel is typeof ${typeof adminModel}`);
98
+ return { model: null, reason: "field_wrong_type", path: configPath };
99
+ }
100
+ if (adminModel === "") {
101
+ logResolutionFailure("field_empty", configPath);
102
+ return { model: null, reason: "field_empty", path: configPath };
103
+ }
104
+ return { model: adminModel, reason: "ok", path: configPath };
105
+ }
106
+ function logResolutionFailure(reason, path, error) {
107
+ const errSegment = error ? ` error=${error}` : "";
108
+ console.error(`[llm-call] adminModel resolution FAILED: reason=${reason} path=${path}${errSegment}`);
81
109
  }
82
110
  // ─────────────────────────────────────────────────────────────
83
111
  // Temp MCP config management
@@ -1 +1 @@
1
- {"version":3,"file":"llm-call.js","sourceRoot":"","sources":["../../src/lib/llm-call.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AAEH,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAC3E,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAoDjC,gEAAgE;AAChE,yBAAyB;AACzB,gEAAgE;AAEhE;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,YAAoB,EAAE,SAAiB;IACpE,4CAA4C;IAC5C,IAAI,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACpF,MAAM,IAAI,KAAK,CAAC,uBAAuB,SAAS,4BAA4B,CAAC,CAAC;IAChF,CAAC;IAED,MAAM,UAAU,GAAG,OAAO,CAAC,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,cAAc,CAAC,CAAC;IAE9F,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QAC9C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAA4B,CAAC;QAC1D,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;QACrC,IAAI,OAAO,UAAU,KAAK,QAAQ,IAAI,UAAU,EAAE,CAAC;YACjD,OAAO,UAAU,CAAC;QACpB,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,gEAAgE;AAChE,6BAA6B;AAC7B,gEAAgE;AAEhE;;;;;;;;GAQG;AACH,SAAS,kBAAkB,CAAC,UAA2C;IACrE,MAAM,GAAG,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,WAAW,CAAC,CAAC,CAAC;IACrD,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;IACzC,MAAM,MAAM,GAAG,EAAE,UAAU,EAAE,CAAC;IAE9B,IAAI,CAAC;QACH,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC;QAC3D,OAAO,CAAC,KAAK,CAAC,2CAA2C,UAAU,EAAE,CAAC,CAAC;QACvE,OAAO,UAAU,CAAC;IACpB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,+CAA+C;QAC/C,IAAI,CAAC;YAAC,MAAM,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,iBAAiB,CAAC,CAAC;QACrE,MAAM,IAAI,KAAK,CACb,gDAAgD,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CACnG,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,SAAS,oBAAoB,CAAC,UAAkB;IAC9C,IAAI,CAAC;QACH,0EAA0E;QAC1E,MAAM,GAAG,GAAG,OAAO,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QACtC,MAAM,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACjC,OAAO,CAAC,KAAK,CAAC,0CAA0C,UAAU,EAAE,CAAC,CAAC;IACxE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,0DAA0D;QAC1D,IAAI,GAAG,YAAY,KAAK,IAAI,MAAM,IAAI,GAAG,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC9F,OAAO;QACT,CAAC;QACD,OAAO,CAAC,KAAK,CACX,0CAA0C,UAAU,KAAK,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAC5G,CAAC;IACJ,CAAC;AACH,CAAC;AAED,gEAAgE;AAChE,sCAAsC;AACtC,gEAAgE;AAEhE,8EAA8E;AAC9E,MAAM,gBAAgB,GAAG,IAAI,CAAC;AAE9B,4EAA4E;AAC5E,MAAM,yBAAyB,GAAG,EAAE,CAAC;AAErC;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,MAAqB;IACxD,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC;IAClE,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,IAAK,SAAgC,CAAC;IAEjE,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CAAC,8DAA8D,CAAC,CAAC;IAClF,CAAC;IAED,MAAM,SAAS,GAAG,UAAU,KAAK,SAAS,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;IACjF,MAAM,iBAAiB,GAAG,SAAS;QACjC,CAAC,CAAC,CAAC,QAAQ,IAAI,yBAAyB,CAAC;QACzC,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAC;IAEpB,MAAM,WAAW,GAAG,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC7D,OAAO,CAAC,KAAK,CACX,0CAA0C,KAAK,aAAa,iBAAiB,EAAE;QAC/E,CAAC,SAAS,CAAC,CAAC,CAAC,gBAAgB,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAC5D,CAAC;IAEF,iEAAiE;IACjE,IAAI,cAAkC,CAAC;IACvC,IAAI,SAAS,EAAE,CAAC;QACd,cAAc,GAAG,kBAAkB,CAAC,UAAU,CAAC,CAAC;IAClD,CAAC;IAED,MAAM,IAAI,GAAG;QACX,SAAS;QACT,SAAS,EAAE,KAAK;QAChB,aAAa,EAAE,MAAM,CAAC,iBAAiB,CAAC;QACxC,mBAAmB,EAAE,SAAS;KAC/B,CAAC;IAEF,IAAI,cAAc,EAAE,CAAC;QACnB,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,cAAc,EAAE,qBAAqB,CAAC,CAAC;IACnE,CAAC;IAED,yCAAyC;IACzC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAElB,IAAI,CAAC;QACH,OAAO,MAAM,IAAI,OAAO,CAAS,CAAC,cAAc,EAAE,MAAM,EAAE,EAAE;YAC1D,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,EAAE,IAAI,EAAE;gBACjC,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;aAClC,CAAC,CAAC;YAEH,IAAI,MAAM,GAAG,EAAE,CAAC;YAChB,IAAI,MAAM,GAAG,EAAE,CAAC;YAEhB,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;gBACvC,MAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YACpC,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;gBACvC,IAAI,MAAM,CAAC,MAAM,GAAG,gBAAgB,EAAE,CAAC;oBACrC,MAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,gBAAgB,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;gBAC/E,CAAC;YACH,CAAC,CAAC,CAAC;YAEH,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;gBAC5B,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBACrB,MAAM,CAAC,IAAI,KAAK,CAAC,4BAA4B,SAAS,IAAI,CAAC,CAAC,CAAC;YAC/D,CAAC,EAAE,SAAS,CAAC,CAAC;YAEd,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;gBACxB,YAAY,CAAC,KAAK,CAAC,CAAC;gBACpB,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;oBACf,MAAM,aAAa,GAAG,MAAM,CAAC,CAAC,CAAC,aAAa,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBACjE,MAAM,aAAa,GAAG,MAAM;wBAC1B,CAAC,CAAC,aAAa,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,gBAAgB,CAAC,CAAC,IAAI,EAAE,EAAE;wBACzD,CAAC,CAAC,EAAE,CAAC;oBACP,MAAM,CAAC,IAAI,KAAK,CACd,gCAAgC,IAAI,GAAG,aAAa,GAAG,aAAa,EAAE,CACvE,CAAC,CAAC;oBACH,OAAO;gBACT,CAAC;gBACD,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;oBACnB,MAAM,CAAC,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC,CAAC;oBAC7D,OAAO;gBACT,CAAC;gBACD,OAAO,CAAC,KAAK,CAAC,wBAAwB,MAAM,CAAC,MAAM,QAAQ,CAAC,CAAC;gBAC7D,cAAc,CAAC,MAAM,CAAC,CAAC;YACzB,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;gBACvB,YAAY,CAAC,KAAK,CAAC,CAAC;gBACpB,MAAM,CAAC,IAAI,KAAK,CAAC,gCAAgC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;YACnE,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;YAAS,CAAC;QACT,IAAI,cAAc,EAAE,CAAC;YACnB,oBAAoB,CAAC,cAAc,CAAC,CAAC;QACvC,CAAC;IACH,CAAC;AACH,CAAC;AAED,gEAAgE;AAChE,oEAAoE;AACpE,gEAAgE;AAEhE,MAAM,wBAAwB,GAAG,MAAM,CAAC;AAExC;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,MAA4B;IAE5B,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,wBAAwB,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;IACvE,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAEzB,OAAO,CAAC,KAAK,CAAC,8BAA8B,KAAK,EAAE,CAAC,CAAC;IAErD,IAAI,CAAC;QACH,MAAM,cAAc,CAAC;YACnB,MAAM,EAAE,MAAM;YACd,KAAK;YACL,SAAS,EAAE,CAAC;YACZ,SAAS;YACT,MAAM;SACP,CAAC,CAAC;QACH,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;QACrC,OAAO,CAAC,KAAK,CAAC,6BAA6B,SAAS,EAAE,CAAC,CAAC;QACxD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;IACjC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;QACrC,MAAM,KAAK,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC/D,4EAA4E;QAC5E,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;QAClD,OAAO,CAAC,KAAK,CAAC,uBAAuB,OAAO,cAAc,SAAS,EAAE,CAAC,CAAC;QACvE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;IAClD,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"llm-call.js","sourceRoot":"","sources":["../../src/lib/llm-call.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"workflow-execute.d.ts","sourceRoot":"","sources":["../../src/tools/workflow-execute.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAoBH,MAAM,WAAW,qBAAqB;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,OAAO,CAAC,EAAE,gBAAgB,GAAG,UAAU,GAAG,QAAQ,CAAC;CACpD;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,WAAW,GAAG,SAAS,GAAG,QAAQ,CAAC;IAC3C,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAwGD,wBAAsB,eAAe,CACnC,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC,CA2bhC"}
1
+ {"version":3,"file":"workflow-execute.d.ts","sourceRoot":"","sources":["../../src/tools/workflow-execute.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAoBH,MAAM,WAAW,qBAAqB;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,OAAO,CAAC,EAAE,gBAAgB,GAAG,UAAU,GAAG,QAAQ,CAAC;CACpD;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,WAAW,GAAG,SAAS,GAAG,QAAQ,CAAC;IAC3C,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAwGD,wBAAsB,eAAe,CACnC,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC,CAuchC"}
@@ -225,8 +225,10 @@ export async function workflowExecute(params) {
225
225
  if (llmStep) {
226
226
  let probeModel = llmStep.model;
227
227
  const probeModelSource = probeModel ? "step override" : "adminModel";
228
+ let adminModelResolution;
228
229
  if (!probeModel) {
229
- probeModel = readAdminModel(platformRoot, accountId) ?? undefined;
230
+ adminModelResolution = readAdminModel(platformRoot, accountId);
231
+ probeModel = adminModelResolution.model ?? undefined;
230
232
  }
231
233
  if (probeModel) {
232
234
  console.error(`[llm-call] model resolved: ${probeModel} (source: ${probeModelSource})`);
@@ -238,8 +240,13 @@ export async function workflowExecute(params) {
238
240
  // throw would escape the inner spawn-catch and bypass the
239
241
  // documented degradation guarantee.
240
242
  llmAvailable = false;
241
- probeError =
242
- "No model configured (step-level override and account adminModel both unset)";
243
+ // Task 570: cite the exact reason from readAdminModel so the
244
+ // persisted WorkflowRun.error and the stderr log agree, and the
245
+ // admin agent knows whether the file, permissions, or content is
246
+ // at fault.
247
+ probeError = adminModelResolution
248
+ ? `No model configured: step override absent and readAdminModel returned null (reason=${adminModelResolution.reason}, path=${adminModelResolution.path}) — see stderr for details`
249
+ : "No model configured (step override absent and readAdminModel was not invoked)";
243
250
  console.error(`[llm-probe] FAILED: ${probeError}`);
244
251
  }
245
252
  else {
@@ -376,12 +383,17 @@ export async function workflowExecute(params) {
376
383
  // Resolve model: step-level override → account adminModel → throw
377
384
  let model = step.model;
378
385
  const modelSource = model ? "step override" : "adminModel";
386
+ let stepAdminResolution;
379
387
  if (!model) {
380
- model = readAdminModel(platformRoot, accountId) ?? undefined;
388
+ stepAdminResolution = readAdminModel(platformRoot, accountId);
389
+ model = stepAdminResolution.model ?? undefined;
381
390
  }
382
391
  if (!model) {
383
- throw new Error("No model specified on LLM step and account adminModel is not configured. " +
384
- "Either set a model on the step or configure adminModel in account settings.");
392
+ // Task 570: cite reason + path so the persisted error matches
393
+ // the stderr log instead of a pre-written assumption.
394
+ throw new Error(stepAdminResolution
395
+ ? `No model specified on LLM step and readAdminModel returned null (reason=${stepAdminResolution.reason}, path=${stepAdminResolution.path}) — see stderr for details`
396
+ : "No model specified on LLM step and readAdminModel was not invoked");
385
397
  }
386
398
  console.error(`[llm-call] model resolved: ${model} (source: ${modelSource})`);
387
399
  const stepTimeoutMs = (step.timeout ?? DEFAULT_LLM_TIMEOUT_S) * 1000;