@tangle-network/agent-app 0.45.65 → 0.45.66
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/{chunk-HSBJB46C.js → chunk-E2CWFUUP.js} +3 -58
- package/dist/chunk-E2CWFUUP.js.map +1 -0
- package/dist/stories/studio/fixtures.d.ts +0 -4
- package/dist/studio/generation.d.ts +2 -51
- package/dist/studio/index.d.ts +1 -2
- package/dist/studio/index.js +1 -11
- package/dist/studio-react/composer-hero.d.ts +1 -3
- package/dist/studio-react/index.d.ts +3 -5
- package/dist/studio-react/index.js +303 -510
- package/dist/studio-react/index.js.map +1 -1
- package/dist/studio-react/studio-workspace.d.ts +2 -4
- package/package.json +1 -1
- package/dist/chunk-HSBJB46C.js.map +0 -1
- package/dist/studio-react/publish-package-composer.d.ts +0 -18
|
@@ -3,14 +3,6 @@ var GENERATION_TYPES = ["image", "video", "avatar", "speech", "transcription"];
|
|
|
3
3
|
function isGenerationType(value) {
|
|
4
4
|
return GENERATION_TYPES.includes(value);
|
|
5
5
|
}
|
|
6
|
-
var DESTINATIONS = [
|
|
7
|
-
{ id: "instagram", label: "Instagram", providerIds: ["instagram"], fields: "Caption, hashtags, crop" },
|
|
8
|
-
{ id: "tiktok", label: "TikTok", providerIds: ["tiktok"], fields: "Caption, audio note, vertical video" },
|
|
9
|
-
{ id: "youtube-shorts", label: "YouTube Shorts", providerIds: ["youtube"], fields: "Title, description, vertical video" },
|
|
10
|
-
{ id: "linkedin", label: "LinkedIn", providerIds: ["linkedin"], fields: "Caption, link, creator/company page" },
|
|
11
|
-
{ id: "x", label: "X", providerIds: ["twitter"], fields: "Short copy, mentions, thread option" }
|
|
12
|
-
];
|
|
13
|
-
var CADENCES = ["Manual approval", "Publish now", "Daily creative drop", "Weekly series"];
|
|
14
6
|
var IMAGE_QUALITIES = ["low", "medium", "high", "auto"];
|
|
15
7
|
var IMAGE_SIZE_HINT = "1024x1024, 1536x1024, 1024x1536, or auto";
|
|
16
8
|
var IMAGE_SIZE_PATTERN = String.raw`(\d{3,4}x\d{3,4}|auto)`;
|
|
@@ -43,47 +35,6 @@ function generationVaultPath(generation) {
|
|
|
43
35
|
const value = generation.metadata?.vaultPath;
|
|
44
36
|
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
45
37
|
}
|
|
46
|
-
function buildPublishPackage({
|
|
47
|
-
caption,
|
|
48
|
-
postDescription,
|
|
49
|
-
mentions,
|
|
50
|
-
cadence,
|
|
51
|
-
destinations
|
|
52
|
-
}) {
|
|
53
|
-
const trimmedCaption = caption.trim();
|
|
54
|
-
const trimmedDescription = postDescription.trim();
|
|
55
|
-
const parsedMentions = mentions.split(",").map((item) => item.trim()).filter(Boolean);
|
|
56
|
-
const selectedDestinations = destinations.filter(Boolean);
|
|
57
|
-
const trimmedCadence = cadence.trim() || "Manual approval";
|
|
58
|
-
const hasPublishContent = Boolean(
|
|
59
|
-
trimmedCaption || trimmedDescription || parsedMentions.length > 0 || selectedDestinations.length > 0 || trimmedCadence !== "Manual approval"
|
|
60
|
-
);
|
|
61
|
-
if (!hasPublishContent) return null;
|
|
62
|
-
return {
|
|
63
|
-
caption: trimmedCaption,
|
|
64
|
-
description: trimmedDescription,
|
|
65
|
-
mentions: parsedMentions,
|
|
66
|
-
destinations: selectedDestinations,
|
|
67
|
-
cadence: trimmedCadence,
|
|
68
|
-
workflowDraft: trimmedCadence !== "Manual approval",
|
|
69
|
-
evalContract: {
|
|
70
|
-
artifactType: "publish_package",
|
|
71
|
-
deterministicChecks: ["has_asset", "has_destination", "has_caption_or_description", "has_cadence"]
|
|
72
|
-
}
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
function isPublishPackage(value) {
|
|
76
|
-
if (!value || typeof value !== "object") return false;
|
|
77
|
-
const publishPackage = value;
|
|
78
|
-
const destinations = Array.isArray(publishPackage.destinations) ? publishPackage.destinations.filter(Boolean) : [];
|
|
79
|
-
const mentions = Array.isArray(publishPackage.mentions) ? publishPackage.mentions.filter(Boolean) : [];
|
|
80
|
-
return Boolean(
|
|
81
|
-
destinations.length > 0 || mentions.length > 0 || typeof publishPackage.caption === "string" && publishPackage.caption.trim() || typeof publishPackage.description === "string" && publishPackage.description.trim() || typeof publishPackage.cadence === "string" && publishPackage.cadence.trim() && publishPackage.cadence.trim() !== "Manual approval"
|
|
82
|
-
);
|
|
83
|
-
}
|
|
84
|
-
function isDestinationConnected(destination, connections) {
|
|
85
|
-
return connections.some((connection) => connection.status === "connected" && (destination.providerIds.includes(connection.providerId) || connection.connectorId !== void 0 && destination.providerIds.includes(connection.connectorId)));
|
|
86
|
-
}
|
|
87
38
|
function selectedModelsWithDefaults(current, catalog) {
|
|
88
39
|
const next = { ...current };
|
|
89
40
|
for (const key of GENERATION_TYPES) {
|
|
@@ -119,7 +70,6 @@ function buildGenerationRequestBody(fields) {
|
|
|
119
70
|
negativePrompt: fields.negativePrompt.trim() || void 0,
|
|
120
71
|
outputPath: fields.outputPath.trim() || void 0
|
|
121
72
|
};
|
|
122
|
-
if (fields.publishPackage) body.publishPackage = fields.publishPackage;
|
|
123
73
|
if (fields.type === "image") Object.assign(body, {
|
|
124
74
|
size: fields.image.size,
|
|
125
75
|
quality: fields.image.quality,
|
|
@@ -136,12 +86,12 @@ function buildGenerationRequestBody(fields) {
|
|
|
136
86
|
});
|
|
137
87
|
}
|
|
138
88
|
if (fields.type === "speech") Object.assign(body, { voice: fields.speech.voice });
|
|
139
|
-
if (fields.type === "avatar") Object.assign(body, {
|
|
89
|
+
if (fields.type === "avatar" && fields.avatar) Object.assign(body, {
|
|
140
90
|
audioUrl: fields.avatar.audioUrl.trim(),
|
|
141
91
|
imageUrl: fields.avatar.imageUrl.trim() || void 0,
|
|
142
92
|
avatarId: fields.avatar.avatarId.trim() || void 0
|
|
143
93
|
});
|
|
144
|
-
if (fields.type === "transcription") {
|
|
94
|
+
if (fields.type === "transcription" && fields.transcription) {
|
|
145
95
|
const temperature = Number(fields.transcription.temperature);
|
|
146
96
|
Object.assign(body, {
|
|
147
97
|
audioUrl: fields.transcription.audioUrl.trim(),
|
|
@@ -270,8 +220,6 @@ function normalizeImageCount(value) {
|
|
|
270
220
|
export {
|
|
271
221
|
GENERATION_TYPES,
|
|
272
222
|
isGenerationType,
|
|
273
|
-
DESTINATIONS,
|
|
274
|
-
CADENCES,
|
|
275
223
|
IMAGE_QUALITIES,
|
|
276
224
|
IMAGE_SIZE_HINT,
|
|
277
225
|
IMAGE_SIZE_PATTERN,
|
|
@@ -283,9 +231,6 @@ export {
|
|
|
283
231
|
relativeTime,
|
|
284
232
|
outputPathFor,
|
|
285
233
|
generationVaultPath,
|
|
286
|
-
buildPublishPackage,
|
|
287
|
-
isPublishPackage,
|
|
288
|
-
isDestinationConnected,
|
|
289
234
|
selectedModelsWithDefaults,
|
|
290
235
|
preferredModelId,
|
|
291
236
|
modelMessage,
|
|
@@ -302,4 +247,4 @@ export {
|
|
|
302
247
|
failedOptimisticGeneration,
|
|
303
248
|
normalizeImageCount
|
|
304
249
|
};
|
|
305
|
-
//# sourceMappingURL=chunk-
|
|
250
|
+
//# sourceMappingURL=chunk-E2CWFUUP.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/studio/generation.ts"],"sourcesContent":["/** Define generation categories for media including image, video, speech, avatar, and transcription */\nexport type GenerationType = 'image' | 'video' | 'speech' | 'avatar' | 'transcription'\n\n/** Define possible states representing the progress of a generation process */\nexport type GenerationStatus = 'pending' | 'running' | 'succeeded' | 'failed'\n\n/** Define possible status values for a media model's availability and accessibility */\nexport type MediaModelStatus = 'available' | 'limited' | 'unavailable'\n\n/** Define the structure for a generation entity including its metadata and creation details */\nexport interface Generation {\n id: string\n type: string\n prompt: string\n result: string | null\n model: string | null\n cost: number | null\n createdAt: Date | null\n metadata: Record<string, unknown> | null\n}\n\n/** Describe media model option properties including id, name, type, status, and optional provider and reason */\nexport interface MediaModelOption {\n id: string\n name: string\n provider?: string\n type: GenerationType\n status: MediaModelStatus\n reason?: string\n}\n\n/** Represent media model catalog with default values, model options, and optional error message */\nexport interface MediaModelCatalogResponse {\n defaults: Record<GenerationType, string>\n models: Record<GenerationType, MediaModelOption[]>\n error?: string\n}\n\n// Order drives the library type filter tabs. The composer offers its own\n// subset (`COMPOSER_TYPES` in studio-react) while avatar/transcription are\n// disabled (#451).\n/** Provide an array of supported generation types for media and content processing */\nexport const GENERATION_TYPES: readonly GenerationType[] = ['image', 'video', 'avatar', 'speech', 'transcription']\n\n/** Resolve whether a string value matches a valid GenerationType */\nexport function isGenerationType(value: string): value is GenerationType {\n return (GENERATION_TYPES as readonly string[]).includes(value)\n}\n\n// Enumerated generation options — the values the tangle media models (OpenAI-shaped\n// image/video APIs) actually accept. Composers render these as selects so an\n// enumerated field can never carry free text the provider would reject.\n/** Provide the valid image quality values for generation requests */\nexport const IMAGE_QUALITIES = ['low', 'medium', 'high', 'auto'] as const\n/** Provide a placeholder hint listing the accepted image size values */\nexport const IMAGE_SIZE_HINT = '1024x1024, 1536x1024, 1024x1536, or auto'\n/** Provide a validation pattern for the free-form image size field (WxH or auto) */\nexport const IMAGE_SIZE_PATTERN = String.raw`(\\d{3,4}x\\d{3,4}|auto)`\n/** Provide the valid video duration values (seconds) for generation requests */\nexport const VIDEO_DURATIONS = ['4', '6', '8', '10', '12'] as const\n/** Provide the valid video resolution values for generation requests */\nexport const VIDEO_RESOLUTIONS = ['720p', '1080p'] as const\n/** Provide the valid video aspect ratio values for generation requests */\nexport const VIDEO_ASPECT_RATIOS = ['16:9', '9:16', '1:1'] as const\n\n/** Define the minimum number of images required for processing or validation */\nexport const MIN_IMAGE_COUNT = 1\n/** Define the maximum number of images allowed for upload or display */\nexport const MAX_IMAGE_COUNT = 4\n\n/** Resolve a human-readable relative time string from a given date or return an empty string if null */\nexport function relativeTime(date: Date | null): string {\n if (!date) return ''\n const now = Date.now()\n const diff = now - new Date(date).getTime()\n const minutes = Math.floor(diff / 60000)\n if (minutes < 1) return 'just now'\n if (minutes < 60) return `${minutes}m ago`\n const hours = Math.floor(minutes / 60)\n if (hours < 24) return `${hours}h ago`\n const days = Math.floor(hours / 24)\n if (days < 7) return `${days}d ago`\n return new Date(date).toLocaleDateString('en-US', { month: 'short', day: 'numeric' })\n}\n\n/** Resolve the output directory path based on the specified generation type */\nexport function outputPathFor(type: GenerationType): string {\n if (type === 'image') return 'generated/images'\n if (type === 'video') return 'generated/videos'\n if (type === 'avatar') return 'generated/avatars'\n if (type === 'speech') return 'generated/audio'\n return 'generated/transcripts'\n}\n\n/** Resolve the vault path string from a Generation object or return null if unavailable */\nexport function generationVaultPath(generation: Generation): string | null {\n const value = generation.metadata?.vaultPath\n return typeof value === 'string' && value.trim() ? value.trim() : null\n}\n\n/** Resolve selected models by applying defaults for missing or unavailable entries in the catalog */\nexport function selectedModelsWithDefaults(\n current: Partial<Record<GenerationType, string>>,\n catalog: MediaModelCatalogResponse,\n): Partial<Record<GenerationType, string>> {\n const next = { ...current }\n for (const key of GENERATION_TYPES) {\n const models = catalog.models[key] ?? []\n const currentOption = models.find((model) => model.id === next[key])\n // Reset when: no selection, selection not in catalog, or selection is unavailable.\n // This ensures the Generate button is never stuck disabled when routeable\n // models exist but the stored default isn't one of them.\n if (!next[key] || !currentOption || currentOption.status === 'unavailable') {\n next[key] = preferredModelId(key, catalog) ?? ''\n }\n }\n return next\n}\n\n/** Resolve the preferred model ID for a given generation type from the media model catalog */\nexport function preferredModelId(type: GenerationType, catalog: MediaModelCatalogResponse | null): string | undefined {\n if (!catalog) return undefined\n const models = catalog.models[type] ?? []\n const preferred = catalog.defaults[type]\n return models.find((model) => model.id === preferred)?.id\n ?? models.find((model) => model.status !== 'unavailable')?.id\n ?? models[0]?.id\n}\n\n/** Resolve the appropriate status message for a media model based on loading state and availability */\nexport function modelMessage(model: MediaModelOption | undefined, loading: boolean, count: number): string | null {\n if (loading) return 'Loading media models...'\n if (count === 0) return 'No models are available for this media type.'\n if (!model) return 'Select a model.'\n if (model.status === 'unavailable') return model.reason ?? 'This model is not configured.'\n if (model.status === 'limited') return model.reason ? `Limited: ${model.reason}` : 'Limited availability.'\n return null\n}\n\n/** Define fields required to configure and request various types of media generation */\nexport interface GenerationRequestFields {\n workspaceId: string\n clientRequestId: string\n type: GenerationType\n model: string\n prompt: string\n negativePrompt: string\n outputPath: string\n image: { size: string; quality: string; count: number }\n video: { duration: string; resolution: string; aspectRatio: string; referenceImageUrl: string }\n speech: { voice: string }\n // Optional while the composer lanes are disabled (#451); the server capability stays.\n avatar?: { audioUrl: string; imageUrl: string; avatarId: string }\n transcription?: { audioUrl: string; language: string; responseFormat: string; temperature: string }\n}\n\n// image.count must already be normalized — it is also the optimistic-card count on the caller side\n/** Build the request body object for a generation operation from provided fields */\nexport function buildGenerationRequestBody(fields: GenerationRequestFields): Record<string, unknown> {\n const body: Record<string, unknown> = {\n workspaceId: fields.workspaceId,\n clientRequestId: fields.clientRequestId,\n type: fields.type,\n model: fields.model,\n prompt: fields.prompt.trim(),\n negativePrompt: fields.negativePrompt.trim() || undefined,\n outputPath: fields.outputPath.trim() || undefined,\n }\n if (fields.type === 'image') Object.assign(body, {\n size: fields.image.size,\n quality: fields.image.quality,\n n: fields.image.count,\n })\n if (fields.type === 'video') {\n const duration = Number(fields.video.duration)\n Object.assign(body, {\n // omit (let the API default) rather than serialize NaN → null on bad input\n duration: Number.isFinite(duration) ? duration : undefined,\n resolution: fields.video.resolution,\n aspectRatio: fields.video.aspectRatio.trim() || undefined,\n referenceImageUrl: fields.video.referenceImageUrl.trim() || undefined,\n })\n }\n if (fields.type === 'speech') Object.assign(body, { voice: fields.speech.voice })\n if (fields.type === 'avatar' && fields.avatar) Object.assign(body, {\n audioUrl: fields.avatar.audioUrl.trim(),\n imageUrl: fields.avatar.imageUrl.trim() || undefined,\n avatarId: fields.avatar.avatarId.trim() || undefined,\n })\n if (fields.type === 'transcription' && fields.transcription) {\n const temperature = Number(fields.transcription.temperature)\n Object.assign(body, {\n audioUrl: fields.transcription.audioUrl.trim(),\n language: fields.transcription.language.trim() || undefined,\n responseFormat: fields.transcription.responseFormat,\n // omit (let the API default) rather than serialize NaN → null on bad input\n temperature: Number.isFinite(temperature) ? temperature : undefined,\n })\n }\n return body\n}\n\n/** Resolve the current status of a generation based on its metadata and result fields */\nexport function generationStatus(generation: Generation): GenerationStatus {\n const metadata = generation.metadata ?? {}\n const status = typeof metadata.generationStatus === 'string' ? metadata.generationStatus : ''\n if (status === 'pending' || status === 'running' || status === 'failed' || status === 'succeeded') return status\n return generation.result ? 'succeeded' : 'pending'\n}\n\n/** Resolve and return the first user-safe error message from generation metadata or null if none exist */\nexport function generationError(generation: Generation): string | null {\n const metadata = generation.metadata ?? {}\n if (typeof metadata.providerError === 'string' && metadata.providerError.trim()) {\n return userSafeGenerationMessage(metadata.providerError)\n }\n if (typeof metadata.storageError === 'string' && metadata.storageError.trim()) {\n return metadata.storageError\n }\n return null\n}\n\nfunction generationClientRequestId(generation: Generation): string | null {\n const metadata = generation.metadata ?? {}\n return typeof metadata.clientRequestId === 'string' && metadata.clientRequestId.trim()\n ? metadata.clientRequestId\n : null\n}\n\nfunction generationBatchSlotKey(generation: Generation): string | null {\n const metadata = generation.metadata ?? {}\n const batchId = typeof metadata.batchId === 'string' && metadata.batchId.trim() ? metadata.batchId : null\n return batchId && typeof metadata.outputIndex === 'number'\n ? `${batchId}:${metadata.outputIndex}`\n : null\n}\n\n/** Resolve a unique merge key from a generation using batch slot or client request ID */\nexport function generationMergeKey(generation: Generation): string | null {\n return generationBatchSlotKey(generation) ?? generationClientRequestId(generation)\n}\n\n/** Merge a new generation into the current list by replacing or prepending it based on matching keys */\nexport function mergeLiveGeneration(current: Generation[], generation: Generation): Generation[] {\n const mergeKey = generationMergeKey(generation)\n const existingIndex = current.findIndex((item) => (\n item.id === generation.id\n || (mergeKey && generationMergeKey(item) === mergeKey)\n ))\n if (existingIndex === -1) return [generation, ...current]\n\n const next = [...current]\n next[existingIndex] = generation\n return next\n}\n\n// Overlay in-flight `live` generations on the loader's rows: each live row leads\n// (prefer the matching loader row by merge key / id so it carries the freshest\n// server state), then the remaining loader rows that no live row already\n// represents — deduped by BOTH id and merge key so a server row and its\n// optimistic twin never both appear. Returns `loader` unchanged when nothing is\n// live. Drives the canvas, library, and polling off one list.\n/** Merge two Generation arrays prioritizing live entries and matching by merge keys or IDs */\nexport function mergeLoaderAndLive(loader: Generation[], live: Generation[]): Generation[] {\n if (live.length === 0) return loader\n const leading = live.map((generation) => {\n const mergeKey = generationMergeKey(generation)\n return mergeKey\n ? loader.find((gen) => generationMergeKey(gen) === mergeKey) ?? generation\n : loader.find((gen) => gen.id === generation.id) ?? generation\n })\n const leadingIds = new Set(leading.map((gen) => gen.id))\n const leadingMergeKeys = new Set(leading\n .map((gen) => generationMergeKey(gen))\n .filter((id): id is string => Boolean(id)))\n return [\n ...leading,\n ...loader.filter((gen) => (\n !leadingIds.has(gen.id)\n && !leadingMergeKeys.has(generationMergeKey(gen) ?? '')\n )),\n ]\n}\n\n/** Determine if a generation ID indicates a local generation */\nexport function isLocalGeneration(generation: Generation): boolean {\n return generation.id.startsWith('local-')\n}\n\nfunction generationOutputIndex(generation: Generation): number {\n const value = generation.metadata?.outputIndex\n return typeof value === 'number' ? value : 0\n}\n\n// The most-recent run: all generations sharing the leading item's clientRequestId\n// (a multi-image batch), ordered by output slot. Falls back to the single leading\n// item when no request id is present. Drives the result canvas.\n/** Resolve and return the latest batch of generations grouped and sorted by client request ID and output index */\nexport function latestBatchOf(generations: Generation[]): Generation[] {\n const first = generations[0]\n if (!first) return []\n const key = generationClientRequestId(first)\n const batch = key\n ? generations.filter((generation) => generationClientRequestId(generation) === key)\n : [first]\n return [...batch].sort((a, b) => generationOutputIndex(a) - generationOutputIndex(b))\n}\n\n/** Resolve a user-safe generation message by filtering sensitive or error-related content */\nexport function userSafeGenerationMessage(message?: string): string {\n if (!message) return 'Generation failed'\n if (/Tangle API key is invalid or expired/i.test(message)) return message\n if (/(api[_ -]?key|secret|token|credential|env|configured|configuration)/i.test(message)) {\n return 'Generation failed'\n }\n return message\n}\n\n/** Generate content optimistically based on input parameters and optional model and output details */\nexport function optimisticGeneration({\n type,\n prompt,\n model,\n clientRequestId,\n outputIndex,\n outputCount,\n}: {\n type: GenerationType\n prompt: string\n model?: string\n clientRequestId: string\n outputIndex?: number\n outputCount?: number\n}): Generation {\n const batchId = outputIndex == null ? undefined : clientRequestId\n return {\n id: outputIndex == null ? `local-${clientRequestId}` : `local-${clientRequestId}-${outputIndex}`,\n type,\n prompt,\n result: null,\n model: model ?? null,\n cost: null,\n createdAt: new Date(),\n metadata: {\n generationStatus: 'pending',\n provider: type,\n clientRequestId,\n batchId,\n outputIndex,\n outputCount,\n },\n }\n}\n\n/** Mark a generation as failed with updated status and error information */\nexport function failedOptimisticGeneration(generation: Generation): Generation {\n return {\n ...generation,\n metadata: {\n ...(generation.metadata ?? {}),\n generationStatus: 'failed',\n providerError: 'Generation failed',\n },\n }\n}\n\n/** Normalize a value to a finite integer within the allowed image count range */\nexport function normalizeImageCount(value: unknown): number {\n const numeric = typeof value === 'number' ? value : Number(value)\n if (!Number.isFinite(numeric)) return MIN_IMAGE_COUNT\n return Math.min(Math.max(Math.trunc(numeric), MIN_IMAGE_COUNT), MAX_IMAGE_COUNT)\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { IntegrationConnection } from '@tangle-network/sandbox-ui/integrations';
|
|
2
1
|
import type { Generation } from '../../studio';
|
|
3
2
|
export declare const teaserA: Generation;
|
|
4
3
|
export declare const storyboardGeneration: Generation;
|
|
@@ -10,7 +9,6 @@ export declare const queuedGeneration: Generation;
|
|
|
10
9
|
export declare const runningGeneration: Generation;
|
|
11
10
|
export declare const failedGeneration: Generation;
|
|
12
11
|
export declare const storageFailedGeneration: Generation;
|
|
13
|
-
export declare const publishPackageGeneration: Generation;
|
|
14
12
|
/** The four-image batch a single "Images: 4" run produces. */
|
|
15
13
|
export declare const teaserBatch: Generation[];
|
|
16
14
|
/** Populated library: the newest batch first, every type and status represented. */
|
|
@@ -18,5 +16,3 @@ export declare const libraryGenerations: Generation[];
|
|
|
18
16
|
export declare const libraryTotalCost = 1.87;
|
|
19
17
|
/** Mirrors StudioWorkspace's default vaultHref (see generation-detail.test.tsx). */
|
|
20
18
|
export declare const demoVaultHref: (filePath?: string | null) => string;
|
|
21
|
-
/** Connected destinations for the publish-package composer (instagram + X). */
|
|
22
|
-
export declare const demoConnections: IntegrationConnection[];
|
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
/** Define the structure for a studio integration connection with status and provider identifiers */
|
|
2
|
-
export interface StudioIntegrationConnection {
|
|
3
|
-
status: string;
|
|
4
|
-
providerId: string;
|
|
5
|
-
connectorId?: string;
|
|
6
|
-
}
|
|
7
1
|
/** Define generation categories for media including image, video, speech, avatar, and transcription */
|
|
8
2
|
export type GenerationType = 'image' | 'video' | 'speech' | 'avatar' | 'transcription';
|
|
9
3
|
/** Define possible states representing the progress of a generation process */
|
|
@@ -36,34 +30,10 @@ export interface MediaModelCatalogResponse {
|
|
|
36
30
|
models: Record<GenerationType, MediaModelOption[]>;
|
|
37
31
|
error?: string;
|
|
38
32
|
}
|
|
39
|
-
/** Define the structure for configuring package publishing details and evaluation criteria */
|
|
40
|
-
export interface PublishPackage {
|
|
41
|
-
caption: string;
|
|
42
|
-
description: string;
|
|
43
|
-
mentions: string[];
|
|
44
|
-
destinations: string[];
|
|
45
|
-
cadence: string;
|
|
46
|
-
workflowDraft: boolean;
|
|
47
|
-
evalContract: {
|
|
48
|
-
artifactType: string;
|
|
49
|
-
deterministicChecks: string[];
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
/** Define a destination for publishing content with identifiers, label, provider IDs, and fields */
|
|
53
|
-
export interface PublishDestination {
|
|
54
|
-
id: string;
|
|
55
|
-
label: string;
|
|
56
|
-
providerIds: string[];
|
|
57
|
-
fields: string;
|
|
58
|
-
}
|
|
59
33
|
/** Provide an array of supported generation types for media and content processing */
|
|
60
34
|
export declare const GENERATION_TYPES: readonly GenerationType[];
|
|
61
35
|
/** Resolve whether a string value matches a valid GenerationType */
|
|
62
36
|
export declare function isGenerationType(value: string): value is GenerationType;
|
|
63
|
-
/** List available social media platforms with their publishing fields and provider identifiers */
|
|
64
|
-
export declare const DESTINATIONS: PublishDestination[];
|
|
65
|
-
/** Provide an array of predefined cadence options for scheduling or approval processes */
|
|
66
|
-
export declare const CADENCES: string[];
|
|
67
37
|
/** Provide the valid image quality values for generation requests */
|
|
68
38
|
export declare const IMAGE_QUALITIES: readonly ["low", "medium", "high", "auto"];
|
|
69
39
|
/** Provide a placeholder hint listing the accepted image size values */
|
|
@@ -86,24 +56,6 @@ export declare function relativeTime(date: Date | null): string;
|
|
|
86
56
|
export declare function outputPathFor(type: GenerationType): string;
|
|
87
57
|
/** Resolve the vault path string from a Generation object or return null if unavailable */
|
|
88
58
|
export declare function generationVaultPath(generation: Generation): string | null;
|
|
89
|
-
/** Build a PublishPackage object from caption, description, mentions, cadence, and destinations inputs */
|
|
90
|
-
export declare function buildPublishPackage({ caption, postDescription, mentions, cadence, destinations, }: {
|
|
91
|
-
caption: string;
|
|
92
|
-
postDescription: string;
|
|
93
|
-
mentions: string;
|
|
94
|
-
cadence: string;
|
|
95
|
-
destinations: string[];
|
|
96
|
-
}): PublishPackage | null;
|
|
97
|
-
/** Determine if a value conforms to the PublishPackage structure with optional metadata fields */
|
|
98
|
-
export declare function isPublishPackage(value: unknown): value is {
|
|
99
|
-
caption?: string;
|
|
100
|
-
description?: string;
|
|
101
|
-
mentions?: string[];
|
|
102
|
-
destinations?: string[];
|
|
103
|
-
cadence?: string;
|
|
104
|
-
};
|
|
105
|
-
/** Determine if a destination has any active connections in the given list of studio integration connections */
|
|
106
|
-
export declare function isDestinationConnected(destination: PublishDestination, connections: StudioIntegrationConnection[]): boolean;
|
|
107
59
|
/** Resolve selected models by applying defaults for missing or unavailable entries in the catalog */
|
|
108
60
|
export declare function selectedModelsWithDefaults(current: Partial<Record<GenerationType, string>>, catalog: MediaModelCatalogResponse): Partial<Record<GenerationType, string>>;
|
|
109
61
|
/** Resolve the preferred model ID for a given generation type from the media model catalog */
|
|
@@ -119,7 +71,6 @@ export interface GenerationRequestFields {
|
|
|
119
71
|
prompt: string;
|
|
120
72
|
negativePrompt: string;
|
|
121
73
|
outputPath: string;
|
|
122
|
-
publishPackage: PublishPackage | null;
|
|
123
74
|
image: {
|
|
124
75
|
size: string;
|
|
125
76
|
quality: string;
|
|
@@ -134,12 +85,12 @@ export interface GenerationRequestFields {
|
|
|
134
85
|
speech: {
|
|
135
86
|
voice: string;
|
|
136
87
|
};
|
|
137
|
-
avatar
|
|
88
|
+
avatar?: {
|
|
138
89
|
audioUrl: string;
|
|
139
90
|
imageUrl: string;
|
|
140
91
|
avatarId: string;
|
|
141
92
|
};
|
|
142
|
-
transcription
|
|
93
|
+
transcription?: {
|
|
143
94
|
audioUrl: string;
|
|
144
95
|
language: string;
|
|
145
96
|
responseFormat: string;
|
package/dist/studio/index.d.ts
CHANGED
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
* Studio module: the generation model and the pure helpers a media-generation
|
|
3
3
|
* surface needs — the `Generation` row shape and its lifecycle status/error
|
|
4
4
|
* derivation, the optimistic + live-merge logic that backs polling, the media
|
|
5
|
-
* model catalog types + selection helpers, the request-body builder
|
|
6
|
-
* publish-package model.
|
|
5
|
+
* model catalog types + selection helpers, and the request-body builder.
|
|
7
6
|
*
|
|
8
7
|
* Logic only — no React, no DOM, no design-system import. Safe in server
|
|
9
8
|
* bundles. The React surface (composer, result canvas, library drawer, the
|
package/dist/studio/index.js
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import {
|
|
2
|
-
CADENCES,
|
|
3
|
-
DESTINATIONS,
|
|
4
2
|
GENERATION_TYPES,
|
|
5
3
|
IMAGE_QUALITIES,
|
|
6
4
|
IMAGE_SIZE_HINT,
|
|
@@ -11,16 +9,13 @@ import {
|
|
|
11
9
|
VIDEO_DURATIONS,
|
|
12
10
|
VIDEO_RESOLUTIONS,
|
|
13
11
|
buildGenerationRequestBody,
|
|
14
|
-
buildPublishPackage,
|
|
15
12
|
failedOptimisticGeneration,
|
|
16
13
|
generationError,
|
|
17
14
|
generationMergeKey,
|
|
18
15
|
generationStatus,
|
|
19
16
|
generationVaultPath,
|
|
20
|
-
isDestinationConnected,
|
|
21
17
|
isGenerationType,
|
|
22
18
|
isLocalGeneration,
|
|
23
|
-
isPublishPackage,
|
|
24
19
|
latestBatchOf,
|
|
25
20
|
mergeLiveGeneration,
|
|
26
21
|
mergeLoaderAndLive,
|
|
@@ -32,10 +27,8 @@ import {
|
|
|
32
27
|
relativeTime,
|
|
33
28
|
selectedModelsWithDefaults,
|
|
34
29
|
userSafeGenerationMessage
|
|
35
|
-
} from "../chunk-
|
|
30
|
+
} from "../chunk-E2CWFUUP.js";
|
|
36
31
|
export {
|
|
37
|
-
CADENCES,
|
|
38
|
-
DESTINATIONS,
|
|
39
32
|
GENERATION_TYPES,
|
|
40
33
|
IMAGE_QUALITIES,
|
|
41
34
|
IMAGE_SIZE_HINT,
|
|
@@ -46,16 +39,13 @@ export {
|
|
|
46
39
|
VIDEO_DURATIONS,
|
|
47
40
|
VIDEO_RESOLUTIONS,
|
|
48
41
|
buildGenerationRequestBody,
|
|
49
|
-
buildPublishPackage,
|
|
50
42
|
failedOptimisticGeneration,
|
|
51
43
|
generationError,
|
|
52
44
|
generationMergeKey,
|
|
53
45
|
generationStatus,
|
|
54
46
|
generationVaultPath,
|
|
55
|
-
isDestinationConnected,
|
|
56
47
|
isGenerationType,
|
|
57
48
|
isLocalGeneration,
|
|
58
|
-
isPublishPackage,
|
|
59
49
|
latestBatchOf,
|
|
60
50
|
mergeLiveGeneration,
|
|
61
51
|
mergeLoaderAndLive,
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { type Generation } from '../studio';
|
|
2
|
-
export declare function ComposerHero({ workspaceId,
|
|
2
|
+
export declare function ComposerHero({ workspaceId, align, surfaceClassName, onGenerated, }: {
|
|
3
3
|
workspaceId?: string;
|
|
4
|
-
integrationsHref?: string;
|
|
5
|
-
canManageIntegrations: boolean;
|
|
6
4
|
/** Heading treatment: `center` (focus mode) vs `start` (composer as a left rail). */
|
|
7
5
|
align?: 'center' | 'start';
|
|
8
6
|
/** Background of the composer card. Host apps pass their own surface token so
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `@tangle-network/agent-app/studio-react` — the media-generation studio
|
|
3
|
-
* surface: a prompt composer over
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* card + detail views. `StudioWorkspace` is the ready-to-mount shell (header +
|
|
3
|
+
* surface: a prompt composer over three generation types (image / video /
|
|
4
|
+
* speech) with a model picker, a result canvas, and a right-side asset-library
|
|
5
|
+
* drawer with card + detail views. `StudioWorkspace` is the ready-to-mount shell (header +
|
|
7
6
|
* composer + canvas + drawer + the merge/poll/revalidate orchestrator); the
|
|
8
7
|
* leaf components are exported so a product can compose its own shell.
|
|
9
8
|
*
|
|
@@ -26,7 +25,6 @@ export * from './generation-grid';
|
|
|
26
25
|
export * from './generation-card';
|
|
27
26
|
export * from './generation-detail';
|
|
28
27
|
export * from './generation-detail-modal';
|
|
29
|
-
export * from './publish-package-composer';
|
|
30
28
|
export * from './type-config';
|
|
31
29
|
export * from './image-composer';
|
|
32
30
|
export * from './video-composer';
|