@slatesvideo/shared 0.6.10 → 0.7.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/README.md +1 -1
- package/dist/auth.js +2 -2
- package/dist/clients/cloud.js +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +4 -1
- package/dist/manual/content.d.ts +1 -1
- package/dist/manual/content.js +1 -1
- package/dist/operations/index.d.ts +817 -16
- package/dist/operations/index.js +1423 -372
- package/dist/operations/surface.d.ts +3 -1
- package/dist/operations/surface.js +37 -10
- package/dist/prompts/ad-presets.d.ts +77 -0
- package/dist/prompts/ad-presets.js +43 -0
- package/dist/prompts/agent-doctrine.js +5 -4
- package/dist/prompts/banned-tokens.d.ts +4 -29
- package/dist/prompts/banned-tokens.js +29 -204
- package/dist/prompts/craft-cards.js +2 -2
- package/dist/prompts/generation-policy.d.ts +41 -0
- package/dist/prompts/generation-policy.js +53 -0
- package/dist/prompts/guide-retrieval.d.ts +9 -0
- package/dist/prompts/guide-retrieval.js +53 -0
- package/dist/prompts/index.d.ts +1 -0
- package/dist/prompts/index.js +1 -0
- package/dist/prompts/model-capabilities.d.ts +18 -1
- package/dist/prompts/model-capabilities.js +72 -19
- package/dist/prompts/model-facts.d.ts +59 -0
- package/dist/prompts/model-facts.js +121 -15
- package/dist/prompts/partials.generated.js +8 -2
- package/dist/prompts/prompting-tips.d.ts +1 -1
- package/dist/prompts/prompting-tips.js +63 -18
- package/dist/prompts/reference-composer.d.ts +2 -0
- package/dist/prompts/reference-composer.js +51 -50
- package/dist/prompts/script-document.d.ts +165 -0
- package/dist/prompts/script-document.js +11 -0
- package/dist/prompts/shot-grammar.d.ts +4 -4
- package/dist/prompts/shot-grammar.js +3 -3
- package/dist/prompts/shot-spec.d.ts +13 -0
- package/dist/prompts/shot-spec.js +23 -5
- package/dist/skills/content.js +26 -23
- package/dist/update-check.d.ts +22 -0
- package/dist/update-check.js +109 -0
- package/exports/slates-chatgpt-images/generated/SKILL.md +107 -0
- package/exports/slates-chatgpt-images/generated/slates-chatgpt-images.skill +0 -0
- package/exports/slates-prompt-builder/generated/SKILL.md +3 -3
- package/exports/slates-prompt-builder/generated/reference-character.md +9 -1
- package/exports/slates-prompt-builder/generated/reference-kling.md +3 -3
- package/exports/slates-prompt-builder/generated/reference-nano-banana.md +22 -10
- package/exports/slates-prompt-builder/generated/reference-seedance.md +4 -4
- package/exports/slates-prompt-builder/generated/slates-prompt-builder-manifest.json +17 -17
- package/exports/slates-prompt-builder/generated/slates-prompt-builder.skill +0 -0
- package/package.json +10 -4
- package/skills/_partials/cinematic-card.md +8 -0
- package/skills/_partials/cinematic-routes-short.md +2 -0
- package/skills/_partials/cinematic-tips-short.md +2 -0
- package/skills/_partials/decision-log.md +1 -13
- package/skills/_partials/image-defaults.md +11 -0
- package/skills/_partials/lens-video-split.md +1 -0
- package/skills/_partials/reference-rules-core.md +1 -1
- package/skills/_partials/sheet-tool-defaults.md +6 -0
- package/skills/slates-character-identity.md +9 -1
- package/skills/slates-chatgpt-images.md +107 -0
- package/skills/slates-cinematic-look.md +237 -0
- package/skills/slates-cost-discipline.md +18 -12
- package/skills/slates-direct-response-ad.md +13 -53
- package/skills/slates-edit-and-iterate.md +1 -1
- package/skills/slates-model-selection.md +139 -133
- package/skills/slates-one-prompt-film.md +38 -95
- package/skills/slates-project-organization.md +7 -3
- package/skills/slates-prompting-flux-2-max.md +15 -4
- package/skills/slates-prompting-gpt-image-2-5.md +41 -28
- package/skills/slates-prompting-kling-v3.md +3 -3
- package/skills/slates-prompting-lip-sync.md +1 -1
- package/skills/slates-prompting-minimax-h3.md +30 -17
- package/skills/slates-prompting-motion-transfer.md +1 -1
- package/skills/slates-prompting-nano-banana-2.md +24 -11
- package/skills/slates-prompting-seedance-2-5.md +12 -12
- package/skills/slates-prompting-seedance.md +5 -5
- package/skills/slates-prompting-seedream-5-lite.md +14 -3
- package/skills/slates-prompting-veo-3.md +1 -1
- package/skills/slates-script-craft.md +45 -0
- package/skills/slates-shot-variety.md +11 -40
- package/skills/slates-storyboard-from-script.md +14 -66
- package/skills/slates-style-prompting.md +54 -54
- package/skills/slates-ugc-influencer-ad.md +32 -309
- package/skills/slates-vision-feedback-loop.md +2 -1
|
@@ -37,6 +37,7 @@ export declare const OPERATION_GROUPS: Record<OperationGroup, readonly string[]>
|
|
|
37
37
|
export declare function groupFor(id: string): OperationGroup | undefined;
|
|
38
38
|
/** `extended` iff the op names a group. Absent from every group ⇒ `core`, so a
|
|
39
39
|
* new op is visible until someone deliberately defers it. */
|
|
40
|
+
export declare const STARTUP_TOOL_IDS: Set<string>;
|
|
40
41
|
export declare function tierFor(id: string): OperationTier;
|
|
41
42
|
/** One-line summary of each group, for `slates_load_tools`' own description. */
|
|
42
43
|
export declare const GROUP_SUMMARY: Record<OperationGroup, string>;
|
|
@@ -60,10 +61,11 @@ export declare function toolDefinition(op: SurfaceOp): ToolDefinition;
|
|
|
60
61
|
* Render a tool surface.
|
|
61
62
|
*
|
|
62
63
|
* `desktop` sends `core` plus whatever groups have been loaded this run; `mcp`
|
|
63
|
-
*
|
|
64
|
+
* renders all definitions; the MCP server filters its connection listing from that set.
|
|
64
65
|
*/
|
|
65
66
|
export declare function toolDefinitions(ops: readonly SurfaceOp[], opts: {
|
|
66
67
|
surface: 'desktop' | 'mcp';
|
|
67
68
|
groups?: readonly OperationGroup[];
|
|
69
|
+
names?: readonly string[];
|
|
68
70
|
}): ToolDefinition[];
|
|
69
71
|
//# sourceMappingURL=surface.d.ts.map
|
|
@@ -11,10 +11,9 @@
|
|
|
11
11
|
//
|
|
12
12
|
// 2. TIERS. 90 ops is 112 KB of descriptions and JSON schemas on EVERY
|
|
13
13
|
// desktop Studio Agent turn. `core` is what a session needs to work;
|
|
14
|
-
// `extended` is
|
|
15
|
-
//
|
|
16
|
-
//
|
|
17
|
-
// already defers stdio tool schemas through its own tool search.
|
|
14
|
+
// `extended` is selected through `slates_load_tools`. Both surfaces replace
|
|
15
|
+
// the optional selection on a named/group load. MCP keeps every direct
|
|
16
|
+
// operation callable for compatibility and notifies when its listing changes.
|
|
18
17
|
//
|
|
19
18
|
// 3. ONE SCHEMA RENDERER. The desktop rendered `$refStrategy: 'none'` and
|
|
20
19
|
// the MCP server rendered `target: 'openApi3'`, so "the two surfaces
|
|
@@ -54,12 +53,15 @@ const DESTRUCTIVE_IDS = new Set([
|
|
|
54
53
|
'slates_delete_character',
|
|
55
54
|
'slates_delete_environment',
|
|
56
55
|
'slates_delete_style',
|
|
56
|
+
'slates_delete_library_item',
|
|
57
57
|
'slates_delete_storyboard',
|
|
58
58
|
'slates_delete_scene',
|
|
59
59
|
'slates_delete_frame',
|
|
60
60
|
'slates_move_assets_to_folder',
|
|
61
61
|
'slates_move_assets_to_project',
|
|
62
62
|
'slates_move_entity_to_project',
|
|
63
|
+
'slates_relocate_project',
|
|
64
|
+
'slates_undo_relocate_project',
|
|
63
65
|
'slates_merge_shots',
|
|
64
66
|
'slates_split_shot',
|
|
65
67
|
]);
|
|
@@ -115,6 +117,11 @@ export const OPERATION_GROUPS = {
|
|
|
115
117
|
'slates_delete_folder',
|
|
116
118
|
'slates_set_folder_cover',
|
|
117
119
|
'slates_move_assets_to_folder',
|
|
120
|
+
'slates_set_asset_favorite',
|
|
121
|
+
'slates_export_assets',
|
|
122
|
+
'slates_list_pins',
|
|
123
|
+
'slates_pin_references',
|
|
124
|
+
'slates_unpin_reference',
|
|
118
125
|
'slates_move_assets_to_project',
|
|
119
126
|
'slates_copy_assets_to_project',
|
|
120
127
|
'slates_move_entity_to_project',
|
|
@@ -122,15 +129,29 @@ export const OPERATION_GROUPS = {
|
|
|
122
129
|
'slates_create_style',
|
|
123
130
|
'slates_update_style',
|
|
124
131
|
'slates_delete_style',
|
|
132
|
+
'slates_list_library',
|
|
133
|
+
'slates_create_library_item',
|
|
134
|
+
'slates_update_library_item',
|
|
135
|
+
'slates_delete_library_item',
|
|
136
|
+
'slates_manage_library_category',
|
|
137
|
+
'slates_copy_library_item_to_project',
|
|
138
|
+
'slates_get_template',
|
|
139
|
+
'slates_export_template',
|
|
140
|
+
'slates_import_template',
|
|
125
141
|
'slates_get_project_directory',
|
|
142
|
+
'slates_relocate_project',
|
|
143
|
+
'slates_undo_relocate_project',
|
|
126
144
|
'slates_reveal_file',
|
|
127
145
|
],
|
|
128
146
|
// The cut and the export. A generation session never touches these.
|
|
147
|
+
script: ['slates_get_script_document', 'slates_update_script_document', 'slates_get_script_sections', 'slates_update_script_section', 'slates_get_script_suggestions', 'slates_update_script_suggestions', 'slates_get_script_uses', 'slates_preview_script_variation', 'slates_create_script_variation', 'slates_get_shot_inputs', 'slates_reuse_shot_take'],
|
|
129
148
|
timeline: [
|
|
149
|
+
'slates_list_timelines', 'slates_save_timeline', 'slates_export_cuts',
|
|
130
150
|
'slates_get_timeline',
|
|
131
151
|
'slates_add_clip_to_timeline',
|
|
132
152
|
'slates_reorder_clips',
|
|
133
153
|
'slates_remove_clip',
|
|
154
|
+
'slates_manage_timeline_marker',
|
|
134
155
|
'slates_add_timeline_track',
|
|
135
156
|
'slates_update_timeline_track',
|
|
136
157
|
'slates_remove_timeline_track',
|
|
@@ -179,14 +200,20 @@ export function groupFor(id) {
|
|
|
179
200
|
}
|
|
180
201
|
/** `extended` iff the op names a group. Absent from every group ⇒ `core`, so a
|
|
181
202
|
* new op is visible until someone deliberately defers it. */
|
|
203
|
+
export const STARTUP_TOOL_IDS = new Set([
|
|
204
|
+
'slates_load_tools', 'slates_get_prompting_guide', 'slates_get_workspace_state',
|
|
205
|
+
'slates_list_projects', 'slates_create_project', 'slates_list_assets',
|
|
206
|
+
'slates_get_asset_image', 'slates_get_generation_status', 'slates_estimate_generation_cost',
|
|
207
|
+
]);
|
|
182
208
|
export function tierFor(id) {
|
|
183
|
-
return
|
|
209
|
+
return STARTUP_TOOL_IDS.has(id) ? 'core' : 'extended';
|
|
184
210
|
}
|
|
185
211
|
/** One-line summary of each group, for `slates_load_tools`' own description. */
|
|
186
212
|
export const GROUP_SUMMARY = {
|
|
187
|
-
library: 'folders,
|
|
188
|
-
|
|
189
|
-
|
|
213
|
+
library: 'folders, the Library (user-named categories of saved references: characters, locations, products, looks), moving and copying assets and Library items between projects, moving a project into the current projects folder, revealing files on disk',
|
|
214
|
+
script: 'rich script documents, anchored sections and their saved versions, reusable passages, variations and take input history',
|
|
215
|
+
timeline: 'named cuts and selected exports; the timeline (tracks, clips, markers, settings), video export and export for DaVinci, Premiere or Final Cut (XML), clip trimming',
|
|
216
|
+
admin: 'rename / delete / reorder for projects, characters, locations, looks, boards, scenes and frames; shot duplicate, split and merge',
|
|
190
217
|
blender: 'the Blender previs bridge — scene inspection, bpy execution, API docs, grey-box render',
|
|
191
218
|
};
|
|
192
219
|
/**
|
|
@@ -211,7 +238,7 @@ export function toolDefinition(op) {
|
|
|
211
238
|
* Render a tool surface.
|
|
212
239
|
*
|
|
213
240
|
* `desktop` sends `core` plus whatever groups have been loaded this run; `mcp`
|
|
214
|
-
*
|
|
241
|
+
* renders all definitions; the MCP server filters its connection listing from that set.
|
|
215
242
|
*/
|
|
216
243
|
export function toolDefinitions(ops, opts) {
|
|
217
244
|
const loaded = new Set(opts.groups ?? []);
|
|
@@ -220,7 +247,7 @@ export function toolDefinitions(ops, opts) {
|
|
|
220
247
|
if (opts.surface === 'mcp')
|
|
221
248
|
return true;
|
|
222
249
|
const group = groupFor(op.id);
|
|
223
|
-
return group
|
|
250
|
+
return STARTUP_TOOL_IDS.has(op.id) || !!opts.names?.includes(op.id) || (group !== undefined && loaded.has(group));
|
|
224
251
|
})
|
|
225
252
|
.map(toolDefinition);
|
|
226
253
|
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/** Original free starter examples. Model choices and costs resolve at use time.
|
|
2
|
+
* Evidence and source coverage: second-brain/business/projects/slates/research/script-craft/.
|
|
3
|
+
* Preview readiness is explicit; importing a draft never claims a tested output. */
|
|
4
|
+
export declare const AD_PRESETS: readonly [{
|
|
5
|
+
readonly id: "catch-the-small-problem";
|
|
6
|
+
readonly revision: 1;
|
|
7
|
+
readonly name: "Catch the small problem";
|
|
8
|
+
readonly tags: readonly ["product demonstration", "spoken", "everyday"];
|
|
9
|
+
readonly techniques: readonly ["sc-event", "sc-proof", "sc-bridge"];
|
|
10
|
+
readonly description: "A small everyday frustration becomes a visible product demonstration. An original fictional keys-tray example.";
|
|
11
|
+
readonly adaptation: "Replace the object, familiar frustration and observable demonstration. Supply real product facts and the destination for the invitation. Compare the opening and its bridge together; keep the demonstration fixed.";
|
|
12
|
+
readonly sections: readonly [{
|
|
13
|
+
readonly label: "Opening";
|
|
14
|
+
readonly alternatives: readonly [{
|
|
15
|
+
readonly label: "Question";
|
|
16
|
+
readonly text: "Where do your keys go when you get home?\nMine used to land wherever my hand stopped.";
|
|
17
|
+
readonly action: "A hand drops a key ring onto a cluttered entrance table. The keys stop near the edge. An ordinary moment, filmed close enough to see the key ring.";
|
|
18
|
+
}, {
|
|
19
|
+
readonly label: "Search";
|
|
20
|
+
readonly text: "I checked my coat, my bag, and the table.\nThey were under the receipt.";
|
|
21
|
+
readonly action: "The same hand checks a coat pocket, opens a bag, then lifts a receipt to reveal the keys. Let the last action answer the search.";
|
|
22
|
+
}, {
|
|
23
|
+
readonly label: "Objection";
|
|
24
|
+
readonly text: "A tray just for keys?\nThat was my question too.";
|
|
25
|
+
readonly action: "A small tray sits beside a scattered key ring. A hand turns the tray once, then puts it down by the door.";
|
|
26
|
+
}];
|
|
27
|
+
}, {
|
|
28
|
+
readonly label: "Demonstration";
|
|
29
|
+
readonly alternatives: readonly [{
|
|
30
|
+
readonly label: "A place to land";
|
|
31
|
+
readonly text: "Now I leave this by the door.\nKeys go in when I arrive. I pick them up when I leave.";
|
|
32
|
+
readonly action: "The hand places the keys inside the shallow tray. Match the next departure gesture to the same framing: the hand finds the keys in that tray. Show only the behavior described.";
|
|
33
|
+
}];
|
|
34
|
+
}, {
|
|
35
|
+
readonly label: "Invitation";
|
|
36
|
+
readonly alternatives: readonly [{
|
|
37
|
+
readonly label: "See the product";
|
|
38
|
+
readonly text: "Give the small things a place to land.";
|
|
39
|
+
readonly action: "Hold a clear view of the tray with the keys inside. Keep the product unobstructed. The destination and offer are supplied by the creator; no price or claim appears in the image.";
|
|
40
|
+
}];
|
|
41
|
+
}];
|
|
42
|
+
}, {
|
|
43
|
+
readonly id: "silent-small-demonstration";
|
|
44
|
+
readonly revision: 1;
|
|
45
|
+
readonly name: "Let the object explain";
|
|
46
|
+
readonly tags: readonly ["silent", "product demonstration", "modular"];
|
|
47
|
+
readonly techniques: readonly ["sc-event", "sc-proof", "sc-modular"];
|
|
48
|
+
readonly description: "An original silent tray demonstration. The opening event changes while the product action stays fixed.";
|
|
49
|
+
readonly adaptation: "Choose a real product action that reads without speech. Replace the sample object and place. Keep the physical setup legible; a different opening must still lead naturally into the same demonstration. Add sound only when wanted.";
|
|
50
|
+
readonly sections: readonly [{
|
|
51
|
+
readonly label: "Opening event";
|
|
52
|
+
readonly alternatives: readonly [{
|
|
53
|
+
readonly label: "Almost lost";
|
|
54
|
+
readonly text: "";
|
|
55
|
+
readonly action: "Silent overhead view of an entrance table. A key ring slides toward the edge and stops. A hand enters with a shallow tray. No dialogue or on-screen text.";
|
|
56
|
+
}, {
|
|
57
|
+
readonly label: "Found it";
|
|
58
|
+
readonly text: "";
|
|
59
|
+
readonly action: "Silent overhead view of an entrance table. A hand lifts a small stack of receipts, revealing a key ring underneath. The hand brings an empty shallow tray into the same space. No dialogue or on-screen text.";
|
|
60
|
+
}];
|
|
61
|
+
}, {
|
|
62
|
+
readonly label: "Demonstration";
|
|
63
|
+
readonly alternatives: readonly [{
|
|
64
|
+
readonly label: "In reach";
|
|
65
|
+
readonly text: "";
|
|
66
|
+
readonly action: "Silent overhead view of the same table and tray. A hand puts the keys inside the tray, leaves the frame, then returns and picks them up directly. Keep the object and gesture visible. No dialogue or on-screen text.";
|
|
67
|
+
}];
|
|
68
|
+
}, {
|
|
69
|
+
readonly label: "Closing view";
|
|
70
|
+
readonly alternatives: readonly [{
|
|
71
|
+
readonly label: "The result";
|
|
72
|
+
readonly text: "";
|
|
73
|
+
readonly action: "Silent close view of the same tray holding the key ring on the table. Hold the still composition so the result is easy to read. No dialogue or on-screen text.";
|
|
74
|
+
}];
|
|
75
|
+
}];
|
|
76
|
+
}];
|
|
77
|
+
//# sourceMappingURL=ad-presets.d.ts.map
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/** Original free starter examples. Model choices and costs resolve at use time.
|
|
2
|
+
* Evidence and source coverage: second-brain/business/projects/slates/research/script-craft/.
|
|
3
|
+
* Preview readiness is explicit; importing a draft never claims a tested output. */
|
|
4
|
+
export const AD_PRESETS = [
|
|
5
|
+
{
|
|
6
|
+
id: 'catch-the-small-problem', revision: 1, name: 'Catch the small problem',
|
|
7
|
+
tags: ['product demonstration', 'spoken', 'everyday'], techniques: ['sc-event', 'sc-proof', 'sc-bridge'],
|
|
8
|
+
description: 'A small everyday frustration becomes a visible product demonstration. An original fictional keys-tray example.',
|
|
9
|
+
adaptation: 'Replace the object, familiar frustration and observable demonstration. Supply real product facts and the destination for the invitation. Compare the opening and its bridge together; keep the demonstration fixed.',
|
|
10
|
+
sections: [
|
|
11
|
+
{ label: 'Opening', alternatives: [
|
|
12
|
+
{ label: 'Question', text: 'Where do your keys go when you get home?\nMine used to land wherever my hand stopped.', action: 'A hand drops a key ring onto a cluttered entrance table. The keys stop near the edge. An ordinary moment, filmed close enough to see the key ring.' },
|
|
13
|
+
{ label: 'Search', text: 'I checked my coat, my bag, and the table.\nThey were under the receipt.', action: 'The same hand checks a coat pocket, opens a bag, then lifts a receipt to reveal the keys. Let the last action answer the search.' },
|
|
14
|
+
{ label: 'Objection', text: 'A tray just for keys?\nThat was my question too.', action: 'A small tray sits beside a scattered key ring. A hand turns the tray once, then puts it down by the door.' },
|
|
15
|
+
] },
|
|
16
|
+
{ label: 'Demonstration', alternatives: [
|
|
17
|
+
{ label: 'A place to land', text: 'Now I leave this by the door.\nKeys go in when I arrive. I pick them up when I leave.', action: 'The hand places the keys inside the shallow tray. Match the next departure gesture to the same framing: the hand finds the keys in that tray. Show only the behavior described.' },
|
|
18
|
+
] },
|
|
19
|
+
{ label: 'Invitation', alternatives: [
|
|
20
|
+
{ label: 'See the product', text: 'Give the small things a place to land.', action: 'Hold a clear view of the tray with the keys inside. Keep the product unobstructed. The destination and offer are supplied by the creator; no price or claim appears in the image.' },
|
|
21
|
+
] },
|
|
22
|
+
],
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
id: 'silent-small-demonstration', revision: 1, name: 'Let the object explain',
|
|
26
|
+
tags: ['silent', 'product demonstration', 'modular'], techniques: ['sc-event', 'sc-proof', 'sc-modular'],
|
|
27
|
+
description: 'An original silent tray demonstration. The opening event changes while the product action stays fixed.',
|
|
28
|
+
adaptation: 'Choose a real product action that reads without speech. Replace the sample object and place. Keep the physical setup legible; a different opening must still lead naturally into the same demonstration. Add sound only when wanted.',
|
|
29
|
+
sections: [
|
|
30
|
+
{ label: 'Opening event', alternatives: [
|
|
31
|
+
{ label: 'Almost lost', text: '', action: 'Silent overhead view of an entrance table. A key ring slides toward the edge and stops. A hand enters with a shallow tray. No dialogue or on-screen text.' },
|
|
32
|
+
{ label: 'Found it', text: '', action: 'Silent overhead view of an entrance table. A hand lifts a small stack of receipts, revealing a key ring underneath. The hand brings an empty shallow tray into the same space. No dialogue or on-screen text.' },
|
|
33
|
+
] },
|
|
34
|
+
{ label: 'Demonstration', alternatives: [
|
|
35
|
+
{ label: 'In reach', text: '', action: 'Silent overhead view of the same table and tray. A hand puts the keys inside the tray, leaves the frame, then returns and picks them up directly. Keep the object and gesture visible. No dialogue or on-screen text.' },
|
|
36
|
+
] },
|
|
37
|
+
{ label: 'Closing view', alternatives: [
|
|
38
|
+
{ label: 'The result', text: '', action: 'Silent close view of the same tray holding the key ring on the table. Hold the still composition so the result is easy to read. No dialogue or on-screen text.' },
|
|
39
|
+
] },
|
|
40
|
+
],
|
|
41
|
+
},
|
|
42
|
+
];
|
|
43
|
+
//# sourceMappingURL=ad-presets.js.map
|
|
@@ -82,7 +82,7 @@ export const WORKING_METHOD = [
|
|
|
82
82
|
both(`For HOW/WHERE questions, load slates_get_prompting_guide with topic "app-manual" and relevant query keywords. Teach the documented buttons and tabs, preserving model-specific conditions; do not invent UI paths or mutate the project when the user only asks for instructions. Slates is a sandbox of optional tools, not a required pipeline.`),
|
|
83
83
|
both(`1. UNDERSTAND the outcome the user wants. If intent is clear, act with sane defaults — don't interrogate. If genuinely ambiguous, batch every question into ONE message.`),
|
|
84
84
|
both(`2. ORIENT: call slates_get_workspace_state once at the start of a workflow. Work in the user's CURRENT project — this chat lives inside it. NEVER create a new project unless explicitly asked; if there's no current project, ask which to use.`),
|
|
85
|
-
both(`3. LOAD KNOWLEDGE ON DEMAND:
|
|
85
|
+
both(`3. LOAD KNOWLEDGE ON DEMAND: slates_get_prompting_guide returns a short card by default; query a section or technique when needed. Use slates_load_tools with query to find a capability, then names to load its exact schema. A load replaces the previous optional selection. Before quoting a model, load its tool schema or routing guide. Use workspace generationDefaults when the user has no preference. Read the model card delivered by the estimate; fetch a section or full guide for an unfamiliar mode or missing detail. Reuse guidance already in context; retrieve it again when omitted or stale.`),
|
|
86
86
|
// FORKED: `present_plan` is a loop-level DESKTOP tool, deliberately not in
|
|
87
87
|
// ALL_OPERATIONS, so MCP never sees it and has no plan gate at all. Its
|
|
88
88
|
// substitute is the per-op `requires_confirm` threshold plus the host
|
|
@@ -102,7 +102,8 @@ export const HARD_RULES = [
|
|
|
102
102
|
fork(`- COST DISCIPLINE (slates-cost-discipline): never fire a billable generation outside an approved plan. Estimate before you promise. Batch related generations into one plan.`, `- COST DISCIPLINE (slates-cost-discipline): never fire a billable generation the user has not agreed to. Estimate before you promise. Batch related generations into one quote so the user approves a total, not a drip.`),
|
|
103
103
|
both(`- CONTENT POLICY: before writing prompts involving real people/celebrities, minors, brands/logos, weapons, or gore, load slates-content-policy and build the scene safe from the first word. If a provider rejects (e.g. real-face detection), explain in plain language — refunds for provider rejections are automatic.`),
|
|
104
104
|
both(`- PROMPT IS LAW (reference doctrine): references are cited inline by name and image number ("Marcus (images 1 and 2)"); the prompt text leads. Never write role-essays about what each reference is "for".`),
|
|
105
|
-
both(`- NAMES AND DESCRIPTIONS ARE THE USER'S UI, NOT YOUR NOTEPAD. A project,
|
|
105
|
+
both(`- NAMES AND DESCRIPTIONS ARE THE USER'S UI, NOT YOUR NOTEPAD. A project, board or shot name is rendered at the top of the user's screen at all times. Name it after the piece ("Kaiju selfie"), never after your process, and NEVER append your own status or housekeeping — no "shot list", no "v2", no "Written from IMG-A172 and IMG-A182", no "Delete freely", no "scratch". Leave the description empty unless the user gave you one worth keeping: a note-to-self at the top of the screen reads as part of the product, and the user has to look at it every day. Say that kind of thing in your reply to them instead.`),
|
|
106
|
+
both(`- SAY THE APP'S WORDS. Tool and parameter names keep older nouns; the screen does not, and the user only ever sees the screen. Say board (not storyboard), location (not environment) and look (not style) for Library items, timeline (a saved version of it is a cut), version (a saved rewrite of a script section; not alternative), Words or Words + shots (the Script page's switch), the Generate panel (not the quote), and tab (Media, Script and Board; not lens). Describe what you did in plain words ("Checked your project", "Priced 6 clips"), never a tool or parameter name.`),
|
|
106
107
|
both(`- RESOLUTION DEFAULT IS UNIFORM: 1080p on the best available video model. Do not crank resolution the user didn't ask for.`),
|
|
107
108
|
// ⛔ THE MODEL ROUTING BLOCK IS GONE FROM HERE, DELIBERATELY (2026-08-30).
|
|
108
109
|
//
|
|
@@ -120,7 +121,7 @@ export const HARD_RULES = [
|
|
|
120
121
|
// exported "in case": an export nothing calls is an export nothing keeps
|
|
121
122
|
// honest. `describeRouting()` in model-facts.ts is the renderer now.
|
|
122
123
|
both(`- MODEL KINDS: image, video and audio models are disjoint — no image model makes a video, no video model makes a standalone image, no image or video model makes audio. Which SEAT to pick inside a kind is on each generate op's own \`model\` description, and the full table is the slates-model-selection skill.`),
|
|
123
|
-
both(`- ASSET CODES + STALENESS: every asset carries a badge code (IMG-A12 / VID-V3 / AUD-S1, top-left of its gallery card); speak about assets by code + label. Asset lists go STALE — the user creates assets in the Slates UI mid-conversation. When the user names a code you have NOT seen in a tool result this session, resolve it with slates_list_assets (use the search filter) BEFORE using it. NEVER guess an asset id or reuse a nearby UUID — pass the exact id a tool returned for that exact code. A wrong start frame burns real credits.`),
|
|
124
|
+
both(`- ASSET CODES + STALENESS: every asset carries a badge code (IMG-A12 / VID-V3 / AUD-S1, top-left of its gallery card); speak about assets by code + label. When the user says "these" or "this one", call slates_get_selection rather than asking which. Asset lists go STALE — the user creates assets in the Slates UI mid-conversation. When the user names a code you have NOT seen in a tool result this session, resolve it with slates_list_assets (use the search filter) BEFORE using it. NEVER guess an asset id or reuse a nearby UUID — pass the exact id a tool returned for that exact code. A wrong start frame burns real credits.`),
|
|
124
125
|
both(`- CREDITS ONLY: every generation you drive bills Slates credits (your tool calls enforce this). Never suggest BYOK keys for agent work.`),
|
|
125
126
|
both(`- Do not invent tools, asset ids, or credit prices. If a tool errors, read the error and fix that exact issue; don't repeat the same call unchanged and never switch models to route around a parameter mistake.`),
|
|
126
127
|
// FORKED: only the desktop loop auto-polls generation status
|
|
@@ -138,7 +139,7 @@ export const HARD_RULES = [
|
|
|
138
139
|
// compliance 0/8 → 30/32, while the same guidance behind a guide fetch sat at
|
|
139
140
|
// 13% before and after. This sentence exists only to say the numbers are
|
|
140
141
|
// there and must be looked at; the craft is the skill.
|
|
141
|
-
both(`- READ THE VARIETY COUNTS BEFORE FIRING A SET: slates_list_shots and slates_get_storyboard_with_frames return
|
|
142
|
+
both(`- READ THE VARIETY COUNTS BEFORE FIRING A SET: slates_list_shots and slates_get_storyboard_with_frames return authored framing and movement distributions. Review unintended sameness while preserving deliberate repetition and the user's format; counts do not require a rewrite. slates-shot-variety is the craft.`),
|
|
142
143
|
both(`- AUDIO LENGTH IS PROMPT-DRIVEN ON SEED AUDIO: it has no duration parameter, so the durationSeconds you pass is written into the prompt AND is what the user is charged, whatever comes back. Choose it deliberately and load slates-prompting-seed-audio before the first call.`),
|
|
143
144
|
];
|
|
144
145
|
// ── Surface-only footers ───────────────────────────────────────────
|
|
@@ -1,40 +1,15 @@
|
|
|
1
|
-
/** Which generate op a list applies to. */
|
|
2
1
|
export type BannedTokenScope = 'image' | 'video';
|
|
3
2
|
export interface BannedToken {
|
|
4
|
-
/** The literal phrase, verbatim from the skill. */
|
|
5
3
|
token: string;
|
|
6
|
-
/** Skill file it was read from — cited in every warning. */
|
|
7
4
|
skill: string;
|
|
8
5
|
scope: BannedTokenScope;
|
|
9
6
|
}
|
|
10
|
-
/**
|
|
7
|
+
/** Compatibility exports: there is no cross-model blacklist. */
|
|
11
8
|
export declare const BANNED_PROMPT_TOKENS: readonly BannedToken[];
|
|
12
|
-
export declare function bannedTokensFor(
|
|
13
|
-
|
|
9
|
+
export declare function bannedTokensFor(_scope: BannedTokenScope): readonly BannedToken[];
|
|
10
|
+
export declare function describeBannedTokens(_scope: BannedTokenScope): string;
|
|
14
11
|
export declare function bannedTokensForSkill(skill: string): readonly BannedToken[];
|
|
15
|
-
|
|
16
|
-
* A single model's never-use list, for the estimate RESULT.
|
|
17
|
-
*
|
|
18
|
-
* Deliberately NOT the cross-model list — that one already rides the op
|
|
19
|
-
* description on every call. This is the half that could not: the quirk that is
|
|
20
|
-
* true of Veo and false of Kling.
|
|
21
|
-
*/
|
|
12
|
+
export declare function findBannedTokens(prompt: string, _scope: BannedTokenScope, skill?: string): BannedToken[];
|
|
22
13
|
export declare function describeBannedTokensForSkill(skill: string): string;
|
|
23
|
-
/** The tokens a submitted prompt actually contains. `skill` adds that model's
|
|
24
|
-
* own list to the modality-wide one — the two overlap for nano-banana-2 and
|
|
25
|
-
* seedance, so hits are deduplicated by token. */
|
|
26
|
-
export declare function findBannedTokens(prompt: string, scope: BannedTokenScope, skill?: string): BannedToken[];
|
|
27
|
-
/**
|
|
28
|
-
* The list as it appears INSIDE an op description — always in context, on both
|
|
29
|
-
* surfaces, with no call required to see it. Generated, never hand-typed.
|
|
30
|
-
*/
|
|
31
|
-
export declare function describeBannedTokens(scope: BannedTokenScope): string;
|
|
32
|
-
/**
|
|
33
|
-
* Non-blocking warning for a submitted prompt. Empty string when clean.
|
|
34
|
-
*
|
|
35
|
-
* Returned in the op RESULT — the one place the agent cannot avoid reading —
|
|
36
|
-
* rather than raised as an error. The generation proceeds either way: the
|
|
37
|
-
* sandbox doctrine says make state visible, never block.
|
|
38
|
-
*/
|
|
39
14
|
export declare function bannedTokenWarning(prompt: string, scope: BannedTokenScope, skill?: string): string;
|
|
40
15
|
//# sourceMappingURL=banned-tokens.d.ts.map
|
|
@@ -1,219 +1,44 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
//
|
|
4
|
-
// THE PROBLEM: "before prompting any model, load the matching guide" is a
|
|
5
|
-
// sentence in a system prompt with nothing checking it. Measured 2026-08-30 in
|
|
6
|
-
// a real Studio Agent session: slates_get_prompting_guide was called ZERO
|
|
7
|
-
// times, and the prompt that shipped tripped the skill's own never-use list
|
|
8
|
-
// twice (`photorealistic`, `cinematic`). A rule with no check is a suggestion,
|
|
9
|
-
// and an LLM is the least reliable enforcer you could pick.
|
|
10
|
-
//
|
|
11
|
-
// THE FIX, in two halves, neither of which the model can skip:
|
|
12
|
-
// (a) the never-use list is INLINED into the generate ops' descriptions.
|
|
13
|
-
// Op descriptions are always in context on BOTH surfaces — there is no
|
|
14
|
-
// call to omit and no discretion to exercise.
|
|
15
|
-
// (b) the submitted prompt is MATCHED against the list and a warning comes
|
|
16
|
-
// back in the op result. Non-blocking: the generation proceeds
|
|
17
|
-
// (PRODUCT_PHILOSOPHY.md → make state visible, never block).
|
|
18
|
-
//
|
|
19
|
-
// 🚨 THE LIST IS NEVER HAND-TYPED HERE. It is extracted from the skill files
|
|
20
|
-
// themselves, between `<!-- @banned:start -->` / `<!-- @banned:end -->`
|
|
21
|
-
// markers. That is this workspace's LLM-docs doctrine — never hand-type a fact
|
|
22
|
-
// an LLM will read — and it is the only way the op description and the skill
|
|
23
|
-
// cannot drift apart. Change the skill; the description follows on the next
|
|
24
|
-
// build. scripts/agent-surface-lockstep-check.mjs fails the build if a token
|
|
25
|
-
// in a description no longer appears in its source skill.
|
|
26
|
-
//
|
|
27
|
-
// Deterministic by construction (document order, no sorting, no dedupe
|
|
28
|
-
// reshuffle) because these strings land in the desktop's prompt-cached tool
|
|
29
|
-
// prefix, whose byte-stability IS the cache mechanism.
|
|
30
|
-
// ============================================================
|
|
31
|
-
import { SKILLS } from '../skills/content.js';
|
|
32
|
-
/**
|
|
33
|
-
* Where each scope's CROSS-MODEL list lives.
|
|
34
|
-
*
|
|
35
|
-
* One skill per scope on purpose: these are the two lists that are GENERIC to
|
|
36
|
-
* their modality (Stable-Diffusion-era tag soup for images, quality
|
|
37
|
-
* incantations for video), not model-specific quirks. A per-model list cannot
|
|
38
|
-
* ride the op DESCRIPTION — a description is one static string for every call,
|
|
39
|
-
* so it cannot change with the `model` argument. That is what
|
|
40
|
-
* `bannedTokensForSkill` below is for: the per-model list rides the estimate
|
|
41
|
-
* RESULT, where the model has just been named.
|
|
42
|
-
*/
|
|
43
|
-
const BANNED_TOKEN_SOURCES = [
|
|
44
|
-
{ skill: 'slates-prompting-nano-banana-2', scope: 'image' },
|
|
45
|
-
{ skill: 'slates-prompting-seedance', scope: 'video' },
|
|
46
|
-
];
|
|
47
|
-
/**
|
|
48
|
-
* 🚨 THE ENFORCEMENT THAT WORKED COVERED TWO SKILLS OF FIFTEEN.
|
|
49
|
-
*
|
|
50
|
-
* `describeBannedTokens('image')` was Nano Banana's list and `('video')` was
|
|
51
|
-
* Seedance's, so a Veo, Kling, LTX, MiniMax, FLUX, Seedream, GPT-Image or audio
|
|
52
|
-
* generation was matched against another model's never-use list and its own was
|
|
53
|
-
* enforced by nothing — while four skills (content-policy, lip-sync,
|
|
54
|
-
* minimax-h3, motion-transfer) carried never-use prose with no markers at all,
|
|
55
|
-
* which is a rule an LLM has to notice.
|
|
56
|
-
*
|
|
57
|
-
* Every skill that carries an `@banned` block now contributes to a per-skill
|
|
58
|
-
* list, delivered on the estimate result beside the craft card. The two above
|
|
59
|
-
* stay ALSO on the op descriptions, because a modality-wide list is true of
|
|
60
|
-
* every call that op can make.
|
|
61
|
-
*/
|
|
62
|
-
function extractPerSkill() {
|
|
63
|
-
const out = new Map();
|
|
64
|
-
for (const [skill, content] of Object.entries(SKILLS)) {
|
|
65
|
-
// Cheap pre-test: only pay the regex for files that carry the marker.
|
|
66
|
-
if (!content.includes('@banned:start'))
|
|
67
|
-
continue;
|
|
68
|
-
const scope = inferScope(skill);
|
|
69
|
-
out.set(skill, extractFromSkill(skill).map((token) => ({ token, skill, scope })));
|
|
70
|
-
}
|
|
71
|
-
return out;
|
|
72
|
-
}
|
|
73
|
-
/** Image-lane skills prompt for pixels; everything else is a time-based lane.
|
|
74
|
-
* Only used to tag a token for the warning text — the per-skill list is
|
|
75
|
-
* matched by SKILL, never by scope, so a wrong guess here cannot mis-enforce. */
|
|
76
|
-
function inferScope(skill) {
|
|
77
|
-
return /nano-banana|gpt-image|flux|seedream/.test(skill) ? 'image' : 'video';
|
|
78
|
-
}
|
|
79
|
-
const FENCE_RE = /<!--\s*@banned:start\s*-->([\s\S]*?)<!--\s*@banned:end\s*-->/g;
|
|
80
|
-
const HTML_COMMENT_RE = /<!--[\s\S]*?-->/g;
|
|
81
|
-
const BACKTICKED_RE = /`([^`\n]+)`/g;
|
|
82
|
-
/**
|
|
83
|
-
* Pull every backticked phrase out of a skill's fenced block(s).
|
|
84
|
-
*
|
|
85
|
-
* HTML comments are stripped FIRST: the fence carries a "MACHINE-READ" note to
|
|
86
|
-
* whoever edits the skill next, and that note itself contains backticks.
|
|
1
|
+
/** Model-specific prompt advice, extracted from each skill's @banned blocks.
|
|
2
|
+
* Warnings never rewrite or block a prompt. No model's list is universal.
|
|
87
3
|
*/
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
out.push(token);
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
if (fences === 0) {
|
|
109
|
-
throw new Error(`[banned-tokens] ${skill}.md has no <!-- @banned:start --> / <!-- @banned:end --> block. ` +
|
|
110
|
-
`The op description and the prompt warnings are GENERATED from it — restore the markers, ` +
|
|
111
|
-
`or drop the skill from BANNED_TOKEN_SOURCES.`);
|
|
112
|
-
}
|
|
113
|
-
if (out.length === 0) {
|
|
114
|
-
throw new Error(`[banned-tokens] ${skill}.md has a @banned block with no backticked tokens in it. ` +
|
|
115
|
-
`An empty list would silently disable the check instead of failing it.`);
|
|
116
|
-
}
|
|
117
|
-
return out;
|
|
118
|
-
}
|
|
119
|
-
/** Every banned token, in skill-document order. Integrity asserted at load. */
|
|
120
|
-
export const BANNED_PROMPT_TOKENS = BANNED_TOKEN_SOURCES.flatMap(({ skill, scope }) => extractFromSkill(skill).map((token) => ({ token, skill, scope })));
|
|
121
|
-
const byScope = new Map();
|
|
122
|
-
for (const entry of BANNED_PROMPT_TOKENS) {
|
|
123
|
-
const list = byScope.get(entry.scope) ?? [];
|
|
124
|
-
list.push(entry);
|
|
125
|
-
byScope.set(entry.scope, list);
|
|
126
|
-
}
|
|
127
|
-
export function bannedTokensFor(scope) {
|
|
128
|
-
return byScope.get(scope) ?? [];
|
|
129
|
-
}
|
|
130
|
-
/** Regex cache — one word-boundary matcher per token, built once. */
|
|
4
|
+
import { SKILLS } from '../skills/content.js';
|
|
5
|
+
const bySkill = new Map();
|
|
6
|
+
for (const [skill, content] of Object.entries(SKILLS)) {
|
|
7
|
+
const fences = [...content.matchAll(/<!--\s*@banned:start\s*-->([\s\S]*?)<!--\s*@banned:end\s*-->/g)];
|
|
8
|
+
if (!fences.length)
|
|
9
|
+
continue;
|
|
10
|
+
const tokens = [...new Set(fences.flatMap((f) => [...f[1].replace(/<!--[\s\S]*?-->/g, '').matchAll(/`([^`\n]+)`/g)].map((m) => m[1].trim())))];
|
|
11
|
+
if (!tokens.length)
|
|
12
|
+
throw new Error(`${skill}: @banned block contains no tokens`);
|
|
13
|
+
const scope = /nano-banana|gpt-image|flux|seedream/.test(skill) ? 'image' : 'video';
|
|
14
|
+
bySkill.set(skill, tokens.map((token) => ({ token, skill, scope })));
|
|
15
|
+
}
|
|
16
|
+
/** Compatibility exports: there is no cross-model blacklist. */
|
|
17
|
+
export const BANNED_PROMPT_TOKENS = Object.freeze([]);
|
|
18
|
+
export function bannedTokensFor(_scope) { return BANNED_PROMPT_TOKENS; }
|
|
19
|
+
export function describeBannedTokens(_scope) { return ''; }
|
|
20
|
+
export function bannedTokensForSkill(skill) { return bySkill.get(skill) ?? []; }
|
|
131
21
|
const matchers = new Map();
|
|
132
22
|
function matcherFor(token) {
|
|
133
|
-
let
|
|
134
|
-
if (!
|
|
23
|
+
let matcher = matchers.get(token);
|
|
24
|
+
if (!matcher) {
|
|
135
25
|
const escaped = token.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
// word character today; if one ever starts with punctuation, \b would
|
|
139
|
-
// anchor wrong — the load-time check below is what would catch it.
|
|
140
|
-
re = new RegExp(`\\b${escaped}\\b`, 'i');
|
|
141
|
-
matchers.set(token, re);
|
|
142
|
-
}
|
|
143
|
-
return re;
|
|
144
|
-
}
|
|
145
|
-
for (const { token, skill } of BANNED_PROMPT_TOKENS) {
|
|
146
|
-
if (!/^\w/.test(token) || !/\w$/.test(token)) {
|
|
147
|
-
throw new Error(`[banned-tokens] ${skill}: token ${JSON.stringify(token)} does not start and end with a word ` +
|
|
148
|
-
`character, so the \\b word-boundary match would never fire. Rewrite the entry or teach ` +
|
|
149
|
-
`matcherFor() the new shape.`);
|
|
26
|
+
matcher = new RegExp(`(?<!\\w)${escaped}(?!\\w)`, 'i');
|
|
27
|
+
matchers.set(token, matcher);
|
|
150
28
|
}
|
|
29
|
+
return matcher;
|
|
151
30
|
}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
/** The never-use list a single skill declares. Empty for a skill with no block. */
|
|
155
|
-
export function bannedTokensForSkill(skill) {
|
|
156
|
-
return bySkill.get(skill) ?? [];
|
|
31
|
+
export function findBannedTokens(prompt, _scope, skill) {
|
|
32
|
+
return skill ? bannedTokensForSkill(skill).filter((b) => matcherFor(b.token).test(prompt)) : [];
|
|
157
33
|
}
|
|
158
|
-
/**
|
|
159
|
-
* A single model's never-use list, for the estimate RESULT.
|
|
160
|
-
*
|
|
161
|
-
* Deliberately NOT the cross-model list — that one already rides the op
|
|
162
|
-
* description on every call. This is the half that could not: the quirk that is
|
|
163
|
-
* true of Veo and false of Kling.
|
|
164
|
-
*/
|
|
165
34
|
export function describeBannedTokensForSkill(skill) {
|
|
166
35
|
const list = bannedTokensForSkill(skill);
|
|
167
|
-
|
|
168
|
-
return '';
|
|
169
|
-
return (`NEVER put these in a ${skill.replace('slates-prompting-', '')} prompt: ` +
|
|
170
|
-
list.map((b) => `"${b.token}"`).join(', ') +
|
|
171
|
-
`. Describe specifically instead (${skill}).`);
|
|
36
|
+
return list.length ? `Avoid these phrases for ${skill}: ${list.map((b) => `"${b.token}"`).join(', ')}. Describe the intended result specifically.` : '';
|
|
172
37
|
}
|
|
173
|
-
/** The tokens a submitted prompt actually contains. `skill` adds that model's
|
|
174
|
-
* own list to the modality-wide one — the two overlap for nano-banana-2 and
|
|
175
|
-
* seedance, so hits are deduplicated by token. */
|
|
176
|
-
export function findBannedTokens(prompt, scope, skill) {
|
|
177
|
-
const candidates = [...bannedTokensFor(scope), ...(skill ? bannedTokensForSkill(skill) : [])];
|
|
178
|
-
const seen = new Set();
|
|
179
|
-
const hits = [];
|
|
180
|
-
for (const b of candidates) {
|
|
181
|
-
if (seen.has(b.token))
|
|
182
|
-
continue;
|
|
183
|
-
seen.add(b.token);
|
|
184
|
-
if (matcherFor(b.token).test(prompt))
|
|
185
|
-
hits.push(b);
|
|
186
|
-
}
|
|
187
|
-
return hits;
|
|
188
|
-
}
|
|
189
|
-
/**
|
|
190
|
-
* The list as it appears INSIDE an op description — always in context, on both
|
|
191
|
-
* surfaces, with no call required to see it. Generated, never hand-typed.
|
|
192
|
-
*/
|
|
193
|
-
export function describeBannedTokens(scope) {
|
|
194
|
-
const list = bannedTokensFor(scope);
|
|
195
|
-
if (list.length === 0)
|
|
196
|
-
return '';
|
|
197
|
-
const skills = [...new Set(list.map((b) => b.skill))].join(' / ');
|
|
198
|
-
return (`NEVER put these in a prompt (they measurably degrade output — full rationale in ${skills}): ` +
|
|
199
|
-
list.map((b) => `"${b.token}"`).join(', ') +
|
|
200
|
-
`. Describe specifically instead.`);
|
|
201
|
-
}
|
|
202
|
-
/**
|
|
203
|
-
* Non-blocking warning for a submitted prompt. Empty string when clean.
|
|
204
|
-
*
|
|
205
|
-
* Returned in the op RESULT — the one place the agent cannot avoid reading —
|
|
206
|
-
* rather than raised as an error. The generation proceeds either way: the
|
|
207
|
-
* sandbox doctrine says make state visible, never block.
|
|
208
|
-
*/
|
|
209
38
|
export function bannedTokenWarning(prompt, scope, skill) {
|
|
210
39
|
const hits = findBannedTokens(prompt, scope, skill);
|
|
211
|
-
if (hits.length
|
|
40
|
+
if (!hits.length)
|
|
212
41
|
return '';
|
|
213
|
-
|
|
214
|
-
return (`⚠️ PROMPT WARNING: your prompt contains ${hits.map((b) => `"${b.token}"`).join(', ')} — ` +
|
|
215
|
-
`on the never-use list in ${skills}. Not blocked, and this generation ran as submitted. ` +
|
|
216
|
-
`Load that guide with slates_get_prompting_guide and rewrite with specific description ` +
|
|
217
|
-
`(named lens, light direction, stock, composition) before the next generation.`);
|
|
42
|
+
return `⚠️ PROMPT WARNING: ${hits.map((b) => `"${b.token}"`).join(', ')} appear in ${skill}'s avoid list. This warning does not change or block your prompt. Describe the intended result specifically; query that guide for details.`;
|
|
218
43
|
}
|
|
219
44
|
//# sourceMappingURL=banned-tokens.js.map
|
|
@@ -57,7 +57,7 @@ function extractCard(skill, content) {
|
|
|
57
57
|
if (body.length > CRAFT_CARD_CEILING) {
|
|
58
58
|
throw new Error(`[craft-cards] ${skill}.md's @card block is ${body.length} chars, over the ` +
|
|
59
59
|
`${CRAFT_CARD_CEILING} ceiling. A card rides EVERY estimate result for that model — ` +
|
|
60
|
-
`move the overflow into the body of the skill,
|
|
60
|
+
`move the overflow into the body of the skill, retrieved with slates_get_prompting_guide depth: full.`);
|
|
61
61
|
}
|
|
62
62
|
return body;
|
|
63
63
|
}
|
|
@@ -77,6 +77,6 @@ export function describeCraftCard(skill) {
|
|
|
77
77
|
const card = craftCard(skill);
|
|
78
78
|
if (!card)
|
|
79
79
|
return '';
|
|
80
|
-
return `${card}\n\nFull guide (examples, failure modes, sources): slates_get_prompting_guide("${skill}").`;
|
|
80
|
+
return `${card}\n\nFull guide (examples, failure modes, sources): slates_get_prompting_guide({topic: "${skill}", depth: "full"}); use query for one section.`;
|
|
81
81
|
}
|
|
82
82
|
//# sourceMappingURL=craft-cards.js.map
|