@blinkk/root-cms 3.0.1-beta.2 → 3.0.1-beta.3
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/app.js +1 -1
- package/dist/{chunk-ATPWU3CU.js → chunk-NXEXOHBD.js} +68 -7
- package/dist/plugin.js +5 -2
- package/dist/ui/ui.css +1 -1
- package/dist/ui/ui.js +196 -164
- package/package.json +3 -3
package/dist/app.js
CHANGED
|
@@ -99,10 +99,12 @@ function createCmsTools() {
|
|
|
99
99
|
})
|
|
100
100
|
}),
|
|
101
101
|
doc_updateField: tool({
|
|
102
|
-
description: 'Update a single field on a draft CMS document by JSON path. Use dotted paths (e.g. "hero.title") and array indices (e.g. "
|
|
102
|
+
description: 'Update a single field on a draft CMS document by JSON path. Paths are relative to the doc fields object; do not prefix them with "fields.". Use dotted paths (e.g. "hero.title") and zero-based array indices. For example, update the first module title with path "content.modules.0.title". To append or remove array items, first read the current doc, then set the whole array path (e.g. "content.modules") to the updated array. The value is validated against the field schema and the call is rejected if the shape is wrong (e.g. passing a string to a richtext field). Only updates the draft version; users must publish separately. Always confirm with the user before calling.',
|
|
103
103
|
inputSchema: z.object({
|
|
104
104
|
docId: z.string(),
|
|
105
|
-
path: z.string().describe(
|
|
105
|
+
path: z.string().describe(
|
|
106
|
+
'Dotted JSON path within the fields object, e.g. "content.modules.0.title".'
|
|
107
|
+
),
|
|
106
108
|
value: z.any().describe("JSON value to set at the path.")
|
|
107
109
|
})
|
|
108
110
|
}),
|
|
@@ -272,6 +274,12 @@ function findImageModel(config, modelId) {
|
|
|
272
274
|
const defaultId = config.defaultImageModel || imageModels[0]?.id;
|
|
273
275
|
return imageModels.find((m) => m.id === defaultId) || null;
|
|
274
276
|
}
|
|
277
|
+
function normalizeExecutionMode(value) {
|
|
278
|
+
if (value === "read" || value === "suggest" || value === "approve" || value === "auto") {
|
|
279
|
+
return value;
|
|
280
|
+
}
|
|
281
|
+
return "approve";
|
|
282
|
+
}
|
|
275
283
|
function requireDefaultModel(rootConfig) {
|
|
276
284
|
const config = getAiConfig(rootConfig);
|
|
277
285
|
if (!config) {
|
|
@@ -416,10 +424,59 @@ async function generateChatTitle(model, messages) {
|
|
|
416
424
|
}
|
|
417
425
|
return fallback;
|
|
418
426
|
}
|
|
427
|
+
function buildExecutionModePrompt(mode) {
|
|
428
|
+
const common = [
|
|
429
|
+
"Root AI execution workflow:",
|
|
430
|
+
"- For content-changing tasks, first gather the relevant context with read tools.",
|
|
431
|
+
"- Before the first write, briefly state a plan that names the target docs, fields, intended changes, assumptions, and validation checks.",
|
|
432
|
+
"- Never claim a draft change was applied until the matching tool output reports success.",
|
|
433
|
+
"- After write tools finish, provide a short receipt with changed docs, changed fields, validation result, and a reminder that publishing remains manual."
|
|
434
|
+
];
|
|
435
|
+
if (mode === "read") {
|
|
436
|
+
common.push(
|
|
437
|
+
"",
|
|
438
|
+
"Current execution mode: Read only.",
|
|
439
|
+
"- You only have read-only CMS tools.",
|
|
440
|
+
"- Do not propose tool writes or ask for approval to write. Answer from the context you can read."
|
|
441
|
+
);
|
|
442
|
+
} else if (mode === "suggest") {
|
|
443
|
+
common.push(
|
|
444
|
+
"",
|
|
445
|
+
"Current execution mode: Suggest changes.",
|
|
446
|
+
"- You only have read-only CMS tools.",
|
|
447
|
+
"- Do not call write tools. Provide proposed edits, field paths, and rationale for the user to review."
|
|
448
|
+
);
|
|
449
|
+
} else if (mode === "approve") {
|
|
450
|
+
common.push(
|
|
451
|
+
"",
|
|
452
|
+
"Current execution mode: Ask before writing.",
|
|
453
|
+
"- Write tools are available, but the UI will pause each draft write for user approval with a diff.",
|
|
454
|
+
"- Call write tools only after you have enough context to make a specific, reviewable change.",
|
|
455
|
+
"- If the user rejects a write, revise the plan instead of retrying the same write."
|
|
456
|
+
);
|
|
457
|
+
} else {
|
|
458
|
+
common.push(
|
|
459
|
+
"",
|
|
460
|
+
"Current execution mode: Auto-apply draft edits.",
|
|
461
|
+
"- Draft-only write tools may run without an approval pause.",
|
|
462
|
+
"- Keep edits narrowly scoped to the user request and summarize the exact draft changes afterward."
|
|
463
|
+
);
|
|
464
|
+
}
|
|
465
|
+
return common.join("\n");
|
|
466
|
+
}
|
|
419
467
|
async function runChatStream(options) {
|
|
420
|
-
const {
|
|
468
|
+
const {
|
|
469
|
+
rootConfig,
|
|
470
|
+
model,
|
|
471
|
+
config,
|
|
472
|
+
messages,
|
|
473
|
+
cmsClient,
|
|
474
|
+
user,
|
|
475
|
+
chatId,
|
|
476
|
+
executionMode = "approve"
|
|
477
|
+
} = options;
|
|
421
478
|
const languageModel = resolveLanguageModel(model);
|
|
422
|
-
const tools = model.capabilities?.tools === false ? {} : createCmsTools();
|
|
479
|
+
const tools = model.capabilities?.tools === false ? {} : executionMode === "read" || executionMode === "suggest" ? createReadOnlyCmsTools() : createCmsTools();
|
|
423
480
|
const basePrompt = config.systemPrompt || [
|
|
424
481
|
"You are an assistant embedded in the Root CMS admin UI.",
|
|
425
482
|
"Help the user explore and edit content, answer questions about",
|
|
@@ -427,7 +484,10 @@ async function runChatStream(options) {
|
|
|
427
484
|
"Be concise and use markdown for rich responses."
|
|
428
485
|
].join(" ");
|
|
429
486
|
const rootMd = await readRootMd(rootConfig.rootDir);
|
|
430
|
-
const systemPrompt = buildSystemPrompt(
|
|
487
|
+
const systemPrompt = buildSystemPrompt(
|
|
488
|
+
[basePrompt, "", buildExecutionModePrompt(executionMode)].join("\n"),
|
|
489
|
+
rootMd
|
|
490
|
+
);
|
|
431
491
|
const modelMessages = await convertToModelMessages(messages, { tools });
|
|
432
492
|
const result = streamText({
|
|
433
493
|
model: languageModel,
|
|
@@ -716,7 +776,7 @@ function extractJsonFromResponse(responseText) {
|
|
|
716
776
|
// package.json
|
|
717
777
|
var package_default = {
|
|
718
778
|
name: "@blinkk/root-cms",
|
|
719
|
-
version: "3.0.1-beta.
|
|
779
|
+
version: "3.0.1-beta.3",
|
|
720
780
|
author: "s@blinkk.com",
|
|
721
781
|
license: "MIT",
|
|
722
782
|
engines: {
|
|
@@ -885,7 +945,7 @@ var package_default = {
|
|
|
885
945
|
yjs: "13.6.27"
|
|
886
946
|
},
|
|
887
947
|
peerDependencies: {
|
|
888
|
-
"@blinkk/root": "3.0.1-beta.
|
|
948
|
+
"@blinkk/root": "3.0.1-beta.3",
|
|
889
949
|
"firebase-admin": ">=11",
|
|
890
950
|
"firebase-functions": ">=4"
|
|
891
951
|
},
|
|
@@ -909,6 +969,7 @@ export {
|
|
|
909
969
|
serializeAiConfig,
|
|
910
970
|
getAiConfig,
|
|
911
971
|
findModel,
|
|
972
|
+
normalizeExecutionMode,
|
|
912
973
|
ChatStore,
|
|
913
974
|
runChatStream,
|
|
914
975
|
runEditObjectStream,
|
package/dist/plugin.js
CHANGED
|
@@ -6,12 +6,13 @@ import {
|
|
|
6
6
|
generatePublishMessage,
|
|
7
7
|
getAiConfig,
|
|
8
8
|
getServerVersion,
|
|
9
|
+
normalizeExecutionMode,
|
|
9
10
|
runChatStream,
|
|
10
11
|
runEditObjectStream,
|
|
11
12
|
serializeAiConfig,
|
|
12
13
|
summarizeDiff,
|
|
13
14
|
translateString
|
|
14
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-NXEXOHBD.js";
|
|
15
16
|
import {
|
|
16
17
|
SearchIndexService,
|
|
17
18
|
runCronJobs
|
|
@@ -555,6 +556,7 @@ function api(server, options) {
|
|
|
555
556
|
res.status(400).json({ success: false, error: "UNKNOWN_MODEL" });
|
|
556
557
|
return;
|
|
557
558
|
}
|
|
559
|
+
const executionMode = normalizeExecutionMode(body.executionMode);
|
|
558
560
|
const cmsClient = new RootCMSClient(req.rootConfig);
|
|
559
561
|
const store = new ChatStore(cmsClient, req.user.email);
|
|
560
562
|
const requestedChatId = typeof body.chatId === "string" ? body.chatId.trim() : "";
|
|
@@ -582,7 +584,8 @@ function api(server, options) {
|
|
|
582
584
|
model,
|
|
583
585
|
messages,
|
|
584
586
|
chatId,
|
|
585
|
-
user: req.user.email
|
|
587
|
+
user: req.user.email,
|
|
588
|
+
executionMode
|
|
586
589
|
});
|
|
587
590
|
streamResponse.headers.set("x-root-cms-chat-id", chatId);
|
|
588
591
|
await pipeWebResponse(streamResponse, res);
|