@miraiclip/assistant 0.2.0 → 0.4.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 +21 -21
- package/README.md +23 -23
- package/dist/index.cjs +733 -41
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +138 -4
- package/dist/index.d.ts +138 -4
- package/dist/index.js +736 -41
- package/dist/index.js.map +1 -1
- package/package.json +6 -5
package/dist/index.d.cts
CHANGED
|
@@ -17,6 +17,12 @@ interface ToolCall {
|
|
|
17
17
|
*/
|
|
18
18
|
meta?: Record<string, unknown>;
|
|
19
19
|
}
|
|
20
|
+
/** An image the model looks at (a rendered preview a tool returns): base64 bytes and their type. */
|
|
21
|
+
interface ChatImage {
|
|
22
|
+
mimeType: string;
|
|
23
|
+
/** Base64, no `data:` prefix. */
|
|
24
|
+
data: string;
|
|
25
|
+
}
|
|
20
26
|
type ChatMessage = {
|
|
21
27
|
role: "system";
|
|
22
28
|
content: string;
|
|
@@ -27,11 +33,14 @@ type ChatMessage = {
|
|
|
27
33
|
role: "assistant";
|
|
28
34
|
content: string;
|
|
29
35
|
toolCalls?: ToolCall[];
|
|
30
|
-
}
|
|
36
|
+
}
|
|
37
|
+
/** `images`: pictures that come with the result (e.g. rendered frames), for models that can see. */
|
|
38
|
+
| {
|
|
31
39
|
role: "tool";
|
|
32
40
|
toolCallId: string;
|
|
33
41
|
name: string;
|
|
34
42
|
content: string;
|
|
43
|
+
images?: ChatImage[];
|
|
35
44
|
};
|
|
36
45
|
/** A tool as the model sees it: name, description and a JSON Schema for its input. */
|
|
37
46
|
interface ToolSpec {
|
|
@@ -153,9 +162,21 @@ interface OpenAIChatModelOptions {
|
|
|
153
162
|
label?: string;
|
|
154
163
|
fetch?: FetchLike;
|
|
155
164
|
}
|
|
165
|
+
type OpenAIPart = {
|
|
166
|
+
type: "text";
|
|
167
|
+
text: string;
|
|
168
|
+
} | {
|
|
169
|
+
type: "image_url";
|
|
170
|
+
image_url: {
|
|
171
|
+
url: string;
|
|
172
|
+
};
|
|
173
|
+
};
|
|
156
174
|
type OpenAIMessage = {
|
|
157
175
|
role: "system" | "user";
|
|
158
176
|
content: string;
|
|
177
|
+
} | {
|
|
178
|
+
role: "user";
|
|
179
|
+
content: OpenAIPart[];
|
|
159
180
|
} | {
|
|
160
181
|
role: "assistant";
|
|
161
182
|
content: string | null;
|
|
@@ -221,6 +242,14 @@ interface AnthropicChatModelOptions {
|
|
|
221
242
|
label?: string;
|
|
222
243
|
fetch?: FetchLike;
|
|
223
244
|
}
|
|
245
|
+
type ImageBlock = {
|
|
246
|
+
type: "image";
|
|
247
|
+
source: {
|
|
248
|
+
type: "base64";
|
|
249
|
+
media_type: string;
|
|
250
|
+
data: string;
|
|
251
|
+
};
|
|
252
|
+
};
|
|
224
253
|
type Block = {
|
|
225
254
|
type: "text";
|
|
226
255
|
text: string;
|
|
@@ -232,7 +261,10 @@ type Block = {
|
|
|
232
261
|
} | {
|
|
233
262
|
type: "tool_result";
|
|
234
263
|
tool_use_id: string;
|
|
235
|
-
content: string
|
|
264
|
+
content: string | ({
|
|
265
|
+
type: "text";
|
|
266
|
+
text: string;
|
|
267
|
+
} | ImageBlock)[];
|
|
236
268
|
} | {
|
|
237
269
|
type: "thinking";
|
|
238
270
|
thinking: string;
|
|
@@ -300,6 +332,10 @@ type Part = {
|
|
|
300
332
|
name: string;
|
|
301
333
|
response: Record<string, unknown>;
|
|
302
334
|
};
|
|
335
|
+
inlineData?: {
|
|
336
|
+
mimeType: string;
|
|
337
|
+
data: string;
|
|
338
|
+
};
|
|
303
339
|
};
|
|
304
340
|
type GeminiContent = {
|
|
305
341
|
role: "user" | "model";
|
|
@@ -550,16 +586,32 @@ interface UnknownFields {
|
|
|
550
586
|
/** Unknown payload fields for a command, judged against the best-matching schema branch. */
|
|
551
587
|
declare function unknownFields(schema: unknown, payload: unknown): UnknownFields | null;
|
|
552
588
|
|
|
589
|
+
/**
|
|
590
|
+
* Checks an html clip's template the way the renderer will read it: as XML
|
|
591
|
+
* (it rasterizes through an SVG `foreignObject`). Markup that isn't
|
|
592
|
+
* well-formed renders nothing, silently, so the assistant rejects it up front
|
|
593
|
+
* with an error the model can fix.
|
|
594
|
+
*/
|
|
595
|
+
/** Why the markup won't parse as XML, or undefined when it's well-formed. */
|
|
596
|
+
declare function markupProblem(markup: string): string | undefined;
|
|
597
|
+
/** `asset:<id>` references in a template. */
|
|
598
|
+
declare function assetRefs(markup: string): string[];
|
|
599
|
+
|
|
553
600
|
/** What a tool's `run` gets. `project` is the turn's working copy. */
|
|
554
601
|
interface ToolContext {
|
|
555
602
|
project: Project;
|
|
556
603
|
signal?: AbortSignal;
|
|
557
604
|
}
|
|
558
|
-
/**
|
|
605
|
+
/**
|
|
606
|
+
* A tool's answer. `changes` are human-readable lines for the app's "what
|
|
607
|
+
* changed" list. `images` go to the model with the result, so it can look at
|
|
608
|
+
* what it made (rendered frames); models that can't see get the text only.
|
|
609
|
+
*/
|
|
559
610
|
type ToolOutput = {
|
|
560
611
|
ok: true;
|
|
561
612
|
result?: unknown;
|
|
562
613
|
changes?: string[];
|
|
614
|
+
images?: ChatImage[];
|
|
563
615
|
} | {
|
|
564
616
|
ok: false;
|
|
565
617
|
error: unknown;
|
|
@@ -590,6 +642,13 @@ interface EditorToolsOptions {
|
|
|
590
642
|
transitionKinds?: string[];
|
|
591
643
|
/** The command catalog to offer in apply_commands (default: the built-ins). Pass `project.commandCatalog()` when you register custom commands. */
|
|
592
644
|
commandCatalog?: Record<string, unknown>;
|
|
645
|
+
/**
|
|
646
|
+
* Runs the continuous-shot check over the document (e.g. `checkShot` from `@miraiclip/server-export`, or the app's
|
|
647
|
+
* in-browser equivalent). The `check_sequence` tool is offered only when this is given, because the check needs a browser.
|
|
648
|
+
*/
|
|
649
|
+
checkSequence?: (doc: ProjectDocument, options: {
|
|
650
|
+
clipId?: string;
|
|
651
|
+
}) => Promise<unknown>;
|
|
593
652
|
}
|
|
594
653
|
/**
|
|
595
654
|
* The tools that edit a Miraiclip project: read state, look up a command's
|
|
@@ -642,12 +701,75 @@ type CommitResult = {
|
|
|
642
701
|
/** Replay a fork's commands onto the real project as one undoable step. */
|
|
643
702
|
declare function commitFork(project: Project, fork: RecordingProject, label?: string): CommitResult;
|
|
644
703
|
|
|
704
|
+
/**
|
|
705
|
+
* Skills: playbooks for bigger jobs (a launch video, captions, a reformat),
|
|
706
|
+
* loaded by the model only when a request needs one.
|
|
707
|
+
*
|
|
708
|
+
* The system prompt lists each skill's name and description. The model calls
|
|
709
|
+
* `load_skill` to read one, and `read_skill_file` for the reference files it
|
|
710
|
+
* points to, so the prompt stays small however many skills there are. An app
|
|
711
|
+
* can also start a request with a skill already loaded (`TurnOptions.skills`),
|
|
712
|
+
* e.g. from a button.
|
|
713
|
+
*
|
|
714
|
+
* Skills are plain Markdown with a front matter (`name`, `description`), the
|
|
715
|
+
* same shape as Claude Code skills. `MIRAICLIP_SKILLS` are the Miraiclip
|
|
716
|
+
* plugin's skills, in their editor versions.
|
|
717
|
+
*/
|
|
718
|
+
interface AssistantSkill {
|
|
719
|
+
/** Lowercase letters, digits and dashes, e.g. "captions". */
|
|
720
|
+
name: string;
|
|
721
|
+
/** When to use it, in one or two sentences. The model picks skills by this. */
|
|
722
|
+
description: string;
|
|
723
|
+
/** The playbook (Markdown, without the front matter). */
|
|
724
|
+
instructions: string;
|
|
725
|
+
/** Reference files the playbook points to, by relative path ("reference/craft.md"). */
|
|
726
|
+
files?: Readonly<Record<string, string>>;
|
|
727
|
+
}
|
|
728
|
+
declare function defineSkill(skill: AssistantSkill): AssistantSkill;
|
|
729
|
+
/** Split `---\nkey: value\n---\nbody` into its fields and body. Values may be quoted. */
|
|
730
|
+
declare function parseFrontMatter(markdown: string): {
|
|
731
|
+
data: Record<string, string>;
|
|
732
|
+
body: string;
|
|
733
|
+
};
|
|
734
|
+
/** One skill from its Markdown (front matter `name` and `description`). */
|
|
735
|
+
declare function parseSkill(markdown: string, options?: {
|
|
736
|
+
name?: string;
|
|
737
|
+
description?: string;
|
|
738
|
+
files?: Record<string, string>;
|
|
739
|
+
}): AssistantSkill;
|
|
740
|
+
interface SkillsFromFilesOptions {
|
|
741
|
+
/**
|
|
742
|
+
* Which file in a skill folder is the playbook, in order of preference.
|
|
743
|
+
* Default `["SKILL.md"]`. The Miraiclip plugin keeps the Claude Code
|
|
744
|
+
* version in SKILL.md and the in-editor version in EDITOR.md, so an editor
|
|
745
|
+
* passes `["EDITOR.md"]` (folders without one are skipped). The other
|
|
746
|
+
* entry file's front matter fills in a missing name or description.
|
|
747
|
+
*/
|
|
748
|
+
entry?: string[];
|
|
749
|
+
}
|
|
750
|
+
/**
|
|
751
|
+
* Skills from a folder of skill folders, given as `{ path: text }` — e.g.
|
|
752
|
+
* Vite's `import.meta.glob("./skills/**\/*.md", { query: "?raw", import: "default", eager: true })`.
|
|
753
|
+
* Every other `.md` in a skill's folder becomes one of its files.
|
|
754
|
+
*/
|
|
755
|
+
declare function skillsFromFiles(files: Record<string, string>, options?: SkillsFromFilesOptions): AssistantSkill[];
|
|
756
|
+
/** The skill list for the system prompt. */
|
|
757
|
+
declare function describeSkills(skills: readonly AssistantSkill[]): string;
|
|
758
|
+
/** `load_skill` and `read_skill_file` for these skills. */
|
|
759
|
+
declare function skillTools(skills: readonly AssistantSkill[]): AssistantTool[];
|
|
760
|
+
|
|
645
761
|
interface AssistantOptions {
|
|
646
762
|
model: ChatModel;
|
|
647
763
|
/** Default `editorTools()`. Add your own (audio, captions, stock media…). */
|
|
648
764
|
tools?: AssistantTool[];
|
|
649
765
|
/** Extra system instructions (brand voice, house rules). */
|
|
650
766
|
instructions?: string;
|
|
767
|
+
/**
|
|
768
|
+
* Playbooks the model can load when a request needs one (e.g.
|
|
769
|
+
* `MIRAICLIP_SKILLS`). Adds `load_skill` and `read_skill_file` to the tools
|
|
770
|
+
* and lists each skill's name and description in the system prompt.
|
|
771
|
+
*/
|
|
772
|
+
skills?: readonly AssistantSkill[];
|
|
651
773
|
/** Model round-trips per request (default 12). */
|
|
652
774
|
maxSteps?: number;
|
|
653
775
|
/** Model id when the adapter serves several. */
|
|
@@ -669,6 +791,8 @@ type AssistantEvent = {
|
|
|
669
791
|
ok: boolean;
|
|
670
792
|
changes?: string[];
|
|
671
793
|
error?: string;
|
|
794
|
+
/** Images the tool returned (previews, storyboards) — the model sees them too; apps may show them. */
|
|
795
|
+
images?: ChatImage[];
|
|
672
796
|
} | {
|
|
673
797
|
type: "step";
|
|
674
798
|
index: number;
|
|
@@ -684,6 +808,13 @@ interface TurnOptions {
|
|
|
684
808
|
onEvent?: (event: AssistantEvent) => void;
|
|
685
809
|
/** History label for the undo step (default "Assistant: <request>"). */
|
|
686
810
|
label?: string;
|
|
811
|
+
/**
|
|
812
|
+
* Skills to load up front for this request, by name (e.g. the user picked
|
|
813
|
+
* "Captions" in the app). Their playbooks go into the system prompt, so the
|
|
814
|
+
* model starts on them without a `load_skill` call. Unknown names are
|
|
815
|
+
* ignored.
|
|
816
|
+
*/
|
|
817
|
+
skills?: readonly string[];
|
|
687
818
|
}
|
|
688
819
|
interface AssistantTurn {
|
|
689
820
|
/** The model's final answer to the user. */
|
|
@@ -714,6 +845,9 @@ interface Assistant {
|
|
|
714
845
|
declare const DEFAULT_INSTRUCTIONS = "You are the editing assistant inside a video editor. You change the user's project by calling tools; every change you make lands as ONE undo step when you finish, so act confidently.\n\nHow to work:\n- The current project is summarized below. Clip, track and asset ids there are what tools expect. Call get_state to re-read it after big changes.\n- Prefer the high-level tools when they fit (add_transition, animate_clip, add_effect, set_effects_enabled, set_background, trim_clip, set_keyframes, close_gaps, and any audio or media tools). Call tools directly; apply_commands takes only editing commands like \"clip/add\", never tool names. Use apply_commands for everything else, batching related commands; look up a command's payload with get_command_schema the first time you use it, and use only the fields it lists.\n- Fading a picture (text, image, logo, video) in or out is animate_clip (in / out: fade). fadeInUs / fadeOutUs are audio fades. \"Fade the video in at the start / out at the end\" means the first clip's entrance and the last clip's exit.\n- Constant values are set directly with clip/set-property: rotation (\"rotate 45\u00B0\", \"tilt\"), volume (\"lower to 30%\", \"louder\"), position, size, opacity. Only values that CHANGE over a time range (\"duck the music between 10 and 15 s\", \"fade to silence between 18 and 20 s\", \"spin one full turn\", \"pan across\") are keyframes: set_keyframes, with times in timeline seconds. Remove an animation with keyframe/clear.\n- \"Cuts\" are the ones listed in the project summary; use their times (e.g. one sound per cut).\n- \"Add N more seconds of footage\" adds a new clip (clip/add with trimStartUs for the source point) after the last one; it does not stretch an existing clip.\n- Caption looks (box behind the text, outline, shadow, colors, word preset) are the caption clip's style (clip/set-property { style }).\n- \"The whole video\" means from 0 to the composition length (trim_clip startSeconds / endSeconds).\n- A solid color background behind everything is set_background (add, recolor, remove). Other html clips are recolored through the params their template uses (shown in the clip details). A new track goes on top unless track/add gets index 0 (the bottom).\n- \"Replace X with Y\" removes X and adds Y in the same turn, whichever tool adds Y (audio tools take replaceClipId, which does both).\n- Solo / mute / lock / hide a track with track/set-property (solo, muted, locked, hidden). \"Solo X\" is solo: true on X, not muting the others.\n- Relative requests (\"bigger\", \"louder\", \"a bit brighter\", \"twice as big\") start from the current values in the clip details below: make a visible change in the asked direction (about 25% for \"bigger\"/\"smaller\", \u00D72 for \"twice\").\n- When something is selected, \"this\", \"it\", \"the clip\" and any request that names no target mean ONLY the selection, even with words like \"at the end\" (the end of that clip). Edit nothing else. \"Here\" / \"now\" / \"this point\" mean the playhead. \"Clips\" without a kind mean the video clips on the main video track.\n- \"Again\" / \"also\" / \"another\" mean keep the original and add a copy (clip/duplicate, or clip/add with the same asset); never move the original. \"Instead\" means move or replace.\n- Removing a clip leaves a gap; when asked to close it, also run close_gaps (or trim_clip with ripple).\n- Commands use integer microseconds (1 second = 1000000). High-level tools take seconds.\n- Positions (transform x, y) are fractions of the frame: 0.5, 0.5 is the center.\n- Only reference media that exists in the project or that a tool returned. Never invent file URLs.\n- If a tool fails, read the error, fix the input and retry. A failed apply_commands batch applied NONE of its commands: resend all of them, corrected. If something can't be done, say why.\n- If the request is ambiguous in a way that matters, ask one short question instead of guessing.\n\nWhen you're done, reply in one to three short sentences: what you changed, in plain words (times in seconds, names over ids). Describe only edits your tools reported as applied; if a tool says something changed nothing or failed, fix it or say so. No markdown headings.";
|
|
715
846
|
declare function createAssistant(options: AssistantOptions): Assistant;
|
|
716
847
|
|
|
848
|
+
/** The Miraiclip plugin's skills, in their in-editor versions: pass to `createAssistant({ skills })`. */
|
|
849
|
+
declare const MIRAICLIP_SKILLS: readonly AssistantSkill[];
|
|
850
|
+
|
|
717
851
|
type ScriptStep = string | {
|
|
718
852
|
text?: string;
|
|
719
853
|
toolCalls?: (Omit<ToolCall, "id"> & {
|
|
@@ -731,4 +865,4 @@ declare function scriptedChatModel(steps: ScriptStep[], options?: {
|
|
|
731
865
|
requests: ChatRequest[];
|
|
732
866
|
};
|
|
733
867
|
|
|
734
|
-
export { AI_PROVIDERS, type AiProviderInfo, type AnthropicChatModelOptions, type Assistant, type AssistantEvent, type AssistantOptions, type AssistantTool, type AssistantTurn, BACKGROUND_TEMPLATE, type ChatHandlerOptions, type ChatMessage, type ChatModel, ChatModelError, type ChatModelInfo, type ChatModelsFromEnvOptions, type ChatOptions, type ChatRequest, type ChatResponse, type ChatUsage, type CommitResult, type CreateChatModelOptions, DEFAULT_INSTRUCTIONS, type EditorToolsOptions, type FetchLike, type ForkOptions, type GeminiChatModelOptions, type ModelEntry, type OpenAIChatModelOptions, type ProviderApi, type RateLimitOptions, type RecordingProject, type RemoteChatModelOptions, type RemoteModelInfo, type RoutedChatModelOptions, type ScriptStep, type ToolCall, type ToolContext, type ToolOutput, type ToolSpec, type TurnOptions, USER_KEY_HEADERS, type UnknownFields, type UserCredentials, type UserKeyInfo, type UserKeyOptions, aiProvider, anthropicChatModel, applyChecked, applyCommandsSchema, chatModelsFromEnv, commitFork, createAssistant, createChatHandler, createChatModel, defineChatModel, defineTool, describeCommands, describeForAssistant, editorTools, forkProject, geminiChatModel, openAIChatModel, parseToolArguments, rateLimitedChatModel, remoteChatModel, retryDelayMs, routedChatModel, scriptedChatModel, splitModelRef, toAnthropicMessages, toGeminiContents, toOpenAIMessages, toolsFromDefinitions, unknownFields, userKeyHeaders, withExplicitIds };
|
|
868
|
+
export { AI_PROVIDERS, type AiProviderInfo, type AnthropicChatModelOptions, type Assistant, type AssistantEvent, type AssistantOptions, type AssistantSkill, type AssistantTool, type AssistantTurn, BACKGROUND_TEMPLATE, type ChatHandlerOptions, type ChatImage, type ChatMessage, type ChatModel, ChatModelError, type ChatModelInfo, type ChatModelsFromEnvOptions, type ChatOptions, type ChatRequest, type ChatResponse, type ChatUsage, type CommitResult, type CreateChatModelOptions, DEFAULT_INSTRUCTIONS, type EditorToolsOptions, type FetchLike, type ForkOptions, type GeminiChatModelOptions, MIRAICLIP_SKILLS, type ModelEntry, type OpenAIChatModelOptions, type ProviderApi, type RateLimitOptions, type RecordingProject, type RemoteChatModelOptions, type RemoteModelInfo, type RoutedChatModelOptions, type ScriptStep, type SkillsFromFilesOptions, type ToolCall, type ToolContext, type ToolOutput, type ToolSpec, type TurnOptions, USER_KEY_HEADERS, type UnknownFields, type UserCredentials, type UserKeyInfo, type UserKeyOptions, aiProvider, anthropicChatModel, applyChecked, applyCommandsSchema, assetRefs, chatModelsFromEnv, commitFork, createAssistant, createChatHandler, createChatModel, defineChatModel, defineSkill, defineTool, describeCommands, describeForAssistant, describeSkills, editorTools, forkProject, geminiChatModel, markupProblem, openAIChatModel, parseFrontMatter, parseSkill, parseToolArguments, rateLimitedChatModel, remoteChatModel, retryDelayMs, routedChatModel, scriptedChatModel, skillTools, skillsFromFiles, splitModelRef, toAnthropicMessages, toGeminiContents, toOpenAIMessages, toolsFromDefinitions, unknownFields, userKeyHeaders, withExplicitIds };
|
package/dist/index.d.ts
CHANGED
|
@@ -17,6 +17,12 @@ interface ToolCall {
|
|
|
17
17
|
*/
|
|
18
18
|
meta?: Record<string, unknown>;
|
|
19
19
|
}
|
|
20
|
+
/** An image the model looks at (a rendered preview a tool returns): base64 bytes and their type. */
|
|
21
|
+
interface ChatImage {
|
|
22
|
+
mimeType: string;
|
|
23
|
+
/** Base64, no `data:` prefix. */
|
|
24
|
+
data: string;
|
|
25
|
+
}
|
|
20
26
|
type ChatMessage = {
|
|
21
27
|
role: "system";
|
|
22
28
|
content: string;
|
|
@@ -27,11 +33,14 @@ type ChatMessage = {
|
|
|
27
33
|
role: "assistant";
|
|
28
34
|
content: string;
|
|
29
35
|
toolCalls?: ToolCall[];
|
|
30
|
-
}
|
|
36
|
+
}
|
|
37
|
+
/** `images`: pictures that come with the result (e.g. rendered frames), for models that can see. */
|
|
38
|
+
| {
|
|
31
39
|
role: "tool";
|
|
32
40
|
toolCallId: string;
|
|
33
41
|
name: string;
|
|
34
42
|
content: string;
|
|
43
|
+
images?: ChatImage[];
|
|
35
44
|
};
|
|
36
45
|
/** A tool as the model sees it: name, description and a JSON Schema for its input. */
|
|
37
46
|
interface ToolSpec {
|
|
@@ -153,9 +162,21 @@ interface OpenAIChatModelOptions {
|
|
|
153
162
|
label?: string;
|
|
154
163
|
fetch?: FetchLike;
|
|
155
164
|
}
|
|
165
|
+
type OpenAIPart = {
|
|
166
|
+
type: "text";
|
|
167
|
+
text: string;
|
|
168
|
+
} | {
|
|
169
|
+
type: "image_url";
|
|
170
|
+
image_url: {
|
|
171
|
+
url: string;
|
|
172
|
+
};
|
|
173
|
+
};
|
|
156
174
|
type OpenAIMessage = {
|
|
157
175
|
role: "system" | "user";
|
|
158
176
|
content: string;
|
|
177
|
+
} | {
|
|
178
|
+
role: "user";
|
|
179
|
+
content: OpenAIPart[];
|
|
159
180
|
} | {
|
|
160
181
|
role: "assistant";
|
|
161
182
|
content: string | null;
|
|
@@ -221,6 +242,14 @@ interface AnthropicChatModelOptions {
|
|
|
221
242
|
label?: string;
|
|
222
243
|
fetch?: FetchLike;
|
|
223
244
|
}
|
|
245
|
+
type ImageBlock = {
|
|
246
|
+
type: "image";
|
|
247
|
+
source: {
|
|
248
|
+
type: "base64";
|
|
249
|
+
media_type: string;
|
|
250
|
+
data: string;
|
|
251
|
+
};
|
|
252
|
+
};
|
|
224
253
|
type Block = {
|
|
225
254
|
type: "text";
|
|
226
255
|
text: string;
|
|
@@ -232,7 +261,10 @@ type Block = {
|
|
|
232
261
|
} | {
|
|
233
262
|
type: "tool_result";
|
|
234
263
|
tool_use_id: string;
|
|
235
|
-
content: string
|
|
264
|
+
content: string | ({
|
|
265
|
+
type: "text";
|
|
266
|
+
text: string;
|
|
267
|
+
} | ImageBlock)[];
|
|
236
268
|
} | {
|
|
237
269
|
type: "thinking";
|
|
238
270
|
thinking: string;
|
|
@@ -300,6 +332,10 @@ type Part = {
|
|
|
300
332
|
name: string;
|
|
301
333
|
response: Record<string, unknown>;
|
|
302
334
|
};
|
|
335
|
+
inlineData?: {
|
|
336
|
+
mimeType: string;
|
|
337
|
+
data: string;
|
|
338
|
+
};
|
|
303
339
|
};
|
|
304
340
|
type GeminiContent = {
|
|
305
341
|
role: "user" | "model";
|
|
@@ -550,16 +586,32 @@ interface UnknownFields {
|
|
|
550
586
|
/** Unknown payload fields for a command, judged against the best-matching schema branch. */
|
|
551
587
|
declare function unknownFields(schema: unknown, payload: unknown): UnknownFields | null;
|
|
552
588
|
|
|
589
|
+
/**
|
|
590
|
+
* Checks an html clip's template the way the renderer will read it: as XML
|
|
591
|
+
* (it rasterizes through an SVG `foreignObject`). Markup that isn't
|
|
592
|
+
* well-formed renders nothing, silently, so the assistant rejects it up front
|
|
593
|
+
* with an error the model can fix.
|
|
594
|
+
*/
|
|
595
|
+
/** Why the markup won't parse as XML, or undefined when it's well-formed. */
|
|
596
|
+
declare function markupProblem(markup: string): string | undefined;
|
|
597
|
+
/** `asset:<id>` references in a template. */
|
|
598
|
+
declare function assetRefs(markup: string): string[];
|
|
599
|
+
|
|
553
600
|
/** What a tool's `run` gets. `project` is the turn's working copy. */
|
|
554
601
|
interface ToolContext {
|
|
555
602
|
project: Project;
|
|
556
603
|
signal?: AbortSignal;
|
|
557
604
|
}
|
|
558
|
-
/**
|
|
605
|
+
/**
|
|
606
|
+
* A tool's answer. `changes` are human-readable lines for the app's "what
|
|
607
|
+
* changed" list. `images` go to the model with the result, so it can look at
|
|
608
|
+
* what it made (rendered frames); models that can't see get the text only.
|
|
609
|
+
*/
|
|
559
610
|
type ToolOutput = {
|
|
560
611
|
ok: true;
|
|
561
612
|
result?: unknown;
|
|
562
613
|
changes?: string[];
|
|
614
|
+
images?: ChatImage[];
|
|
563
615
|
} | {
|
|
564
616
|
ok: false;
|
|
565
617
|
error: unknown;
|
|
@@ -590,6 +642,13 @@ interface EditorToolsOptions {
|
|
|
590
642
|
transitionKinds?: string[];
|
|
591
643
|
/** The command catalog to offer in apply_commands (default: the built-ins). Pass `project.commandCatalog()` when you register custom commands. */
|
|
592
644
|
commandCatalog?: Record<string, unknown>;
|
|
645
|
+
/**
|
|
646
|
+
* Runs the continuous-shot check over the document (e.g. `checkShot` from `@miraiclip/server-export`, or the app's
|
|
647
|
+
* in-browser equivalent). The `check_sequence` tool is offered only when this is given, because the check needs a browser.
|
|
648
|
+
*/
|
|
649
|
+
checkSequence?: (doc: ProjectDocument, options: {
|
|
650
|
+
clipId?: string;
|
|
651
|
+
}) => Promise<unknown>;
|
|
593
652
|
}
|
|
594
653
|
/**
|
|
595
654
|
* The tools that edit a Miraiclip project: read state, look up a command's
|
|
@@ -642,12 +701,75 @@ type CommitResult = {
|
|
|
642
701
|
/** Replay a fork's commands onto the real project as one undoable step. */
|
|
643
702
|
declare function commitFork(project: Project, fork: RecordingProject, label?: string): CommitResult;
|
|
644
703
|
|
|
704
|
+
/**
|
|
705
|
+
* Skills: playbooks for bigger jobs (a launch video, captions, a reformat),
|
|
706
|
+
* loaded by the model only when a request needs one.
|
|
707
|
+
*
|
|
708
|
+
* The system prompt lists each skill's name and description. The model calls
|
|
709
|
+
* `load_skill` to read one, and `read_skill_file` for the reference files it
|
|
710
|
+
* points to, so the prompt stays small however many skills there are. An app
|
|
711
|
+
* can also start a request with a skill already loaded (`TurnOptions.skills`),
|
|
712
|
+
* e.g. from a button.
|
|
713
|
+
*
|
|
714
|
+
* Skills are plain Markdown with a front matter (`name`, `description`), the
|
|
715
|
+
* same shape as Claude Code skills. `MIRAICLIP_SKILLS` are the Miraiclip
|
|
716
|
+
* plugin's skills, in their editor versions.
|
|
717
|
+
*/
|
|
718
|
+
interface AssistantSkill {
|
|
719
|
+
/** Lowercase letters, digits and dashes, e.g. "captions". */
|
|
720
|
+
name: string;
|
|
721
|
+
/** When to use it, in one or two sentences. The model picks skills by this. */
|
|
722
|
+
description: string;
|
|
723
|
+
/** The playbook (Markdown, without the front matter). */
|
|
724
|
+
instructions: string;
|
|
725
|
+
/** Reference files the playbook points to, by relative path ("reference/craft.md"). */
|
|
726
|
+
files?: Readonly<Record<string, string>>;
|
|
727
|
+
}
|
|
728
|
+
declare function defineSkill(skill: AssistantSkill): AssistantSkill;
|
|
729
|
+
/** Split `---\nkey: value\n---\nbody` into its fields and body. Values may be quoted. */
|
|
730
|
+
declare function parseFrontMatter(markdown: string): {
|
|
731
|
+
data: Record<string, string>;
|
|
732
|
+
body: string;
|
|
733
|
+
};
|
|
734
|
+
/** One skill from its Markdown (front matter `name` and `description`). */
|
|
735
|
+
declare function parseSkill(markdown: string, options?: {
|
|
736
|
+
name?: string;
|
|
737
|
+
description?: string;
|
|
738
|
+
files?: Record<string, string>;
|
|
739
|
+
}): AssistantSkill;
|
|
740
|
+
interface SkillsFromFilesOptions {
|
|
741
|
+
/**
|
|
742
|
+
* Which file in a skill folder is the playbook, in order of preference.
|
|
743
|
+
* Default `["SKILL.md"]`. The Miraiclip plugin keeps the Claude Code
|
|
744
|
+
* version in SKILL.md and the in-editor version in EDITOR.md, so an editor
|
|
745
|
+
* passes `["EDITOR.md"]` (folders without one are skipped). The other
|
|
746
|
+
* entry file's front matter fills in a missing name or description.
|
|
747
|
+
*/
|
|
748
|
+
entry?: string[];
|
|
749
|
+
}
|
|
750
|
+
/**
|
|
751
|
+
* Skills from a folder of skill folders, given as `{ path: text }` — e.g.
|
|
752
|
+
* Vite's `import.meta.glob("./skills/**\/*.md", { query: "?raw", import: "default", eager: true })`.
|
|
753
|
+
* Every other `.md` in a skill's folder becomes one of its files.
|
|
754
|
+
*/
|
|
755
|
+
declare function skillsFromFiles(files: Record<string, string>, options?: SkillsFromFilesOptions): AssistantSkill[];
|
|
756
|
+
/** The skill list for the system prompt. */
|
|
757
|
+
declare function describeSkills(skills: readonly AssistantSkill[]): string;
|
|
758
|
+
/** `load_skill` and `read_skill_file` for these skills. */
|
|
759
|
+
declare function skillTools(skills: readonly AssistantSkill[]): AssistantTool[];
|
|
760
|
+
|
|
645
761
|
interface AssistantOptions {
|
|
646
762
|
model: ChatModel;
|
|
647
763
|
/** Default `editorTools()`. Add your own (audio, captions, stock media…). */
|
|
648
764
|
tools?: AssistantTool[];
|
|
649
765
|
/** Extra system instructions (brand voice, house rules). */
|
|
650
766
|
instructions?: string;
|
|
767
|
+
/**
|
|
768
|
+
* Playbooks the model can load when a request needs one (e.g.
|
|
769
|
+
* `MIRAICLIP_SKILLS`). Adds `load_skill` and `read_skill_file` to the tools
|
|
770
|
+
* and lists each skill's name and description in the system prompt.
|
|
771
|
+
*/
|
|
772
|
+
skills?: readonly AssistantSkill[];
|
|
651
773
|
/** Model round-trips per request (default 12). */
|
|
652
774
|
maxSteps?: number;
|
|
653
775
|
/** Model id when the adapter serves several. */
|
|
@@ -669,6 +791,8 @@ type AssistantEvent = {
|
|
|
669
791
|
ok: boolean;
|
|
670
792
|
changes?: string[];
|
|
671
793
|
error?: string;
|
|
794
|
+
/** Images the tool returned (previews, storyboards) — the model sees them too; apps may show them. */
|
|
795
|
+
images?: ChatImage[];
|
|
672
796
|
} | {
|
|
673
797
|
type: "step";
|
|
674
798
|
index: number;
|
|
@@ -684,6 +808,13 @@ interface TurnOptions {
|
|
|
684
808
|
onEvent?: (event: AssistantEvent) => void;
|
|
685
809
|
/** History label for the undo step (default "Assistant: <request>"). */
|
|
686
810
|
label?: string;
|
|
811
|
+
/**
|
|
812
|
+
* Skills to load up front for this request, by name (e.g. the user picked
|
|
813
|
+
* "Captions" in the app). Their playbooks go into the system prompt, so the
|
|
814
|
+
* model starts on them without a `load_skill` call. Unknown names are
|
|
815
|
+
* ignored.
|
|
816
|
+
*/
|
|
817
|
+
skills?: readonly string[];
|
|
687
818
|
}
|
|
688
819
|
interface AssistantTurn {
|
|
689
820
|
/** The model's final answer to the user. */
|
|
@@ -714,6 +845,9 @@ interface Assistant {
|
|
|
714
845
|
declare const DEFAULT_INSTRUCTIONS = "You are the editing assistant inside a video editor. You change the user's project by calling tools; every change you make lands as ONE undo step when you finish, so act confidently.\n\nHow to work:\n- The current project is summarized below. Clip, track and asset ids there are what tools expect. Call get_state to re-read it after big changes.\n- Prefer the high-level tools when they fit (add_transition, animate_clip, add_effect, set_effects_enabled, set_background, trim_clip, set_keyframes, close_gaps, and any audio or media tools). Call tools directly; apply_commands takes only editing commands like \"clip/add\", never tool names. Use apply_commands for everything else, batching related commands; look up a command's payload with get_command_schema the first time you use it, and use only the fields it lists.\n- Fading a picture (text, image, logo, video) in or out is animate_clip (in / out: fade). fadeInUs / fadeOutUs are audio fades. \"Fade the video in at the start / out at the end\" means the first clip's entrance and the last clip's exit.\n- Constant values are set directly with clip/set-property: rotation (\"rotate 45\u00B0\", \"tilt\"), volume (\"lower to 30%\", \"louder\"), position, size, opacity. Only values that CHANGE over a time range (\"duck the music between 10 and 15 s\", \"fade to silence between 18 and 20 s\", \"spin one full turn\", \"pan across\") are keyframes: set_keyframes, with times in timeline seconds. Remove an animation with keyframe/clear.\n- \"Cuts\" are the ones listed in the project summary; use their times (e.g. one sound per cut).\n- \"Add N more seconds of footage\" adds a new clip (clip/add with trimStartUs for the source point) after the last one; it does not stretch an existing clip.\n- Caption looks (box behind the text, outline, shadow, colors, word preset) are the caption clip's style (clip/set-property { style }).\n- \"The whole video\" means from 0 to the composition length (trim_clip startSeconds / endSeconds).\n- A solid color background behind everything is set_background (add, recolor, remove). Other html clips are recolored through the params their template uses (shown in the clip details). A new track goes on top unless track/add gets index 0 (the bottom).\n- \"Replace X with Y\" removes X and adds Y in the same turn, whichever tool adds Y (audio tools take replaceClipId, which does both).\n- Solo / mute / lock / hide a track with track/set-property (solo, muted, locked, hidden). \"Solo X\" is solo: true on X, not muting the others.\n- Relative requests (\"bigger\", \"louder\", \"a bit brighter\", \"twice as big\") start from the current values in the clip details below: make a visible change in the asked direction (about 25% for \"bigger\"/\"smaller\", \u00D72 for \"twice\").\n- When something is selected, \"this\", \"it\", \"the clip\" and any request that names no target mean ONLY the selection, even with words like \"at the end\" (the end of that clip). Edit nothing else. \"Here\" / \"now\" / \"this point\" mean the playhead. \"Clips\" without a kind mean the video clips on the main video track.\n- \"Again\" / \"also\" / \"another\" mean keep the original and add a copy (clip/duplicate, or clip/add with the same asset); never move the original. \"Instead\" means move or replace.\n- Removing a clip leaves a gap; when asked to close it, also run close_gaps (or trim_clip with ripple).\n- Commands use integer microseconds (1 second = 1000000). High-level tools take seconds.\n- Positions (transform x, y) are fractions of the frame: 0.5, 0.5 is the center.\n- Only reference media that exists in the project or that a tool returned. Never invent file URLs.\n- If a tool fails, read the error, fix the input and retry. A failed apply_commands batch applied NONE of its commands: resend all of them, corrected. If something can't be done, say why.\n- If the request is ambiguous in a way that matters, ask one short question instead of guessing.\n\nWhen you're done, reply in one to three short sentences: what you changed, in plain words (times in seconds, names over ids). Describe only edits your tools reported as applied; if a tool says something changed nothing or failed, fix it or say so. No markdown headings.";
|
|
715
846
|
declare function createAssistant(options: AssistantOptions): Assistant;
|
|
716
847
|
|
|
848
|
+
/** The Miraiclip plugin's skills, in their in-editor versions: pass to `createAssistant({ skills })`. */
|
|
849
|
+
declare const MIRAICLIP_SKILLS: readonly AssistantSkill[];
|
|
850
|
+
|
|
717
851
|
type ScriptStep = string | {
|
|
718
852
|
text?: string;
|
|
719
853
|
toolCalls?: (Omit<ToolCall, "id"> & {
|
|
@@ -731,4 +865,4 @@ declare function scriptedChatModel(steps: ScriptStep[], options?: {
|
|
|
731
865
|
requests: ChatRequest[];
|
|
732
866
|
};
|
|
733
867
|
|
|
734
|
-
export { AI_PROVIDERS, type AiProviderInfo, type AnthropicChatModelOptions, type Assistant, type AssistantEvent, type AssistantOptions, type AssistantTool, type AssistantTurn, BACKGROUND_TEMPLATE, type ChatHandlerOptions, type ChatMessage, type ChatModel, ChatModelError, type ChatModelInfo, type ChatModelsFromEnvOptions, type ChatOptions, type ChatRequest, type ChatResponse, type ChatUsage, type CommitResult, type CreateChatModelOptions, DEFAULT_INSTRUCTIONS, type EditorToolsOptions, type FetchLike, type ForkOptions, type GeminiChatModelOptions, type ModelEntry, type OpenAIChatModelOptions, type ProviderApi, type RateLimitOptions, type RecordingProject, type RemoteChatModelOptions, type RemoteModelInfo, type RoutedChatModelOptions, type ScriptStep, type ToolCall, type ToolContext, type ToolOutput, type ToolSpec, type TurnOptions, USER_KEY_HEADERS, type UnknownFields, type UserCredentials, type UserKeyInfo, type UserKeyOptions, aiProvider, anthropicChatModel, applyChecked, applyCommandsSchema, chatModelsFromEnv, commitFork, createAssistant, createChatHandler, createChatModel, defineChatModel, defineTool, describeCommands, describeForAssistant, editorTools, forkProject, geminiChatModel, openAIChatModel, parseToolArguments, rateLimitedChatModel, remoteChatModel, retryDelayMs, routedChatModel, scriptedChatModel, splitModelRef, toAnthropicMessages, toGeminiContents, toOpenAIMessages, toolsFromDefinitions, unknownFields, userKeyHeaders, withExplicitIds };
|
|
868
|
+
export { AI_PROVIDERS, type AiProviderInfo, type AnthropicChatModelOptions, type Assistant, type AssistantEvent, type AssistantOptions, type AssistantSkill, type AssistantTool, type AssistantTurn, BACKGROUND_TEMPLATE, type ChatHandlerOptions, type ChatImage, type ChatMessage, type ChatModel, ChatModelError, type ChatModelInfo, type ChatModelsFromEnvOptions, type ChatOptions, type ChatRequest, type ChatResponse, type ChatUsage, type CommitResult, type CreateChatModelOptions, DEFAULT_INSTRUCTIONS, type EditorToolsOptions, type FetchLike, type ForkOptions, type GeminiChatModelOptions, MIRAICLIP_SKILLS, type ModelEntry, type OpenAIChatModelOptions, type ProviderApi, type RateLimitOptions, type RecordingProject, type RemoteChatModelOptions, type RemoteModelInfo, type RoutedChatModelOptions, type ScriptStep, type SkillsFromFilesOptions, type ToolCall, type ToolContext, type ToolOutput, type ToolSpec, type TurnOptions, USER_KEY_HEADERS, type UnknownFields, type UserCredentials, type UserKeyInfo, type UserKeyOptions, aiProvider, anthropicChatModel, applyChecked, applyCommandsSchema, assetRefs, chatModelsFromEnv, commitFork, createAssistant, createChatHandler, createChatModel, defineChatModel, defineSkill, defineTool, describeCommands, describeForAssistant, describeSkills, editorTools, forkProject, geminiChatModel, markupProblem, openAIChatModel, parseFrontMatter, parseSkill, parseToolArguments, rateLimitedChatModel, remoteChatModel, retryDelayMs, routedChatModel, scriptedChatModel, skillTools, skillsFromFiles, splitModelRef, toAnthropicMessages, toGeminiContents, toOpenAIMessages, toolsFromDefinitions, unknownFields, userKeyHeaders, withExplicitIds };
|