@avocadostudio-ai/orchestrator-core 0.1.0
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/LICENSE +201 -0
- package/dist/agent/agent-context.d.ts +19 -0
- package/dist/agent/agent-context.js +67 -0
- package/dist/agent/agent-logger.d.ts +5 -0
- package/dist/agent/agent-logger.js +22 -0
- package/dist/agent/agent-loop-openai.d.ts +8 -0
- package/dist/agent/agent-loop-openai.js +172 -0
- package/dist/agent/agent-loop.d.ts +56 -0
- package/dist/agent/agent-loop.js +167 -0
- package/dist/agent/agent-provider.d.ts +28 -0
- package/dist/agent/agent-provider.js +63 -0
- package/dist/agent/agent-tools.d.ts +28 -0
- package/dist/agent/agent-tools.js +899 -0
- package/dist/agent/context/editing-guidelines.md +46 -0
- package/dist/agent/context/role.md +39 -0
- package/dist/agent/integration-prompt.d.ts +9 -0
- package/dist/agent/integration-prompt.js +154 -0
- package/dist/agent/sites-agent-context.d.ts +12 -0
- package/dist/agent/sites-agent-context.js +316 -0
- package/dist/agent/sites-agent-shared.d.ts +161 -0
- package/dist/agent/sites-agent-shared.js +1101 -0
- package/dist/agent/sites-agent-tools.d.ts +18 -0
- package/dist/agent/sites-agent-tools.js +1227 -0
- package/dist/chat/anthropic-cache.d.ts +20 -0
- package/dist/chat/anthropic-cache.js +54 -0
- package/dist/chat/anthropic-planner.d.ts +98 -0
- package/dist/chat/anthropic-planner.js +1012 -0
- package/dist/chat/changelog-coverage-validator.d.ts +37 -0
- package/dist/chat/changelog-coverage-validator.js +215 -0
- package/dist/chat/chat-pipeline-context.d.ts +211 -0
- package/dist/chat/chat-pipeline-context.js +249 -0
- package/dist/chat/chat-pipeline-deterministic.d.ts +61 -0
- package/dist/chat/chat-pipeline-deterministic.js +407 -0
- package/dist/chat/chat-pipeline-image.d.ts +86 -0
- package/dist/chat/chat-pipeline-image.js +897 -0
- package/dist/chat/chat-pipeline-shared.d.ts +69 -0
- package/dist/chat/chat-pipeline-shared.js +212 -0
- package/dist/chat/chat-pipeline-translation.d.ts +27 -0
- package/dist/chat/chat-pipeline-translation.js +417 -0
- package/dist/chat/chat-pipeline-ui.d.ts +14 -0
- package/dist/chat/chat-pipeline-ui.js +244 -0
- package/dist/chat/chat-pipeline.d.ts +99 -0
- package/dist/chat/chat-pipeline.js +3999 -0
- package/dist/chat/decomposer.d.ts +21 -0
- package/dist/chat/decomposer.js +65 -0
- package/dist/chat/gemini-planner.d.ts +70 -0
- package/dist/chat/gemini-planner.js +541 -0
- package/dist/chat/hallucination-validator.d.ts +36 -0
- package/dist/chat/hallucination-validator.js +110 -0
- package/dist/chat/locale-strings.d.ts +47 -0
- package/dist/chat/locale-strings.js +100 -0
- package/dist/chat/plan-json-schema.d.ts +133 -0
- package/dist/chat/plan-json-schema.js +112 -0
- package/dist/chat/planner-types.d.ts +120 -0
- package/dist/chat/planner-types.js +66 -0
- package/dist/chat/planner.d.ts +148 -0
- package/dist/chat/planner.js +1361 -0
- package/dist/chat/prompts.d.ts +67 -0
- package/dist/chat/prompts.js +356 -0
- package/dist/chat/provider-routing.d.ts +14 -0
- package/dist/chat/provider-routing.js +27 -0
- package/dist/chat/variation-pipeline.d.ts +135 -0
- package/dist/chat/variation-pipeline.js +837 -0
- package/dist/chat/vision-alt-generator.d.ts +35 -0
- package/dist/chat/vision-alt-generator.js +152 -0
- package/dist/cms/adapter.d.ts +62 -0
- package/dist/cms/adapter.js +1 -0
- package/dist/cms/bootstrap.d.ts +17 -0
- package/dist/cms/bootstrap.js +85 -0
- package/dist/cms/editor-api-adapter.d.ts +23 -0
- package/dist/cms/editor-api-adapter.js +71 -0
- package/dist/cms/index.d.ts +4 -0
- package/dist/cms/index.js +3 -0
- package/dist/cms/json-file-adapter.d.ts +11 -0
- package/dist/cms/json-file-adapter.js +62 -0
- package/dist/demo-mode.d.ts +59 -0
- package/dist/demo-mode.js +201 -0
- package/dist/errors.d.ts +67 -0
- package/dist/errors.js +129 -0
- package/dist/http/chat-stream-resumable.d.ts +108 -0
- package/dist/http/chat-stream-resumable.js +290 -0
- package/dist/http/chat-stream.d.ts +99 -0
- package/dist/http/chat-stream.js +92 -0
- package/dist/image/gdrive-client.d.ts +22 -0
- package/dist/image/gdrive-client.js +215 -0
- package/dist/image/image-helpers.d.ts +95 -0
- package/dist/image/image-helpers.js +488 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/jira/jira-approval.d.ts +22 -0
- package/dist/jira/jira-approval.js +51 -0
- package/dist/jira/jira-client.d.ts +44 -0
- package/dist/jira/jira-client.js +313 -0
- package/dist/jira/jira-poller.d.ts +46 -0
- package/dist/jira/jira-poller.js +184 -0
- package/dist/jira/jira-processor.d.ts +103 -0
- package/dist/jira/jira-processor.js +1085 -0
- package/dist/jira/jira-types.d.ts +117 -0
- package/dist/jira/jira-types.js +38 -0
- package/dist/logger.d.ts +12 -0
- package/dist/logger.js +28 -0
- package/dist/migration/mcp-server-stdio.d.ts +8 -0
- package/dist/migration/mcp-server-stdio.js +672 -0
- package/dist/migration/migration-prompt.d.ts +7 -0
- package/dist/migration/migration-prompt.js +197 -0
- package/dist/migration/migration-tools.d.ts +17 -0
- package/dist/migration/migration-tools.js +159 -0
- package/dist/migration/scrape-cache.d.ts +9 -0
- package/dist/migration/scrape-cache.js +19 -0
- package/dist/nlp/deterministic-planner-context.d.ts +141 -0
- package/dist/nlp/deterministic-planner-context.js +362 -0
- package/dist/nlp/deterministic-planner-pages.d.ts +26 -0
- package/dist/nlp/deterministic-planner-pages.js +170 -0
- package/dist/nlp/deterministic-planner-patches.d.ts +80 -0
- package/dist/nlp/deterministic-planner-patches.js +508 -0
- package/dist/nlp/deterministic-planner-refs.d.ts +33 -0
- package/dist/nlp/deterministic-planner-refs.js +164 -0
- package/dist/nlp/deterministic-planner-suggestions.d.ts +49 -0
- package/dist/nlp/deterministic-planner-suggestions.js +579 -0
- package/dist/nlp/deterministic-planner.d.ts +85 -0
- package/dist/nlp/deterministic-planner.js +1631 -0
- package/dist/nlp/intent-detection.d.ts +309 -0
- package/dist/nlp/intent-detection.js +730 -0
- package/dist/nlp/intent-helpers.d.ts +15 -0
- package/dist/nlp/intent-helpers.js +243 -0
- package/dist/nlp/intent-patterns.d.ts +40 -0
- package/dist/nlp/intent-patterns.js +223 -0
- package/dist/nlp/plan-normalizer.d.ts +41 -0
- package/dist/nlp/plan-normalizer.js +1537 -0
- package/dist/ops/destructive-action-gate.d.ts +44 -0
- package/dist/ops/destructive-action-gate.js +90 -0
- package/dist/ops/ops-engine.d.ts +151 -0
- package/dist/ops/ops-engine.js +1394 -0
- package/dist/publish/diff-engine.d.ts +18 -0
- package/dist/publish/diff-engine.js +305 -0
- package/dist/publish/publish-helpers.d.ts +87 -0
- package/dist/publish/publish-helpers.js +521 -0
- package/dist/publish/publish-target-registry.d.ts +7 -0
- package/dist/publish/publish-target-registry.js +61 -0
- package/dist/publish/publish-target.d.ts +81 -0
- package/dist/publish/publish-target.js +1 -0
- package/dist/publish/targets/deploy-hook.d.ts +13 -0
- package/dist/publish/targets/deploy-hook.js +123 -0
- package/dist/publish/targets/git.d.ts +13 -0
- package/dist/publish/targets/git.js +55 -0
- package/dist/publish/targets/site-contract.d.ts +19 -0
- package/dist/publish/targets/site-contract.js +124 -0
- package/dist/state/content-source.d.ts +17 -0
- package/dist/state/content-source.js +1 -0
- package/dist/state/in-memory-content-source.d.ts +27 -0
- package/dist/state/in-memory-content-source.js +51 -0
- package/dist/state/session-lock.d.ts +13 -0
- package/dist/state/session-lock.js +29 -0
- package/dist/state/session-state.d.ts +310 -0
- package/dist/state/session-state.js +1083 -0
- package/dist/state/sqlite-store-singleton.d.ts +31 -0
- package/dist/state/sqlite-store-singleton.js +170 -0
- package/dist/state/sqlite-store.d.ts +135 -0
- package/dist/state/sqlite-store.js +421 -0
- package/dist/telemetry/chat-telemetry.d.ts +105 -0
- package/dist/telemetry/chat-telemetry.js +247 -0
- package/dist/telemetry/eval-candidate-store.d.ts +50 -0
- package/dist/telemetry/eval-candidate-store.js +120 -0
- package/dist/telemetry/feedback-store.d.ts +34 -0
- package/dist/telemetry/feedback-store.js +76 -0
- package/dist/telemetry/jira-telemetry.d.ts +57 -0
- package/dist/telemetry/jira-telemetry.js +68 -0
- package/dist/telemetry/migration-telemetry.d.ts +35 -0
- package/dist/telemetry/migration-telemetry.js +40 -0
- package/dist/telemetry/usage.d.ts +24 -0
- package/dist/telemetry/usage.js +80 -0
- package/dist/tools/builtin-registrations.d.ts +12 -0
- package/dist/tools/builtin-registrations.js +33 -0
- package/dist/tools/builtins/gdrive-browse.d.ts +3 -0
- package/dist/tools/builtins/gdrive-browse.js +68 -0
- package/dist/tools/builtins/image-generate.d.ts +3 -0
- package/dist/tools/builtins/image-generate.js +211 -0
- package/dist/tools/builtins/unsplash-get-by-id.d.ts +23 -0
- package/dist/tools/builtins/unsplash-get-by-id.js +119 -0
- package/dist/tools/builtins/unsplash-search.d.ts +3 -0
- package/dist/tools/builtins/unsplash-search.js +74 -0
- package/dist/tools/executor.d.ts +23 -0
- package/dist/tools/executor.js +169 -0
- package/dist/tools/index.d.ts +5 -0
- package/dist/tools/index.js +5 -0
- package/dist/tools/registry.d.ts +21 -0
- package/dist/tools/registry.js +75 -0
- package/dist/tools/runtime.d.ts +27 -0
- package/dist/tools/runtime.js +48 -0
- package/dist/tools/schema-validator.d.ts +24 -0
- package/dist/tools/schema-validator.js +88 -0
- package/dist/tools/types.d.ts +86 -0
- package/dist/tools/types.js +1 -0
- package/dist/variation-images.d.ts +19 -0
- package/dist/variation-images.js +12 -0
- package/package.json +78 -0
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
import { isStandalonePageOperation, requestsContentGeneration } from "../nlp/intent-helpers.js";
|
|
2
|
+
import { inferDeterministicIntent } from "../nlp/deterministic-planner.js";
|
|
3
|
+
import { inferTranslationScopeFromMessage } from "./chat-pipeline-translation.js";
|
|
4
|
+
import { isRewriteLikeMessage } from "./chat-pipeline-deterministic.js";
|
|
5
|
+
import { isRewriteRequest } from "../nlp/deterministic-planner-patches.js";
|
|
6
|
+
function isClarificationFollowUp(message) {
|
|
7
|
+
return message.includes("\nClarification from user:");
|
|
8
|
+
}
|
|
9
|
+
export function shouldPreferFastModelForMessage(message) {
|
|
10
|
+
if (inferTranslationScopeFromMessage(message) !== "none")
|
|
11
|
+
return false;
|
|
12
|
+
if (isStandalonePageOperation(message))
|
|
13
|
+
return false;
|
|
14
|
+
if (isClarificationFollowUp(message))
|
|
15
|
+
return false;
|
|
16
|
+
// Compound multi-field requests (2+ quoted values) need full context, not lightweight mode
|
|
17
|
+
if (isCompoundMultiFieldRequest(message))
|
|
18
|
+
return false;
|
|
19
|
+
if (isRewriteLikeMessage(message))
|
|
20
|
+
return true;
|
|
21
|
+
// Simple targeted prop edits — single-block text/label/emoji modifications
|
|
22
|
+
// don't need the balanced model. Fast is sufficient.
|
|
23
|
+
const lower = message.toLowerCase();
|
|
24
|
+
if (isSingleBlockPropEdit(lower))
|
|
25
|
+
return true;
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
/** Detects compound multi-field requests with 2+ quoted values, e.g.
|
|
29
|
+
* "set subheading to 'X' and change CTA text to 'Y'" */
|
|
30
|
+
function isCompoundMultiFieldRequest(message) {
|
|
31
|
+
const quoteChars = message.match(/['''"""\u201C\u201D\u2018\u2019]/g);
|
|
32
|
+
return !!(quoteChars && quoteChars.length >= 4);
|
|
33
|
+
}
|
|
34
|
+
function isSingleBlockPropEdit(lower) {
|
|
35
|
+
// Action verb + small cosmetic target (emojis, icons, labels, text, links)
|
|
36
|
+
const cosmeticTarget = /\b(emojis?|icons?|labels?|names?|titles?|text|headings?|links?)\b/;
|
|
37
|
+
if (!cosmeticTarget.test(lower))
|
|
38
|
+
return false;
|
|
39
|
+
// Must have a simple action verb — not create/build/generate (which imply complex content)
|
|
40
|
+
return /\b(add|remove|strip|delete|drop|clear|change|update|put|set|replace)\b/.test(lower);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Returns true when the message is complex/ambiguous enough that we should
|
|
44
|
+
* auto-escalate to an Anthropic thinking-capable model with extended thinking
|
|
45
|
+
* enabled. Designed to complement `shouldPreferFastModelForMessage` (which
|
|
46
|
+
* downgrades simple edits) — this one upgrades.
|
|
47
|
+
*
|
|
48
|
+
* Positive signals:
|
|
49
|
+
* - Multi-step / decomposable request
|
|
50
|
+
* - Clarification follow-up (user is correcting an earlier result)
|
|
51
|
+
* - Structural verbs suggesting site-level reasoning (restructure, redesign,
|
|
52
|
+
* reorganize, rewrite tone, convert into, persuasive, narrative)
|
|
53
|
+
* - Long request with multiple quoted values (compound multi-field)
|
|
54
|
+
*/
|
|
55
|
+
export function shouldEnableReasoningForMessage(message) {
|
|
56
|
+
const normalized = message.trim();
|
|
57
|
+
if (normalized.length === 0)
|
|
58
|
+
return false;
|
|
59
|
+
// Strong positive signals (override the fast-model preference)
|
|
60
|
+
if (isClarificationFollowUp(message))
|
|
61
|
+
return true;
|
|
62
|
+
if (isCompoundMultiFieldRequest(message))
|
|
63
|
+
return true;
|
|
64
|
+
const lower = message.toLowerCase();
|
|
65
|
+
const structuralVerbs = /\b(restructure|redesign|reorganize|rethink|reimagine|overhaul|persuasive|narrative|convert\s+into|transform\s+into|tone\s+(of\s+voice|more|less))\b/;
|
|
66
|
+
if (structuralVerbs.test(lower))
|
|
67
|
+
return true;
|
|
68
|
+
// Explicit tone/voice/style directives — these benefit from reasoning even
|
|
69
|
+
// when the message looks like a plain rewrite.
|
|
70
|
+
if (/\b(rewrite|redo|rephrase|adjust)\b.*\b(tone|voice|style|mood|register)\b/.test(lower))
|
|
71
|
+
return true;
|
|
72
|
+
// "rewrite X and Y" / multi-section rewrites
|
|
73
|
+
if (/\b(rewrite|redo)\b/.test(lower) && /\b(and|plus|also)\b/.test(lower))
|
|
74
|
+
return true;
|
|
75
|
+
// Long prompts (> 200 chars) with conditional branching language suggest the
|
|
76
|
+
// user is describing a non-trivial transformation
|
|
77
|
+
if (normalized.length > 200 && /\b(if|when|so\s+that|in\s+order\s+to|but|however|unless)\b/.test(lower))
|
|
78
|
+
return true;
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
export function shouldUseLlmIntentRouter(message) {
|
|
82
|
+
if (inferTranslationScopeFromMessage(message) !== "none")
|
|
83
|
+
return false;
|
|
84
|
+
if (isStandalonePageOperation(message))
|
|
85
|
+
return false;
|
|
86
|
+
if (isClarificationFollowUp(message))
|
|
87
|
+
return false;
|
|
88
|
+
const normalized = message.trim();
|
|
89
|
+
if (normalized.length === 0 || normalized.length > 260)
|
|
90
|
+
return false;
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
export function compactPlannerContextPack(args) {
|
|
94
|
+
if (args.translationScope === "page")
|
|
95
|
+
return args.contextPack;
|
|
96
|
+
const lower = args.message.toLowerCase();
|
|
97
|
+
const keepsFullContext = /\b(create|generate|build|duplicate)\b.*\bpage\b/.test(lower) ||
|
|
98
|
+
/\b(rename|remove|delete|move)\b.*\bpage\b/.test(lower) ||
|
|
99
|
+
/\btranslate\b/.test(lower);
|
|
100
|
+
if (keepsFullContext)
|
|
101
|
+
return args.contextPack;
|
|
102
|
+
const selectedBlockId = String(args.contextPack.selected.blockId ?? "");
|
|
103
|
+
const compactOutline = args.contextPack.pageOutline.map((entry) => {
|
|
104
|
+
if (entry.id === selectedBlockId)
|
|
105
|
+
return entry;
|
|
106
|
+
return {
|
|
107
|
+
id: entry.id,
|
|
108
|
+
type: entry.type,
|
|
109
|
+
props: {},
|
|
110
|
+
arrayProps: entry.arrayProps
|
|
111
|
+
};
|
|
112
|
+
});
|
|
113
|
+
return {
|
|
114
|
+
...args.contextPack,
|
|
115
|
+
pageOutline: compactOutline,
|
|
116
|
+
recentSuccessfulEdits: args.contextPack.recentSuccessfulEdits.slice(-3)
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
export function minimalPlannerContextPack(args) {
|
|
120
|
+
const selectedBlockId = String(args.contextPack.selected.blockId ?? "");
|
|
121
|
+
if (!selectedBlockId)
|
|
122
|
+
return args.contextPack;
|
|
123
|
+
const neighborIds = new Set([args.contextPack.neighbors.previous?.id, args.contextPack.neighbors.next?.id]
|
|
124
|
+
.filter((value) => typeof value === "string" && value.length > 0));
|
|
125
|
+
const compactOutline = args.contextPack.pageOutline
|
|
126
|
+
.filter((entry) => entry.id === selectedBlockId || neighborIds.has(entry.id))
|
|
127
|
+
.map((entry) => {
|
|
128
|
+
if (entry.id === selectedBlockId)
|
|
129
|
+
return entry;
|
|
130
|
+
return {
|
|
131
|
+
id: entry.id,
|
|
132
|
+
type: entry.type,
|
|
133
|
+
props: {},
|
|
134
|
+
arrayProps: entry.arrayProps
|
|
135
|
+
};
|
|
136
|
+
});
|
|
137
|
+
const routeSet = new Set();
|
|
138
|
+
routeSet.add(args.contextPack.route);
|
|
139
|
+
for (const slug of args.contextPack.pageRoutes) {
|
|
140
|
+
if (routeSet.size >= 6)
|
|
141
|
+
break;
|
|
142
|
+
routeSet.add(slug);
|
|
143
|
+
}
|
|
144
|
+
return {
|
|
145
|
+
...args.contextPack,
|
|
146
|
+
pageRoutes: Array.from(routeSet),
|
|
147
|
+
pageOutline: compactOutline,
|
|
148
|
+
recentSuccessfulEdits: args.contextPack.recentSuccessfulEdits.slice(-1),
|
|
149
|
+
// Keep resolvedReferences from full context — small (~50 tokens) but helps LLM
|
|
150
|
+
// target the right block even in minimal mode
|
|
151
|
+
resolvedReferences: args.contextPack.resolvedReferences
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
export function shouldUseMinimalPlannerContext(args) {
|
|
155
|
+
if (args.translationScope !== "none")
|
|
156
|
+
return false;
|
|
157
|
+
if (!args.activeBlockId && !args.activeEditablePath)
|
|
158
|
+
return false;
|
|
159
|
+
if (isStandalonePageOperation(args.message))
|
|
160
|
+
return false;
|
|
161
|
+
const lower = args.message.toLowerCase();
|
|
162
|
+
return (isRewriteLikeMessage(lower) ||
|
|
163
|
+
isSingleBlockPropEdit(lower) ||
|
|
164
|
+
/\b(replace|change|update|set|edit|rewrite|rephrase)\b/.test(lower));
|
|
165
|
+
}
|
|
166
|
+
export function shouldPreferFocusedTranslation(args) {
|
|
167
|
+
if (args.inferredScope !== "page")
|
|
168
|
+
return false;
|
|
169
|
+
if (!args.activeBlockId)
|
|
170
|
+
return false;
|
|
171
|
+
const lower = args.message.toLowerCase();
|
|
172
|
+
const hasExplicitPageCue = /\b(this|the|entire|whole|full)\s+page\b/.test(lower) ||
|
|
173
|
+
/\bwhole\s+site\b/.test(lower) ||
|
|
174
|
+
/\ball\s+sections?\b/.test(lower) ||
|
|
175
|
+
/\btranslate\s+page\b/.test(lower);
|
|
176
|
+
if (hasExplicitPageCue)
|
|
177
|
+
return false;
|
|
178
|
+
return true;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Uses the deterministic planner's intent analysis to classify message
|
|
182
|
+
* complexity, providing more accurate context packing decisions than
|
|
183
|
+
* the pure-regex heuristics in shouldPreferFastModelForMessage.
|
|
184
|
+
*
|
|
185
|
+
* Returns "simple" when the intent is fully resolvable from the message
|
|
186
|
+
* (add/remove/move with clear target, or update with extracted patch).
|
|
187
|
+
* Returns "standard" otherwise.
|
|
188
|
+
*/
|
|
189
|
+
export function classifyMessageComplexity(args) {
|
|
190
|
+
if (args.translationScope !== "none")
|
|
191
|
+
return "standard";
|
|
192
|
+
if (isStandalonePageOperation(args.message))
|
|
193
|
+
return "standard";
|
|
194
|
+
// Rewrites need surrounding context for tone matching even when intent is clear
|
|
195
|
+
if (isRewriteRequest(args.message))
|
|
196
|
+
return "standard";
|
|
197
|
+
const intent = inferDeterministicIntent({
|
|
198
|
+
message: args.message,
|
|
199
|
+
currentPage: args.currentPage,
|
|
200
|
+
activeBlockId: args.activeBlockId,
|
|
201
|
+
activeEditablePath: args.activeEditablePath
|
|
202
|
+
});
|
|
203
|
+
if (!intent?.action)
|
|
204
|
+
return "standard";
|
|
205
|
+
// Structural ops (add/remove/move) with a resolved target are simple
|
|
206
|
+
if (intent.action === "add" || intent.action === "remove" || intent.action === "move") {
|
|
207
|
+
if (intent.target_block_type || intent.new_block_type || intent.target_block_ref) {
|
|
208
|
+
return "simple";
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
// Update with an extracted patch means the value was fully parsed from the message
|
|
212
|
+
if (intent.action === "update" && intent.patch && Object.keys(intent.patch).length > 0) {
|
|
213
|
+
return "simple";
|
|
214
|
+
}
|
|
215
|
+
// Update with a resolved target block but no patch — needs LLM for content
|
|
216
|
+
return "standard";
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Checks whether a router plan is too shallow for the message's intent.
|
|
220
|
+
*
|
|
221
|
+
* Returns true when the message signals content generation need (e.g.,
|
|
222
|
+
* "add a compelling hero about our mission") but the router plan only
|
|
223
|
+
* has default/placeholder props. In this case the full planner should
|
|
224
|
+
* be preferred.
|
|
225
|
+
*/
|
|
226
|
+
export function isRouterPlanTooShallow(message, plan) {
|
|
227
|
+
if (plan.intent !== "edit_plan" || plan.ops.length === 0)
|
|
228
|
+
return false;
|
|
229
|
+
// Check if message requests meaningful content
|
|
230
|
+
const wantsContent = requestsContentGeneration(message) ||
|
|
231
|
+
/\b(about|featuring|directing|promoting|highlighting|compelling|engaging)\b/i.test(message);
|
|
232
|
+
if (!wantsContent)
|
|
233
|
+
return false;
|
|
234
|
+
// Check if the plan only has add_block ops with default-looking props
|
|
235
|
+
for (const op of plan.ops) {
|
|
236
|
+
if (op.op !== "add_block")
|
|
237
|
+
continue;
|
|
238
|
+
const block = op.block;
|
|
239
|
+
if (!block?.props)
|
|
240
|
+
continue;
|
|
241
|
+
const values = Object.values(block.props);
|
|
242
|
+
const stringValues = values.filter((v) => typeof v === "string");
|
|
243
|
+
// If all string props are short defaults (< 30 chars), the plan is shallow
|
|
244
|
+
const allShort = stringValues.length > 0 && stringValues.every(v => v.length < 30);
|
|
245
|
+
if (allShort)
|
|
246
|
+
return true;
|
|
247
|
+
}
|
|
248
|
+
return false;
|
|
249
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { EditPlan, Operation, PageDoc } from "@avocadostudio-ai/shared";
|
|
2
|
+
export declare function isRewriteLikeMessage(message: string): boolean;
|
|
3
|
+
export declare function isPerformanceAwareMessage(message: string): boolean;
|
|
4
|
+
export declare function isLikelyTextField(key: string): boolean;
|
|
5
|
+
export declare function collectChangedTextFields(ops: Operation[]): string[];
|
|
6
|
+
export declare function buildMetaChangeLogEntries(ops: Operation[]): string[];
|
|
7
|
+
export declare function buildAiInsightChanges(args: {
|
|
8
|
+
plan: EditPlan;
|
|
9
|
+
message: string;
|
|
10
|
+
}): string[];
|
|
11
|
+
/** Format a page slug for display — avoids double-slash for home page "/" or slugs that already start with "/" */
|
|
12
|
+
export declare function fmtSlug(slug: string): string;
|
|
13
|
+
export declare function buildOpChangeLogEntries(ops: Operation[], ctx: {
|
|
14
|
+
getBlockType: (slug: string, blockId: string) => string | undefined;
|
|
15
|
+
}): string[];
|
|
16
|
+
export declare function looksLikeDetailedPageSpec(message: string): boolean;
|
|
17
|
+
export declare function deterministicCreatePagePlan(args: {
|
|
18
|
+
session: string;
|
|
19
|
+
message: string;
|
|
20
|
+
hasPageTemplates?: boolean;
|
|
21
|
+
}): {
|
|
22
|
+
intent: "needs_clarification";
|
|
23
|
+
summary_for_user: string;
|
|
24
|
+
change_log: string[];
|
|
25
|
+
ops: never[];
|
|
26
|
+
} | {
|
|
27
|
+
intent: "edit_plan";
|
|
28
|
+
summary_for_user: string;
|
|
29
|
+
change_log: string[];
|
|
30
|
+
ops: {
|
|
31
|
+
op: "create_page";
|
|
32
|
+
page: PageDoc;
|
|
33
|
+
}[];
|
|
34
|
+
} | null;
|
|
35
|
+
export declare function deterministicDuplicatePagePlan(args: {
|
|
36
|
+
session: string;
|
|
37
|
+
message: string;
|
|
38
|
+
effectiveSlug: string;
|
|
39
|
+
}): {
|
|
40
|
+
intent: "needs_clarification";
|
|
41
|
+
summary_for_user: string;
|
|
42
|
+
change_log: never[];
|
|
43
|
+
ops: never[];
|
|
44
|
+
} | {
|
|
45
|
+
intent: "edit_plan";
|
|
46
|
+
summary_for_user: string;
|
|
47
|
+
change_log: string[];
|
|
48
|
+
ops: {
|
|
49
|
+
op: "duplicate_page";
|
|
50
|
+
pageSlug: string;
|
|
51
|
+
newPageSlug: string;
|
|
52
|
+
}[];
|
|
53
|
+
} | null;
|
|
54
|
+
export declare function deterministicSelectedTextRewritePlan(args: {
|
|
55
|
+
slug: string;
|
|
56
|
+
message: string;
|
|
57
|
+
currentPage: PageDoc;
|
|
58
|
+
activeBlockId?: string;
|
|
59
|
+
activeEditablePath?: string;
|
|
60
|
+
}): null;
|
|
61
|
+
export declare function shouldReturnDeterministicClarification(message: string): boolean;
|