@blinkk/root-cms 3.0.2 → 3.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app.js +5 -5
- package/dist/{chunk-3HARN4U6.js → chunk-7Z5IRD2G.js} +176 -83
- package/dist/{chunk-2BSW7SIH.js → chunk-N4K6ICFR.js} +4 -4
- package/dist/{chunk-BGTUWIV6.js → chunk-PNLLZXVY.js} +4 -4
- package/dist/{chunk-C245C557.js → chunk-RXWDB3K4.js} +3 -3
- package/dist/{chunk-XLX37FRL.js → chunk-TEKMLYXS.js} +3 -4
- package/dist/cli/cli.d.ts +12 -0
- package/dist/cli/docs.d.ts +49 -0
- package/dist/cli/export.d.ts +11 -0
- package/dist/cli/generate-types.d.ts +6 -0
- package/dist/cli/import.d.ts +13 -0
- package/dist/cli/init-firebase.d.ts +7 -0
- package/dist/cli/utils.d.ts +27 -0
- package/dist/cli.js +10 -10
- package/dist/client.js +1 -1
- package/dist/core/ai-tools.d.ts +156 -0
- package/dist/core/ai.d.ts +330 -0
- package/dist/core/api.d.ts +21 -0
- package/dist/core/app.d.ts +16 -0
- package/dist/core/checks-translations.d.ts +13 -0
- package/dist/core/checks.d.ts +48 -0
- package/dist/core/client.d.ts +715 -0
- package/dist/core/core.d.ts +5 -0
- package/dist/core/cron.d.ts +19 -0
- package/dist/core/csv.d.ts +5 -0
- package/dist/core/functions.d.ts +9 -0
- package/dist/core/plugin.d.ts +357 -0
- package/dist/{project.d.ts → core/project.d.ts} +8 -12
- package/dist/core/richtext.d.ts +101 -0
- package/dist/{core.d.ts → core/route.d.ts} +13 -66
- package/dist/core/runtime.d.ts +46 -0
- package/dist/{schema-Db_xODoi.d.ts → core/schema.d.ts} +47 -100
- package/dist/core/search-extract.d.ts +70 -0
- package/dist/core/search-index.d.ts +182 -0
- package/dist/core/search-query.d.ts +68 -0
- package/dist/core/security.d.ts +6 -0
- package/dist/core/server-version.d.ts +5 -0
- package/dist/core/services-notifications.d.ts +57 -0
- package/dist/core/services.d.ts +44 -0
- package/dist/core/sse.d.ts +10 -0
- package/dist/core/translations-manager.d.ts +187 -0
- package/dist/core/translations.d.ts +83 -0
- package/dist/core/url-safety.d.ts +19 -0
- package/dist/core/validation.d.ts +30 -0
- package/dist/core/values.d.ts +9 -0
- package/dist/core/versions.d.ts +48 -0
- package/dist/core.js +1 -1
- package/dist/edit-M4PN4SGX.js +7 -0
- package/dist/functions.js +4 -4
- package/dist/{generate-types-SPV7I3A5.js → generate-types-JWIG4QVI.js} +1 -1
- package/dist/plugin.js +124 -129
- package/dist/shared/marshal.d.ts +68 -0
- package/dist/shared/objects.d.ts +9 -0
- package/dist/shared/richtext.d.ts +74 -0
- package/dist/shared/safe-json.d.ts +11 -0
- package/dist/shared/sanitize.d.ts +12 -0
- package/dist/shared/slug.d.ts +19 -0
- package/dist/shared/sse.d.ts +16 -0
- package/dist/shared/strings.d.ts +23 -0
- package/dist/ui/AIPage-2LUC2PWC.js +1 -0
- package/dist/ui/AssetsPage-PODV4QAB.js +1 -0
- package/dist/ui/CollectionPage-4DMKW5YB.js +1 -0
- package/dist/ui/ComparePage-JMJE5A5Y.js +1 -0
- package/dist/ui/DataPage-MVLZT2BU.js +1 -0
- package/dist/ui/DataSourcePage-4RPBXRI2.js +1 -0
- package/dist/ui/DocTranslationsPage-XJSPKGVX.js +1 -0
- package/dist/ui/DocumentPage-R2PVNG24.js +1 -0
- package/dist/ui/EditDataSourcePage-3SHAARNL.js +1 -0
- package/dist/ui/EditReleasePage-G5VW2OGW.js +1 -0
- package/dist/ui/ImageEditorDialog-4H665KK2.js +81 -0
- package/dist/ui/ImageEditorDialog-4H665KK2.js.LEGAL.txt +17 -0
- package/dist/ui/LogsPage-K6KYEG2P.js +1 -0
- package/dist/ui/NewDataSourcePage-O2VQEOJG.js +1 -0
- package/dist/ui/NewReleasePage-RSVS32RZ.js +1 -0
- package/dist/ui/NotFoundPage-ZYD5ILG6.js +1 -0
- package/dist/ui/ProjectPage-X3YQBWL4.js +1 -0
- package/dist/ui/ReleasePage-FJHHXNNB.js +1 -0
- package/dist/ui/ReleasesPage-VGWIBNEZ.js +1 -0
- package/dist/ui/SettingsPage-C4RXOQ6T.js +1 -0
- package/dist/ui/SidebarToolsPage-ZBOKPEMP.js +1 -0
- package/dist/ui/TaskPage-BQ4OX5WN.js +1 -0
- package/dist/ui/TasksPage-3IGQYVYS.js +1 -0
- package/dist/ui/TranslationsArbPage-GGHCWPQL.js +2 -0
- package/dist/ui/TranslationsEditPage-E2BCMKYV.js +1 -0
- package/dist/ui/TranslationsPage-MC4O4ZNI.js +162 -0
- package/dist/ui/ai-tools-5E5ELLZX.js +1 -0
- package/dist/ui/chunk-3IYZCUPI.js +1 -0
- package/dist/ui/chunk-4KE2SZKH.js +1 -0
- package/dist/ui/chunk-4W73RW5I.js +1 -0
- package/dist/ui/chunk-54DVDYU6.js +1 -0
- package/dist/ui/chunk-5MV6XVGA.js +1 -0
- package/dist/ui/chunk-62UWGWON.js +1 -0
- package/dist/ui/chunk-6IFGKSIE.js +1 -0
- package/dist/ui/chunk-767BAQ53.js +1 -0
- package/dist/ui/chunk-AFWBSIPL.js +1 -0
- package/dist/ui/chunk-AL3TN2KI.js +1 -0
- package/dist/ui/chunk-B6BLDN24.js +141 -0
- package/dist/ui/chunk-B6BLDN24.js.LEGAL.txt +106 -0
- package/dist/ui/chunk-BZIRGB4W.js +1 -0
- package/dist/ui/chunk-C5NH23G4.js +3 -0
- package/dist/ui/chunk-CGCKJFL4.js +1 -0
- package/dist/ui/chunk-DEGMKEHP.js +1 -0
- package/dist/ui/chunk-DTMZLUNY.js +15 -0
- package/dist/ui/chunk-DTMZLUNY.js.LEGAL.txt +237 -0
- package/dist/ui/chunk-DUJYIOLE.js +5 -0
- package/dist/ui/chunk-E2RCCK2T.js +1 -0
- package/dist/ui/chunk-EGEB6N4J.js +22 -0
- package/dist/ui/chunk-EGEB6N4J.js.LEGAL.txt +1059 -0
- package/dist/ui/chunk-GXSAEPU3.js +1 -0
- package/dist/ui/chunk-HHMG665Z.js +1 -0
- package/dist/ui/chunk-HKINZLMW.js +84 -0
- package/dist/ui/chunk-HLMBCVRX.js +1 -0
- package/dist/ui/chunk-HRGYNHZ3.js +1 -0
- package/dist/ui/chunk-I6ICVKEC.js +1 -0
- package/dist/ui/chunk-IU36W2TB.js +1 -0
- package/dist/ui/chunk-JDW4UORS.js +1 -0
- package/dist/ui/chunk-JHBAMPGB.js +1 -0
- package/dist/ui/chunk-JYFLU7DM.js +19 -0
- package/dist/ui/chunk-JZFTZ4X4.js +87 -0
- package/dist/ui/chunk-JZFTZ4X4.js.LEGAL.txt +9 -0
- package/dist/ui/chunk-KFAZBEPV.js +1 -0
- package/dist/ui/chunk-KKEWCXVV.js +1 -0
- package/dist/ui/chunk-KUCVLANF.js +1 -0
- package/dist/ui/chunk-KYDOSLTO.js +1 -0
- package/dist/ui/chunk-L4RHGQUG.js +1 -0
- package/dist/ui/chunk-MDUBCXU2.js +1 -0
- package/dist/ui/chunk-NXQVLOTK.js +1 -0
- package/dist/ui/chunk-NZHF733K.js +7 -0
- package/dist/ui/chunk-NZHF733K.js.LEGAL.txt +146 -0
- package/dist/ui/chunk-ONTGW2VA.js +1 -0
- package/dist/ui/chunk-ORXEMIQC.js +1 -0
- package/dist/ui/chunk-PHBMVORG.js +1 -0
- package/dist/ui/chunk-PJA7YP4A.js +1 -0
- package/dist/ui/chunk-PVAE643M.js +1 -0
- package/dist/ui/chunk-PWKJDYE2.js +1 -0
- package/dist/ui/chunk-RSVO46S3.js +1 -0
- package/dist/ui/chunk-SKEP5WYH.js +10 -0
- package/dist/ui/chunk-SKEP5WYH.js.LEGAL.txt +176 -0
- package/dist/ui/chunk-SQRKKWRG.js +3 -0
- package/dist/ui/chunk-UEON4JAT.js +1 -0
- package/dist/ui/chunk-V7S4IAGB.js +1 -0
- package/dist/ui/chunk-VMT7JFAM.js +1 -0
- package/dist/ui/chunk-W3BJ2EZX.js +1 -0
- package/dist/ui/chunk-W3HIZQ4Z.js +1 -0
- package/dist/ui/chunk-X2WHBGTP.js +1 -0
- package/dist/ui/chunk-XOQ3KDSR.js +3 -0
- package/dist/ui/chunk-YDO2EDVY.js +1 -0
- package/dist/ui/chunk-YFA6U2CV.js +1 -0
- package/dist/ui/gcs-L33FIRZU.js +1 -0
- package/dist/ui/prerender-Q4YSDCPB.js +1 -0
- package/dist/ui/signin.js +1 -1
- package/dist/ui/ui.css +1 -1
- package/dist/ui/ui.js +1 -630
- package/dist/ui/ui.js.LEGAL.txt +19 -732
- package/package.json +20 -20
- package/dist/client-1puwLgNx.d.ts +0 -1552
- package/dist/client.d.ts +0 -5
- package/dist/edit-MT4B37QK.js +0 -7
- package/dist/functions.d.ts +0 -13
- package/dist/plugin.d.ts +0 -5
- package/dist/richtext.d.ts +0 -104
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
export interface DocsGetOptions {
|
|
2
|
+
/** Doc mode: "draft" or "published". */
|
|
3
|
+
mode?: string;
|
|
4
|
+
/** Whether to output raw firestore data. */
|
|
5
|
+
raw?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export interface DocsSetOptions {
|
|
8
|
+
/** Doc mode: "draft" or "published". */
|
|
9
|
+
mode?: string;
|
|
10
|
+
}
|
|
11
|
+
export interface DocsDownloadOptions {
|
|
12
|
+
/** Doc mode: "draft" or "published". */
|
|
13
|
+
mode?: string;
|
|
14
|
+
}
|
|
15
|
+
export interface DocsUploadOptions {
|
|
16
|
+
/** Doc mode: "draft" or "published". */
|
|
17
|
+
mode?: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Fetches a single doc and outputs it as JSON.
|
|
21
|
+
* If an output path is provided, writes to a file. Otherwise, writes to stdout.
|
|
22
|
+
*
|
|
23
|
+
* Usage:
|
|
24
|
+
* root-cms docs.get <docId> [outputPath] [--mode draft] [--raw]
|
|
25
|
+
*/
|
|
26
|
+
export declare function docsGet(docId: string, outputPath: string | undefined, options: DocsGetOptions): Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* Sets a single doc's data from a JSON file or stdin.
|
|
29
|
+
* If a filepath is provided, reads from the file. Otherwise, reads from stdin.
|
|
30
|
+
*
|
|
31
|
+
* Usage:
|
|
32
|
+
* root-cms docs.set <docId> [filepath] [--mode draft]
|
|
33
|
+
* cat data.json | root-cms docs.set Pages/home
|
|
34
|
+
*/
|
|
35
|
+
export declare function docsSet(docId: string, filepath: string | undefined, options: DocsSetOptions): Promise<void>;
|
|
36
|
+
/**
|
|
37
|
+
* Downloads all docs in a collection to a local directory.
|
|
38
|
+
*
|
|
39
|
+
* Usage:
|
|
40
|
+
* root-cms docs.download <collection> [outputDir] [--mode draft]
|
|
41
|
+
*/
|
|
42
|
+
export declare function docsDownload(collectionId: string, outputDirArg: string | undefined, options: DocsDownloadOptions): Promise<void>;
|
|
43
|
+
/**
|
|
44
|
+
* Uploads docs from a local directory to a collection.
|
|
45
|
+
*
|
|
46
|
+
* Usage:
|
|
47
|
+
* root-cms docs.upload <collection> <dir> [--mode draft]
|
|
48
|
+
*/
|
|
49
|
+
export declare function docsUpload(collectionId: string, dir: string, options: DocsUploadOptions): Promise<void>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface ExportOptions {
|
|
2
|
+
/** Filter to specific content. */
|
|
3
|
+
filter?: string;
|
|
4
|
+
/** Site id to export (overrides root config). */
|
|
5
|
+
site?: string;
|
|
6
|
+
/** Firestore database id. */
|
|
7
|
+
database?: string;
|
|
8
|
+
/** GCP project id (overrides root config). */
|
|
9
|
+
project?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function exportData(options: ExportOptions): Promise<void>;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Schema } from '../core/schema.js';
|
|
2
|
+
export declare function generateTypes(): Promise<void>;
|
|
3
|
+
/**
|
|
4
|
+
* Generates a root-cms.d.ts file from the .schema.ts files in the project.
|
|
5
|
+
*/
|
|
6
|
+
export declare function generateSchemaDts(outputPath: string, schemas: Record<string, Schema>): Promise<void>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface ImportOptions {
|
|
2
|
+
/** Directory to import from. */
|
|
3
|
+
dir?: string;
|
|
4
|
+
/** Filter to specific content. */
|
|
5
|
+
filter?: string;
|
|
6
|
+
/** Site id to import to (overrides root config). */
|
|
7
|
+
site?: string;
|
|
8
|
+
/** Firestore database id. */
|
|
9
|
+
database?: string;
|
|
10
|
+
/** GCP project id (overrides root config). */
|
|
11
|
+
project?: string;
|
|
12
|
+
}
|
|
13
|
+
export declare function importData(options: ImportOptions): Promise<void>;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parses a comma-separated filter string into include and exclude patterns.
|
|
3
|
+
* Exclude patterns are prefixed with "!".
|
|
4
|
+
*/
|
|
5
|
+
export declare function parseFilters(filterStr?: string): {
|
|
6
|
+
includes: string[];
|
|
7
|
+
excludes: string[];
|
|
8
|
+
};
|
|
9
|
+
export type PathStatus = 'INCLUDE' | 'TRAVERSE' | 'SKIP' | 'EXCLUDE';
|
|
10
|
+
/**
|
|
11
|
+
* Determines the status of a path against a set of include and exclude patterns.
|
|
12
|
+
*
|
|
13
|
+
* - `EXCLUDE`: Path matches an exclude pattern.
|
|
14
|
+
* - `INCLUDE`: Path matches an include pattern fully.
|
|
15
|
+
* - `TRAVERSE`: Path is a parent of an include pattern (partial match).
|
|
16
|
+
* - `SKIP`: Path does not match any include pattern and is not a parent of one.
|
|
17
|
+
*/
|
|
18
|
+
export declare function getPathStatus(path: string, includes: string[], excludes: string[]): PathStatus;
|
|
19
|
+
/**
|
|
20
|
+
* Recursively converts Firestore types to JSON-serializable format.
|
|
21
|
+
*/
|
|
22
|
+
export declare function convertForExport(obj: any): any;
|
|
23
|
+
export type LimitFunction = <T>(fn: () => Promise<T>) => Promise<T>;
|
|
24
|
+
/**
|
|
25
|
+
* Creates a concurrency limiter.
|
|
26
|
+
*/
|
|
27
|
+
export declare function pLimit(concurrency: number): LimitFunction;
|
package/dist/cli.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
generateTypes
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-TEKMLYXS.js";
|
|
4
4
|
import {
|
|
5
5
|
RootCMSClient,
|
|
6
6
|
getCmsPlugin,
|
|
7
7
|
unmarshalData
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-N4K6ICFR.js";
|
|
9
9
|
import "./chunk-MLKGABMK.js";
|
|
10
10
|
|
|
11
11
|
// cli/cli.ts
|
|
@@ -13,9 +13,9 @@ import { Command } from "commander";
|
|
|
13
13
|
import { bgGreen, black } from "kleur/colors";
|
|
14
14
|
|
|
15
15
|
// cli/docs.ts
|
|
16
|
-
import fs from "fs";
|
|
17
|
-
import path from "path";
|
|
18
|
-
import * as readline from "readline";
|
|
16
|
+
import fs from "node:fs";
|
|
17
|
+
import path from "node:path";
|
|
18
|
+
import * as readline from "node:readline";
|
|
19
19
|
import { loadRootConfig } from "@blinkk/root/node";
|
|
20
20
|
import { Timestamp, GeoPoint } from "firebase-admin/firestore";
|
|
21
21
|
|
|
@@ -332,8 +332,8 @@ function convertFirestoreTypes(obj, db) {
|
|
|
332
332
|
}
|
|
333
333
|
|
|
334
334
|
// cli/export.ts
|
|
335
|
-
import fs2 from "fs";
|
|
336
|
-
import path2 from "path";
|
|
335
|
+
import fs2 from "node:fs";
|
|
336
|
+
import path2 from "node:path";
|
|
337
337
|
import { loadRootConfig as loadRootConfig2 } from "@blinkk/root/node";
|
|
338
338
|
async function exportData(options) {
|
|
339
339
|
const rootDir = process.cwd();
|
|
@@ -519,9 +519,9 @@ function formatTimestamp(date) {
|
|
|
519
519
|
}
|
|
520
520
|
|
|
521
521
|
// cli/import.ts
|
|
522
|
-
import fs3 from "fs";
|
|
523
|
-
import path3 from "path";
|
|
524
|
-
import * as readline2 from "readline";
|
|
522
|
+
import fs3 from "node:fs";
|
|
523
|
+
import path3 from "node:path";
|
|
524
|
+
import * as readline2 from "node:readline";
|
|
525
525
|
import { loadRootConfig as loadRootConfig3 } from "@blinkk/root/node";
|
|
526
526
|
import cliProgress from "cli-progress";
|
|
527
527
|
import { Timestamp as Timestamp2, GeoPoint as GeoPoint2 } from "firebase-admin/firestore";
|
package/dist/client.js
CHANGED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in CMS tools exposed to the chat model on the `/cms/ai` page.
|
|
3
|
+
*
|
|
4
|
+
* Read tools (`doc_get`, `docs_list`, etc.) execute server-side via the
|
|
5
|
+
* Firebase Admin SDK when a `CmsToolContext` is passed to the factory. This
|
|
6
|
+
* keeps potentially-large doc payloads off the wire: results stay in the
|
|
7
|
+
* model's server-side context instead of round-tripping through the browser
|
|
8
|
+
* on every chat turn.
|
|
9
|
+
*
|
|
10
|
+
* Write tools (`doc_set`, `doc_create`, `doc_updateField`, `doc_duplicate`)
|
|
11
|
+
* stay schema-only here — the browser executes them via `onToolCall` so the
|
|
12
|
+
* user can approve diffs in the UI and so Firestore listeners on other tabs
|
|
13
|
+
* see the change immediately.
|
|
14
|
+
*
|
|
15
|
+
* Validation helpers (`validateFields`, `validateValueAtPath`) live here
|
|
16
|
+
* too so both browser and server can share the same checks.
|
|
17
|
+
*
|
|
18
|
+
* Browser-import safety: this module is dynamically imported by the browser
|
|
19
|
+
* bundle (cmsToolHandlers.ts) to reuse the validators, so it must not pull
|
|
20
|
+
* server-only modules into runtime imports. `RootCMSClient` and `RootConfig`
|
|
21
|
+
* are referenced as types only; the actual instance is passed in at call
|
|
22
|
+
* time via `CmsToolContext`.
|
|
23
|
+
*/
|
|
24
|
+
import type { RootConfig } from '@blinkk/root';
|
|
25
|
+
import { ToolSet } from 'ai';
|
|
26
|
+
import type { RootCMSClient } from './client.js';
|
|
27
|
+
import { Collection } from './schema.js';
|
|
28
|
+
import { validateFields } from './validation.js';
|
|
29
|
+
/** Tool ids handled client-side. Kept in sync with the schemas below. */
|
|
30
|
+
export declare const CMS_TOOL_NAMES: readonly ["collections_list", "docs_list", "doc_get", "doc_getVersion", "doc_set", "doc_create", "doc_updateField", "doc_edit", "doc_duplicate", "doc_listVersions", "doc_translateField", "schema_get"];
|
|
31
|
+
export type CmsToolName = (typeof CMS_TOOL_NAMES)[number];
|
|
32
|
+
/**
|
|
33
|
+
* Subset of CMS tools that perform reads only. Used by flows where the user
|
|
34
|
+
* approves changes via UI (e.g. the array-item "Edit with AI" diff viewer)
|
|
35
|
+
* and the model must not write to Firestore directly.
|
|
36
|
+
*/
|
|
37
|
+
export declare const READ_ONLY_CMS_TOOL_NAMES: readonly CmsToolName[];
|
|
38
|
+
/**
|
|
39
|
+
* Result of a server-side search invocation. Loosely-typed — the result is
|
|
40
|
+
* serialized to JSON and handed to the model, so extra fields are fine.
|
|
41
|
+
* `hits` is an array of objects each carrying at least a `docId`.
|
|
42
|
+
*/
|
|
43
|
+
export interface CmsSearchResult {
|
|
44
|
+
hits: Array<Record<string, unknown> | {
|
|
45
|
+
docId: string;
|
|
46
|
+
}>;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Context passed into the tool factory to enable server-side execution of
|
|
50
|
+
* the read tools. The caller (typically `runChatStream` in `core/ai.ts`)
|
|
51
|
+
* owns the Firebase Admin client and the schema/search lookups.
|
|
52
|
+
*/
|
|
53
|
+
export interface CmsToolContext {
|
|
54
|
+
cmsClient: RootCMSClient;
|
|
55
|
+
user: string;
|
|
56
|
+
rootConfig: RootConfig;
|
|
57
|
+
loadCollection: (collectionId: string) => Promise<Collection | null>;
|
|
58
|
+
loadAllCollections: () => Promise<Record<string, Collection>>;
|
|
59
|
+
search: (query: string, options: {
|
|
60
|
+
limit: number;
|
|
61
|
+
}) => Promise<CmsSearchResult>;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Returns a `ToolSet` filtered to only the read-only CMS tools. Use this in
|
|
65
|
+
* flows where the AI assists with proposing changes that the user reviews
|
|
66
|
+
* and saves manually (so the model can read context but cannot mutate data).
|
|
67
|
+
*/
|
|
68
|
+
export declare function createReadOnlyCmsTools(ctx: CmsToolContext): ToolSet;
|
|
69
|
+
/**
|
|
70
|
+
* Builds the full tool set advertised to the model.
|
|
71
|
+
*
|
|
72
|
+
* Read tools (`collections_list`, `docs_list`, `docs_search`, `doc_get`,
|
|
73
|
+
* `doc_getVersion`, `doc_listVersions`, `schema_get`) carry a server-side
|
|
74
|
+
* `execute` so the Vercel AI SDK runs them in-process; their results stay
|
|
75
|
+
* in the model's server-side context and never round-trip through the
|
|
76
|
+
* browser. Write tools (`doc_set`, `doc_create`, `doc_updateField`,
|
|
77
|
+
* `doc_duplicate`, `doc_translateField`) remain schema-only — the browser
|
|
78
|
+
* executes them via `onToolCall` so the user can approve diffs before
|
|
79
|
+
* persistence.
|
|
80
|
+
*
|
|
81
|
+
* Safety policy: this tool set is intentionally read + draft-write only.
|
|
82
|
+
* The following operations are deliberately NOT exposed to the model
|
|
83
|
+
* because they are publishing-related, destructive, or otherwise
|
|
84
|
+
* irreversible. Surfacing them would let a single hallucinated tool call
|
|
85
|
+
* affect the live site or wipe authored content. Users must perform these
|
|
86
|
+
* actions themselves through the regular CMS UI:
|
|
87
|
+
*
|
|
88
|
+
* - `doc_publish` / `doc_unpublish` — promote/demote a draft to/from
|
|
89
|
+
* production. Always user-initiated.
|
|
90
|
+
* - `doc_delete` — permanent removal of a doc.
|
|
91
|
+
* - `doc_revertDraft` — discards in-progress draft edits.
|
|
92
|
+
* - `doc_schedule` / `doc_unschedule` — affects future production state.
|
|
93
|
+
* - `doc_lockPublishing` / `doc_unlockPublishing` — affects governance state.
|
|
94
|
+
* - `doc_restoreVersion` — overwrites the current draft with old data.
|
|
95
|
+
* - Bulk variants (e.g. `docs_publish`) of any of the above.
|
|
96
|
+
*
|
|
97
|
+
* If you add new write tools here, keep them limited to draft-mode edits
|
|
98
|
+
* the user can easily review before publishing.
|
|
99
|
+
*/
|
|
100
|
+
export declare function createCmsTools(ctx: CmsToolContext): ToolSet;
|
|
101
|
+
/**
|
|
102
|
+
* Validates `value` against the field schema located at `path` within
|
|
103
|
+
* `collection`. Returns validation errors if the field can be resolved and
|
|
104
|
+
* the value doesn't match its expected shape. If the field cannot be located
|
|
105
|
+
* (e.g. the path walks through a `oneof` with an unknown discriminator),
|
|
106
|
+
* returns an empty array to fall back to "no validation" rather than
|
|
107
|
+
* blocking the write.
|
|
108
|
+
*/
|
|
109
|
+
export declare function validateValueAtPath(collection: Collection, path: string, value: any): Array<{
|
|
110
|
+
path: string;
|
|
111
|
+
message: string;
|
|
112
|
+
expected?: string;
|
|
113
|
+
received?: any;
|
|
114
|
+
}>;
|
|
115
|
+
export { validateFields };
|
|
116
|
+
/** A single edit operation handled by the `doc_edit` tool. */
|
|
117
|
+
export interface DocEditOperation {
|
|
118
|
+
op: 'set' | 'insert_item' | 'remove_item';
|
|
119
|
+
/** Dotted path within the fields object (no leading "fields." prefix). */
|
|
120
|
+
path: string;
|
|
121
|
+
/** Value to write ("set") or insert ("insert_item"). Unused for "remove_item". */
|
|
122
|
+
value?: any;
|
|
123
|
+
/** Zero-based array index for "insert_item" (optional) and "remove_item" (required). */
|
|
124
|
+
index?: number;
|
|
125
|
+
}
|
|
126
|
+
/** A structural failure applying one operation in a `doc_edit` batch. */
|
|
127
|
+
export interface DocEditError {
|
|
128
|
+
/** Zero-based position of the failing operation in the input list. */
|
|
129
|
+
opIndex: number;
|
|
130
|
+
op: string;
|
|
131
|
+
path: string;
|
|
132
|
+
message: string;
|
|
133
|
+
expected?: string;
|
|
134
|
+
received?: any;
|
|
135
|
+
}
|
|
136
|
+
export type ApplyDocEditsResult = {
|
|
137
|
+
ok: true;
|
|
138
|
+
fields: Record<string, any>;
|
|
139
|
+
} | {
|
|
140
|
+
ok: false;
|
|
141
|
+
error: DocEditError;
|
|
142
|
+
};
|
|
143
|
+
/**
|
|
144
|
+
* Applies a sequence of `doc_edit` operations to a plain-JSON `fields` object
|
|
145
|
+
* and returns the resulting fields, or the first operation that failed.
|
|
146
|
+
*
|
|
147
|
+
* Pure: the input is deep-cloned and never mutated, so callers can validate
|
|
148
|
+
* the result against the collection schema (via `validateFields`) before
|
|
149
|
+
* persisting. Operations run in order — array indices in each op refer to the
|
|
150
|
+
* array state after earlier ops have been applied.
|
|
151
|
+
*
|
|
152
|
+
* This performs structural checks only (path resolves against the current
|
|
153
|
+
* data, the target is an array for insert_item/remove_item, the index is in
|
|
154
|
+
* range). Type/schema validation is the caller's responsibility.
|
|
155
|
+
*/
|
|
156
|
+
export declare function applyDocEdits(fields: Record<string, any>, operations: DocEditOperation[]): ApplyDocEditsResult;
|
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
import { RootConfig } from '@blinkk/root';
|
|
2
|
+
import { ImageModel, LanguageModel, UIMessage } from 'ai';
|
|
3
|
+
import { Timestamp } from 'firebase-admin/firestore';
|
|
4
|
+
import { RootCMSClient } from './client.js';
|
|
5
|
+
import { Collection } from './schema.js';
|
|
6
|
+
/** Filename of the project-level instructions file loaded into the AI prompt. */
|
|
7
|
+
export declare const ROOT_MD_FILENAME = "ROOT.md";
|
|
8
|
+
export type AiExecutionMode = 'read' | 'approve' | 'auto';
|
|
9
|
+
/**
|
|
10
|
+
* Provider type for an AI model. Use `openai-compatible` for any OpenAI-style
|
|
11
|
+
* endpoint (e.g. local Ollama, vLLM, OpenRouter).
|
|
12
|
+
*/
|
|
13
|
+
export type AiProvider = 'openai' | 'openai-compatible' | 'anthropic' | 'google';
|
|
14
|
+
/**
|
|
15
|
+
* Configuration for a single chat model.
|
|
16
|
+
*
|
|
17
|
+
* Inspired by Ollama's `Modelfile` and LiteLLM's model config: each entry maps
|
|
18
|
+
* a CMS-facing id to a provider, model id and credentials.
|
|
19
|
+
*/
|
|
20
|
+
export interface AiModelConfig {
|
|
21
|
+
/** Stable id used by the CMS UI and stored alongside chat history. */
|
|
22
|
+
id: string;
|
|
23
|
+
/** Optional human-readable label rendered in the model picker. */
|
|
24
|
+
label?: string;
|
|
25
|
+
/** Optional description shown under the label. */
|
|
26
|
+
description?: string;
|
|
27
|
+
/** AI provider/family to route requests to. */
|
|
28
|
+
provider: AiProvider;
|
|
29
|
+
/**
|
|
30
|
+
* Provider-specific model id (e.g. `gpt-4o`, `claude-opus-4-5`,
|
|
31
|
+
* `gemini-2.5-pro`). Defaults to `id` if omitted.
|
|
32
|
+
*/
|
|
33
|
+
modelId?: string;
|
|
34
|
+
/** API key for the provider. */
|
|
35
|
+
apiKey?: string;
|
|
36
|
+
/** Override the provider's base URL (required for `openai-compatible`). */
|
|
37
|
+
baseURL?: string;
|
|
38
|
+
/** Custom headers to send with each request. */
|
|
39
|
+
headers?: Record<string, string>;
|
|
40
|
+
/** Capabilities advertised to the UI. */
|
|
41
|
+
capabilities?: {
|
|
42
|
+
/** Whether the model can call tools. Defaults to `true`. */
|
|
43
|
+
tools?: boolean;
|
|
44
|
+
/** Whether the model can stream reasoning/thinking. Defaults to `false`. */
|
|
45
|
+
reasoning?: boolean;
|
|
46
|
+
/** Whether the model accepts image attachments. Defaults to `false`. */
|
|
47
|
+
attachments?: boolean;
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Full AI config registered on the cms plugin.
|
|
52
|
+
*/
|
|
53
|
+
export interface AiConfig {
|
|
54
|
+
/** Models exposed in the model picker. The first entry is the default. */
|
|
55
|
+
models: AiModelConfig[];
|
|
56
|
+
/** Id of the default model. Defaults to the first model in `models`. */
|
|
57
|
+
defaultModel?: string;
|
|
58
|
+
/**
|
|
59
|
+
* Image generation models. Used by the image generator and any other
|
|
60
|
+
* features that produce images. Only the `openai` and `google` providers
|
|
61
|
+
* support image generation.
|
|
62
|
+
*/
|
|
63
|
+
imageModels?: AiModelConfig[];
|
|
64
|
+
/** Id of the default image model. Defaults to the first entry in `imageModels`. */
|
|
65
|
+
defaultImageModel?: string;
|
|
66
|
+
/**
|
|
67
|
+
* Optional system prompt prepended to every conversation. If a `ROOT.md`
|
|
68
|
+
* file exists at the project root, its contents are appended to this
|
|
69
|
+
* prompt automatically.
|
|
70
|
+
*/
|
|
71
|
+
systemPrompt?: string;
|
|
72
|
+
/** Maximum tool-loop steps before stopping. Defaults to 10. */
|
|
73
|
+
maxSteps?: number;
|
|
74
|
+
}
|
|
75
|
+
interface ChatRecord {
|
|
76
|
+
id: string;
|
|
77
|
+
createdBy: string;
|
|
78
|
+
createdAt: Timestamp;
|
|
79
|
+
modifiedAt: Timestamp;
|
|
80
|
+
modelId?: string;
|
|
81
|
+
title?: string;
|
|
82
|
+
messages: UIMessage[];
|
|
83
|
+
}
|
|
84
|
+
/** Resolves an `AiModelConfig` to an AI SDK `LanguageModel` instance. */
|
|
85
|
+
export declare function resolveLanguageModel(model: AiModelConfig): LanguageModel;
|
|
86
|
+
/** Resolves an `AiModelConfig` to an AI SDK `ImageModel` instance. */
|
|
87
|
+
export declare function resolveImageModel(model: AiModelConfig): ImageModel;
|
|
88
|
+
/** Strips secrets from `AiConfig` before sending to the browser. */
|
|
89
|
+
export declare function serializeAiConfig(config: AiConfig): {
|
|
90
|
+
defaultModel: string;
|
|
91
|
+
models: {
|
|
92
|
+
id: string;
|
|
93
|
+
label: string;
|
|
94
|
+
description: string | undefined;
|
|
95
|
+
provider: AiProvider;
|
|
96
|
+
capabilities: {
|
|
97
|
+
tools: boolean;
|
|
98
|
+
reasoning: boolean;
|
|
99
|
+
attachments: boolean;
|
|
100
|
+
};
|
|
101
|
+
}[];
|
|
102
|
+
imageGenerationEnabled: boolean;
|
|
103
|
+
};
|
|
104
|
+
/** Returns the AI config registered on the CMS plugin, or `null`. */
|
|
105
|
+
export declare function getAiConfig(rootConfig: RootConfig): AiConfig | null;
|
|
106
|
+
/** Returns the model config matching `modelId`, or the default model. */
|
|
107
|
+
export declare function findModel(config: AiConfig, modelId?: string): AiModelConfig | null;
|
|
108
|
+
/** Returns the image model config matching `modelId`, or the default image model. */
|
|
109
|
+
export declare function findImageModel(config: AiConfig, modelId?: string): AiModelConfig | null;
|
|
110
|
+
export declare function normalizeExecutionMode(value: unknown): AiExecutionMode;
|
|
111
|
+
/**
|
|
112
|
+
* Persists chat sessions to Firestore so that users can resume past
|
|
113
|
+
* conversations from the chat history sidebar.
|
|
114
|
+
*/
|
|
115
|
+
export declare class ChatStore {
|
|
116
|
+
cmsClient: RootCMSClient;
|
|
117
|
+
user: string;
|
|
118
|
+
constructor(cmsClient: RootCMSClient, user: string);
|
|
119
|
+
collection(): FirebaseFirestore.CollectionReference<FirebaseFirestore.DocumentData, FirebaseFirestore.DocumentData>;
|
|
120
|
+
createChat(options?: {
|
|
121
|
+
id?: string;
|
|
122
|
+
modelId?: string;
|
|
123
|
+
}): Promise<ChatRecord>;
|
|
124
|
+
getChat(id: string): Promise<ChatRecord | null>;
|
|
125
|
+
listChats(options?: {
|
|
126
|
+
limit?: number;
|
|
127
|
+
}): Promise<ChatRecord[]>;
|
|
128
|
+
deleteChat(id: string): Promise<void>;
|
|
129
|
+
updateMessages(id: string, messages: UIMessage[], options?: {
|
|
130
|
+
modelId?: string;
|
|
131
|
+
title?: string;
|
|
132
|
+
}): Promise<void>;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Merges the latest incoming message into the persisted chat history.
|
|
136
|
+
*
|
|
137
|
+
* The client posts only the last message; the server holds the rest in
|
|
138
|
+
* Firestore. After client-side tool execution the SDK resubmits the *same*
|
|
139
|
+
* assistant message — now carrying tool results — under the id it was
|
|
140
|
+
* streamed with. That id already exists in the persisted history (saved by
|
|
141
|
+
* `onFinish` before the results came back), so a naive append would
|
|
142
|
+
* duplicate it: the stored copy still has unresolved tool calls, which
|
|
143
|
+
* convert to `tool_use` blocks with no following `tool_result` and the model
|
|
144
|
+
* provider rejects the request.
|
|
145
|
+
*
|
|
146
|
+
* Replacing the matched entry (and dropping anything after it) keeps message
|
|
147
|
+
* ids unique and the tool-call/result pairing intact. A genuinely new
|
|
148
|
+
* message id is appended as usual.
|
|
149
|
+
*/
|
|
150
|
+
export declare function mergeIncomingMessage(stored: UIMessage[], incoming: UIMessage): UIMessage[];
|
|
151
|
+
/**
|
|
152
|
+
* Synthesizes an aborted result for any tool-call part still awaiting one, so
|
|
153
|
+
* every `tool_use` keeps a matching `tool_result` when the history is handed
|
|
154
|
+
* to the model. Left unresolved, such parts (from an abandoned turn) make the
|
|
155
|
+
* provider reject the next request. Returns the original array unchanged when
|
|
156
|
+
* there is nothing to repair.
|
|
157
|
+
*/
|
|
158
|
+
export declare function sanitizeDanglingToolCalls(messages: UIMessage[]): UIMessage[];
|
|
159
|
+
/**
|
|
160
|
+
* Reads the project's `ROOT.md` file, if present. Mirrors the convention used
|
|
161
|
+
* by tools like `AGENTS.md` and `CLAUDE.md`: developers can drop a markdown
|
|
162
|
+
* file at the project root to give Root AI extra context about site-specific
|
|
163
|
+
* patterns or conventions.
|
|
164
|
+
*
|
|
165
|
+
* Returns the file contents (trimmed) or `null` if the file is missing or
|
|
166
|
+
* unreadable.
|
|
167
|
+
*/
|
|
168
|
+
export declare function readRootMd(rootDir: string): Promise<string | null>;
|
|
169
|
+
/**
|
|
170
|
+
* Builds the full system prompt by combining the configured/default base
|
|
171
|
+
* prompt with the contents of `ROOT.md`, when present. The project-level
|
|
172
|
+
* file is appended under a clearly delimited section so the model can
|
|
173
|
+
* distinguish it from the framework-provided instructions.
|
|
174
|
+
*/
|
|
175
|
+
export declare function buildSystemPrompt(basePrompt: string, rootMd: string | null): string;
|
|
176
|
+
/** Derives a short title from the first user message (used as fallback). */
|
|
177
|
+
export declare function deriveChatTitle(messages: UIMessage[]): string;
|
|
178
|
+
/**
|
|
179
|
+
* Extracts the first user turn and first assistant text turn as a plain-text
|
|
180
|
+
* transcript, suitable for the title-generation prompt. Skips tool-call
|
|
181
|
+
* parts, reasoning chunks, and attachments so the model sees the
|
|
182
|
+
* conversational substance and nothing else.
|
|
183
|
+
*
|
|
184
|
+
* Only the opening exchange is included on purpose — the chat title should
|
|
185
|
+
* describe what the conversation is *about*, anchored on the user's initial
|
|
186
|
+
* ask, not drift as later follow-ups arrive.
|
|
187
|
+
*/
|
|
188
|
+
export declare function buildTitlePromptContext(messages: UIMessage[]): string;
|
|
189
|
+
/**
|
|
190
|
+
* Strips the cruft LLMs commonly emit around a title — leading "Title:"
|
|
191
|
+
* preamble, surrounding quotes, trailing punctuation, internal newlines —
|
|
192
|
+
* and enforces a hard length cap.
|
|
193
|
+
*/
|
|
194
|
+
export declare function sanitizeGeneratedTitle(raw: string): string;
|
|
195
|
+
/**
|
|
196
|
+
* Uses the AI model to generate a short summary title for the chat. The
|
|
197
|
+
* prompt is anchored on the user's initial question (and, if available, the
|
|
198
|
+
* assistant's first reply) so the title captures *intent and topic* rather
|
|
199
|
+
* than echoing the first line verbatim.
|
|
200
|
+
*
|
|
201
|
+
* Falls back to `deriveChatTitle` if the generation fails or returns an
|
|
202
|
+
* empty result.
|
|
203
|
+
*/
|
|
204
|
+
export declare function generateChatTitle(model: LanguageModel, messages: UIMessage[]): Promise<string>;
|
|
205
|
+
export interface RunChatStreamOptions {
|
|
206
|
+
rootConfig: RootConfig;
|
|
207
|
+
cmsClient: RootCMSClient;
|
|
208
|
+
config: AiConfig;
|
|
209
|
+
model: AiModelConfig;
|
|
210
|
+
messages: UIMessage[];
|
|
211
|
+
chatId: string;
|
|
212
|
+
user: string;
|
|
213
|
+
executionMode?: AiExecutionMode;
|
|
214
|
+
/**
|
|
215
|
+
* Title already saved on this chat. When non-empty the server will NOT
|
|
216
|
+
* regenerate it on this turn — titles are derived once, on the first
|
|
217
|
+
* assistant response, so they describe the original ask instead of
|
|
218
|
+
* thrashing as follow-up messages arrive.
|
|
219
|
+
*/
|
|
220
|
+
existingTitle?: string;
|
|
221
|
+
/**
|
|
222
|
+
* When set, tells the model which document the user is currently viewing
|
|
223
|
+
* in the CMS UI so phrases like "this document" can be resolved.
|
|
224
|
+
*/
|
|
225
|
+
activeDocId?: string;
|
|
226
|
+
/**
|
|
227
|
+
* Loads a single collection's schema. The caller owns dev-vs-prod schema
|
|
228
|
+
* resolution (Vite SSR vs. prebuilt `dist/collections/*.json`).
|
|
229
|
+
*/
|
|
230
|
+
loadCollection: (collectionId: string) => Promise<Collection | null>;
|
|
231
|
+
/** Loads every project collection keyed by id. */
|
|
232
|
+
loadAllCollections: () => Promise<Record<string, Collection>>;
|
|
233
|
+
}
|
|
234
|
+
export declare function buildExecutionModePrompt(mode: AiExecutionMode): string;
|
|
235
|
+
/**
|
|
236
|
+
* Builds a streaming response that proxies the model's UI message stream
|
|
237
|
+
* directly to the client. Persists the final message list to Firestore once
|
|
238
|
+
* the stream finishes.
|
|
239
|
+
*/
|
|
240
|
+
export declare function runChatStream(options: RunChatStreamOptions): Promise<Response>;
|
|
241
|
+
export interface RunEditObjectStreamOptions {
|
|
242
|
+
rootConfig: RootConfig;
|
|
243
|
+
cmsClient: RootCMSClient;
|
|
244
|
+
user: string;
|
|
245
|
+
config: AiConfig;
|
|
246
|
+
model: AiModelConfig;
|
|
247
|
+
messages: UIMessage[];
|
|
248
|
+
/** The JSON object the user is editing. Injected as context for the model. */
|
|
249
|
+
editData: unknown;
|
|
250
|
+
loadCollection: (collectionId: string) => Promise<Collection | null>;
|
|
251
|
+
loadAllCollections: () => Promise<Record<string, Collection>>;
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Streaming variant used by the array-item "Edit with AI" diff-viewer flow.
|
|
255
|
+
*
|
|
256
|
+
* Differences from `runChatStream`:
|
|
257
|
+
*
|
|
258
|
+
* - Uses an edit-specific system prompt that injects the JSON the user is
|
|
259
|
+
* editing and the project's `root-cms.d.ts` types, and instructs the model
|
|
260
|
+
* to end every response with a fenced ```json block containing the
|
|
261
|
+
* complete proposed new JSON. The client extracts that block to populate
|
|
262
|
+
* the diff viewer.
|
|
263
|
+
* - Tools are filtered to read-only (see `createReadOnlyCmsTools`). The user
|
|
264
|
+
* approves changes via the modal's "Save" button, so the model must not
|
|
265
|
+
* mutate Firestore directly.
|
|
266
|
+
* - No Firestore persistence — edit sessions are ephemeral and don't show up
|
|
267
|
+
* in the user's chat history.
|
|
268
|
+
*/
|
|
269
|
+
export declare function runEditObjectStream(options: RunEditObjectStreamOptions): Promise<Response>;
|
|
270
|
+
/**
|
|
271
|
+
* Recursively removes `undefined` values from an object/array. Returns a new
|
|
272
|
+
* structure; the input is not mutated. Used to clean payloads before sending
|
|
273
|
+
* them to Firestore, which rejects `undefined` outright.
|
|
274
|
+
*/
|
|
275
|
+
export declare function stripUndefined<T>(value: T): T;
|
|
276
|
+
export interface SummarizeDiffOptions {
|
|
277
|
+
before: Record<string, any> | null;
|
|
278
|
+
after: Record<string, any> | null;
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Generates a natural language summary of the differences between two JSON
|
|
282
|
+
* payloads.
|
|
283
|
+
*/
|
|
284
|
+
export declare function summarizeDiff(rootConfig: RootConfig, options: SummarizeDiffOptions): Promise<string>;
|
|
285
|
+
/**
|
|
286
|
+
* Generates a concise commit-style publish message based on document changes.
|
|
287
|
+
*/
|
|
288
|
+
export declare function generatePublishMessage(rootConfig: RootConfig, options: SummarizeDiffOptions): Promise<string>;
|
|
289
|
+
export interface TranslateStringOptions {
|
|
290
|
+
sourceText: string;
|
|
291
|
+
targetLocales: string[];
|
|
292
|
+
description?: string;
|
|
293
|
+
existingTranslations?: Record<string, string>;
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Translates a source string into multiple target locales using AI.
|
|
297
|
+
*/
|
|
298
|
+
export declare function translateString(rootConfig: RootConfig, options: TranslateStringOptions): Promise<Record<string, string>>;
|
|
299
|
+
export interface GenerateAltTextOptions {
|
|
300
|
+
/** Absolute URL or data URL of the image to describe. */
|
|
301
|
+
imageUrl: string;
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Generates concise alt text for the given image URL using a multimodal model.
|
|
305
|
+
*/
|
|
306
|
+
export declare function generateAltText(rootConfig: RootConfig, options: GenerateAltTextOptions): Promise<string>;
|
|
307
|
+
/** Allowed aspect ratios for image generation. */
|
|
308
|
+
export type AspectRatio = '1:1' | '2:3' | '3:2' | '3:4' | '4:3' | '4:5' | '5:4' | '9:16' | '16:9' | '21:9';
|
|
309
|
+
export interface GenerateImageOptions {
|
|
310
|
+
prompt: string;
|
|
311
|
+
aspectRatio: AspectRatio;
|
|
312
|
+
/** Specific image model id from `AiConfig.imageModels`. */
|
|
313
|
+
modelId?: string;
|
|
314
|
+
}
|
|
315
|
+
export interface GenerateImageResult {
|
|
316
|
+
/** Generated image as a `data:image/...` URL. */
|
|
317
|
+
imageUrl: string;
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Generates an image using the configured `imageModels`. Returns the image as
|
|
321
|
+
* a base64-encoded data URL so the caller can either inline it or upload it
|
|
322
|
+
* to storage.
|
|
323
|
+
*/
|
|
324
|
+
export declare function generateImage(rootConfig: RootConfig, options: GenerateImageOptions): Promise<GenerateImageResult>;
|
|
325
|
+
/**
|
|
326
|
+
* Extracts JSON from an AI response that may contain markdown code blocks.
|
|
327
|
+
* @internal
|
|
328
|
+
*/
|
|
329
|
+
export declare function extractJsonFromResponse(responseText: string): string;
|
|
330
|
+
export {};
|